|
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
|
2 // Use of this source code is governed by a BSD-style license that can be |
|
3 // found in the LICENSE file. |
|
4 |
|
5 package org.chromium.debug.ui; |
|
6 |
|
7 import java.util.HashMap; |
|
8 import java.util.HashSet; |
|
9 import java.util.Map; |
|
10 import java.util.Set; |
|
11 |
|
12 import org.chromium.debug.core.model.StackFrame; |
|
13 import org.eclipse.core.runtime.IAdaptable; |
|
14 import org.eclipse.debug.ui.DebugUITools; |
|
15 import org.eclipse.debug.ui.contexts.DebugContextEvent; |
|
16 import org.eclipse.debug.ui.contexts.IDebugContextListener; |
|
17 import org.eclipse.jface.viewers.ISelection; |
|
18 import org.eclipse.jface.viewers.IStructuredSelection; |
|
19 import org.eclipse.ui.IWindowListener; |
|
20 import org.eclipse.ui.IWorkbench; |
|
21 import org.eclipse.ui.IWorkbenchPage; |
|
22 import org.eclipse.ui.IWorkbenchPart; |
|
23 import org.eclipse.ui.IWorkbenchWindow; |
|
24 import org.eclipse.ui.PlatformUI; |
|
25 |
|
26 /** |
|
27 * Keeps track of the evaluation context (selected StackFrame) in all the |
|
28 * workbench parts. A singleton. |
|
29 */ |
|
30 public class JsEvalContextManager implements IWindowListener, IDebugContextListener { |
|
31 |
|
32 private static final String DEBUGGER_ACTIVE = ChromiumDebugUIPlugin.PLUGIN_ID + ".debuggerActive"; //$NON-NLS-1$ |
|
33 |
|
34 private static JsEvalContextManager instance; |
|
35 |
|
36 private IWorkbenchWindow activeWindow; |
|
37 |
|
38 private final Map<IWorkbenchPage, StackFrame> pageToFrame = |
|
39 new HashMap<IWorkbenchPage, StackFrame>(); |
|
40 |
|
41 protected JsEvalContextManager() { |
|
42 DebugUITools.getDebugContextManager().addDebugContextListener(this); |
|
43 } |
|
44 |
|
45 /** |
|
46 * This method will get called only once. |
|
47 */ |
|
48 public static void startup() { |
|
49 Runnable r = new Runnable() { |
|
50 public void run() { |
|
51 if (instance == null) { |
|
52 instance = new JsEvalContextManager(); |
|
53 IWorkbench workbench = PlatformUI.getWorkbench(); |
|
54 workbench.addWindowListener(instance); |
|
55 instance.activeWindow = workbench.getActiveWorkbenchWindow(); |
|
56 } |
|
57 } |
|
58 }; |
|
59 ChromiumDebugUIPlugin.getDisplay().asyncExec(r); |
|
60 } |
|
61 |
|
62 public void windowActivated(IWorkbenchWindow window) { |
|
63 activeWindow = window; |
|
64 } |
|
65 |
|
66 public void windowClosed(IWorkbenchWindow window) { |
|
67 } |
|
68 |
|
69 public void windowDeactivated(IWorkbenchWindow window) { |
|
70 } |
|
71 |
|
72 public void windowOpened(IWorkbenchWindow window) { |
|
73 } |
|
74 |
|
75 public void debugContextChanged(DebugContextEvent event) { |
|
76 if ((event.getFlags() & DebugContextEvent.ACTIVATED) > 0) { |
|
77 IWorkbenchPart part = event.getDebugContextProvider().getPart(); |
|
78 if (part == null) { |
|
79 return; |
|
80 } |
|
81 IWorkbenchPage page = part.getSite().getPage(); |
|
82 ISelection selection = event.getContext(); |
|
83 if (selection instanceof IStructuredSelection) { |
|
84 Object firstElement = ((IStructuredSelection) selection).getFirstElement(); |
|
85 if (firstElement instanceof IAdaptable) { |
|
86 StackFrame frame = (StackFrame) ((IAdaptable) firstElement).getAdapter(StackFrame.class); |
|
87 if (frame != null) { |
|
88 putStackFrame(page, frame); |
|
89 return; |
|
90 } |
|
91 } |
|
92 } |
|
93 // debug context for the |page| has been lost |
|
94 removeStackFrame(page); |
|
95 } |
|
96 } |
|
97 |
|
98 /** |
|
99 * Returns the stackframe corresponding to the given {@code part}, or {@code |
|
100 * null} if none. |
|
101 * |
|
102 * @param part the active part |
|
103 * @return the stack frame in whose context the evaluation is performed, or |
|
104 * {@code null} if none |
|
105 */ |
|
106 public static StackFrame getStackFrameFor(IWorkbenchPart part) { |
|
107 IWorkbenchPage page = part.getSite().getPage(); |
|
108 StackFrame frame = getStackFrameFor(page); |
|
109 if (frame == null) { |
|
110 return getStackFrameFor(page.getWorkbenchWindow()); |
|
111 } |
|
112 return frame; |
|
113 } |
|
114 |
|
115 /** |
|
116 * Returns the stackframe corresponding to the given {@code window}, or |
|
117 * {@code null} if none. |
|
118 * |
|
119 * @param window to find the StackFrame for. If {@code null}, the {@code |
|
120 * activeWindow} will be used instead |
|
121 * @return the stack frame in whose the evaluation is performed, or {@code |
|
122 * null} if none |
|
123 */ |
|
124 public static StackFrame getStackFrameFor(IWorkbenchWindow window) { |
|
125 Set<IWorkbenchWindow> visitedWindows = new HashSet<IWorkbenchWindow>(); |
|
126 if (window == null) { |
|
127 window = instance.activeWindow; |
|
128 } |
|
129 return getStackFrameFor(window, visitedWindows); |
|
130 } |
|
131 |
|
132 private static StackFrame getStackFrameFor( |
|
133 IWorkbenchWindow window, Set<IWorkbenchWindow> visitedWindows) { |
|
134 IWorkbenchPage activePage = window.getActivePage(); |
|
135 StackFrame frame = null; |
|
136 // Check the active page in the window |
|
137 if (activePage != null) { |
|
138 frame = getStackFrameFor(activePage); |
|
139 if (frame != null) { |
|
140 return frame; |
|
141 } |
|
142 } |
|
143 // Check all the current Eclipse window pages |
|
144 for (IWorkbenchPage windowPage : window.getPages()) { |
|
145 if (activePage != windowPage) { |
|
146 frame = getStackFrameFor(windowPage); |
|
147 if (frame != null) { |
|
148 return frame; |
|
149 } |
|
150 } |
|
151 } |
|
152 |
|
153 // Last resort - check all other Eclipse windows |
|
154 visitedWindows.add(window); |
|
155 |
|
156 for (IWorkbenchWindow workbenchWindow : PlatformUI.getWorkbench().getWorkbenchWindows()) { |
|
157 if (!visitedWindows.contains(workbenchWindow)) { |
|
158 frame = getStackFrameFor(workbenchWindow, visitedWindows); |
|
159 if (frame != null) { |
|
160 return frame; |
|
161 } |
|
162 } |
|
163 } |
|
164 |
|
165 // Nothing found |
|
166 return null; |
|
167 } |
|
168 |
|
169 private static StackFrame getStackFrameFor(IWorkbenchPage page) { |
|
170 if (instance != null) { |
|
171 return instance.pageToFrame.get(page); |
|
172 } |
|
173 return null; |
|
174 } |
|
175 |
|
176 private void removeStackFrame(IWorkbenchPage page) { |
|
177 pageToFrame.remove(page); |
|
178 if (pageToFrame.isEmpty()) { |
|
179 // No more available frames |
|
180 System.setProperty(DEBUGGER_ACTIVE, Boolean.FALSE.toString()); |
|
181 } |
|
182 } |
|
183 |
|
184 private void putStackFrame(IWorkbenchPage page, StackFrame frame) { |
|
185 pageToFrame.put(page, frame); |
|
186 System.setProperty(DEBUGGER_ACTIVE, Boolean.TRUE.toString()); |
|
187 } |
|
188 |
|
189 } |