Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 130d7152794c7eb325d0a82c1a3c2177a6f76229 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*******************************************************************************
 * Copyright (c) 2004, 2013 QNX Software Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     QNX Software Systems - Initial API and implementation
 *     Ericsson             - DSF-GDB version
 *     Nokia                - Made generic to DSF
 *     Wind River Systems   - Adapted to TCF Debug
 *******************************************************************************/
package org.eclipse.tcf.internal.cdt.ui;

import org.eclipse.cdt.debug.core.model.IMoveToLine;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.cdt.dsf.debug.ui.DsfDebugUITools;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.model.ISuspendResume;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.debug.ui.contexts.IDebugContextService;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.tcf.internal.debug.ui.model.TCFNodeExecContext;
import org.eclipse.tcf.internal.debug.ui.model.TCFNodeStackFrame;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.WorkbenchJob;

/**
 * Manages the current evaluation context (stack frame) for evaluation actions.
 * In each page, the selection is tracked in each debug view (if any). When a
 * debug target selection exists, the "debuggerActive" System property is set to
 * true. This property is used to make the "Run To Line", "Resume At Line",
 * "Move To Line" and "Add Watch Expression" actions visible in editors only if
 * there is a running debug session.
 */
public class EvaluationContextManager implements IWindowListener, IDebugContextListener {

    // Must use the same ID as the base CDT since we want to enable
    // actions that are registered by base CDT.
    private final static String DEBUGGER_ACTIVE = CDebugUIPlugin.PLUGIN_ID + ".debuggerActive"; //$NON-NLS-1$

    protected static EvaluationContextManager fgManager;

    protected EvaluationContextManager() {
    }

    public static void startup() {
        // Bug 416849: trigger lazy activation of 'org.eclipse.cdt.dsf.ui' and 'org.eclipse.cdt.debug.ui'
        DsfDebugUITools.getPreferenceStore();
        CDebugUIPlugin.getDefault();
        WorkbenchJob job = new WorkbenchJob("") {
            @Override
            public IStatus runInUIThread(IProgressMonitor monitor) {
                if (fgManager == null) {
                    fgManager = new EvaluationContextManager();
                    IWorkbench workbench = PlatformUI.getWorkbench();
                    IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
                    if (window != null) {
                        fgManager.windowActivated(window);
                    }
                    workbench.addWindowListener(fgManager);
                }
                return Status.OK_STATUS;
            }
        };
        job.setPriority(Job.SHORT);
        job.setSystem(true);
        job.schedule(100);
    }


    /* (non-Javadoc)
     * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow)
     */
    public void windowActivated(IWorkbenchWindow window) {
            IDebugContextService service = DebugUITools.getDebugContextManager().getContextService(window);
            service.addDebugContextListener(this);
            selectionChanged( service.getActiveContext() );
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow)
     */
    public void windowDeactivated(IWorkbenchWindow window) {
             DebugUITools.getDebugContextManager().getContextService(window).removeDebugContextListener(this);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow)
     */
    public void windowOpened(IWorkbenchWindow window) {
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow)
     */
    public void windowClosed(IWorkbenchWindow window) {
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.debug.ui.contexts.IDebugContextListener#debugContextChanged(org.eclipse.debug.ui.contexts.DebugContextEvent)
     */
    public void debugContextChanged(DebugContextEvent event) {
        selectionChanged(event.getContext());
    }

    /*
     * Takes the current selection and validates that we have a valid TCF node
     * selected and various actions should be visible and enabled.
     */
    private void selectionChanged(ISelection selection) {
        if (selection instanceof IStructuredSelection) {
            IStructuredSelection ss = (IStructuredSelection)selection;
            if (ss.size() == 1) {
                Object element = ss.getFirstElement();
                if (element instanceof TCFNodeExecContext || element instanceof TCFNodeStackFrame) {
                    System.setProperty(DEBUGGER_ACTIVE, Boolean.toString(true));
                    return;
                }
                // Test for other CDT-based debuggers
                ISuspendResume sr = adapt(element, ISuspendResume.class);
                IMoveToLine mtl = adapt(sr, IMoveToLine.class);
                if (mtl != null) {
                    // debugger supports move-to-line, don't interfere with it
                    return;
                }
            }
        }

        // no context in the given view
        System.setProperty(DEBUGGER_ACTIVE, Boolean.toString(false));
    }

    @SuppressWarnings("unchecked")
    private <T> T adapt(Object adaptable, Class<T> clazz) {
        if (adaptable == null)
            return null;
        if (clazz.isInstance(adaptable))
            return (T) adaptable;
        T adapter = null;
        if (adaptable instanceof IAdaptable)
            adapter = (T) ((IAdaptable) adaptable).getAdapter(clazz);
        if (adapter == null)
            adapter = (T) Platform.getAdapterManager().loadAdapter(adaptable, clazz.getName());
        return adapter;
    }

}

Back to the top