|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 package com.nokia.carbide.cpp.debug.kernelaware.ui; |
|
18 |
|
19 import org.eclipse.cdt.debug.core.model.ICDebugTarget; |
|
20 import org.eclipse.cdt.debug.core.model.ICStackFrame; |
|
21 import org.eclipse.cdt.debug.core.model.ICThread; |
|
22 import org.eclipse.cdt.debug.internal.core.model.CDebugElement; |
|
23 import org.eclipse.core.runtime.IProgressMonitor; |
|
24 import org.eclipse.core.runtime.IStatus; |
|
25 import org.eclipse.core.runtime.Status; |
|
26 import org.eclipse.core.runtime.jobs.Job; |
|
27 import org.eclipse.debug.core.DebugEvent; |
|
28 import org.eclipse.debug.core.DebugException; |
|
29 import org.eclipse.debug.core.DebugPlugin; |
|
30 import org.eclipse.debug.core.IDebugEventSetListener; |
|
31 import org.eclipse.debug.ui.IDebugUIConstants; |
|
32 import org.eclipse.jface.action.Action; |
|
33 import org.eclipse.jface.action.IAction; |
|
34 import org.eclipse.jface.action.IMenuListener; |
|
35 import org.eclipse.jface.action.IMenuManager; |
|
36 import org.eclipse.jface.action.IToolBarManager; |
|
37 import org.eclipse.jface.action.MenuManager; |
|
38 import org.eclipse.jface.action.Separator; |
|
39 import org.eclipse.jface.dialogs.IInputValidator; |
|
40 import org.eclipse.jface.dialogs.InputDialog; |
|
41 import org.eclipse.jface.dialogs.MessageDialog; |
|
42 import org.eclipse.jface.resource.ImageDescriptor; |
|
43 import org.eclipse.jface.viewers.DoubleClickEvent; |
|
44 import org.eclipse.jface.viewers.IDoubleClickListener; |
|
45 import org.eclipse.jface.viewers.ISelection; |
|
46 import org.eclipse.jface.viewers.ISelectionChangedListener; |
|
47 import org.eclipse.jface.viewers.IStructuredSelection; |
|
48 import org.eclipse.jface.viewers.SelectionChangedEvent; |
|
49 import org.eclipse.jface.viewers.StructuredViewer; |
|
50 import org.eclipse.jface.viewers.TableViewer; |
|
51 import org.eclipse.jface.viewers.TreeViewer; |
|
52 import org.eclipse.jface.window.Window; |
|
53 import org.eclipse.swt.SWT; |
|
54 import org.eclipse.swt.events.SelectionAdapter; |
|
55 import org.eclipse.swt.events.SelectionEvent; |
|
56 import org.eclipse.swt.graphics.Color; |
|
57 import org.eclipse.swt.widgets.Composite; |
|
58 import org.eclipse.swt.widgets.Menu; |
|
59 import org.eclipse.swt.widgets.TabFolder; |
|
60 import org.eclipse.swt.widgets.TabItem; |
|
61 import org.eclipse.swt.widgets.TableColumn; |
|
62 import org.eclipse.swt.widgets.Widget; |
|
63 import org.eclipse.ui.IActionBars; |
|
64 import org.eclipse.ui.IMemento; |
|
65 import org.eclipse.ui.INullSelectionListener; |
|
66 import org.eclipse.ui.ISelectionListener; |
|
67 import org.eclipse.ui.IViewSite; |
|
68 import org.eclipse.ui.IWorkbenchActionConstants; |
|
69 import org.eclipse.ui.IWorkbenchPage; |
|
70 import org.eclipse.ui.IWorkbenchPart; |
|
71 import org.eclipse.ui.IWorkbenchPartReference; |
|
72 import org.eclipse.ui.PartInitException; |
|
73 import org.eclipse.ui.PlatformUI; |
|
74 import org.eclipse.ui.part.ViewPart; |
|
75 import org.eclipse.ui.plugin.AbstractUIPlugin; |
|
76 |
|
77 import com.freescale.cdt.debug.cw.core.CWPlugin; |
|
78 import com.freescale.cdt.debug.cw.core.cdi.Session; |
|
79 import com.nokia.carbide.cpp.debug.kernelaware.IDataChangedListener; |
|
80 import com.nokia.carbide.cpp.debug.kernelaware.IOSObjectProperties; |
|
81 import com.nokia.carbide.cpp.debug.kernelaware.KernelawarePlugin; |
|
82 import com.nokia.carbide.cpp.debug.kernelaware.OSDataManager; |
|
83 import com.nokia.carbide.cpp.debug.kernelaware.OSObjectProcess; |
|
84 import com.nokia.carbide.cpp.debug.kernelaware.OSObjectThread; |
|
85 import com.nokia.carbide.cpp.internal.featureTracker.FeatureUseTrackerConsts; |
|
86 import com.nokia.carbide.cpp.internal.featureTracker.FeatureUseTrackerPlugin; |
|
87 |
|
88 import cwdbg.EclipseDEConstants; |
|
89 |
|
90 public class SymbianOSView extends ViewPart implements ISelectionListener, |
|
91 INullSelectionListener, IDataChangedListener, Runnable, |
|
92 IDebugEventSetListener { |
|
93 |
|
94 /* |
|
95 * Help context ID. Should be: PluginID + "." + <words without '.'> |
|
96 */ |
|
97 private static final String HelpID_Prefix = KernelawarePlugin |
|
98 .getUniqueIdentifier() |
|
99 + "."; //$NON-NLS-1$ |
|
100 |
|
101 public static final String s_HelpID_View = HelpID_Prefix |
|
102 + "symbian_os_data_view"; //$NON-NLS-1$ |
|
103 |
|
104 public static final String s_HelpID_OverviewTab = HelpID_Prefix |
|
105 + "symbian_os_data_view_overview_tab"; //$NON-NLS-1$ |
|
106 |
|
107 public static final String s_HelpID_ProcessTab = HelpID_Prefix |
|
108 + "symbian_os_data_view_process_tab"; //$NON-NLS-1$ |
|
109 |
|
110 public static final String s_HelpID_ThreadTab = HelpID_Prefix |
|
111 + "symbian_os_data_view_thread_tab"; //$NON-NLS-1$ |
|
112 |
|
113 public static final String s_HelpID_ChunkTab = HelpID_Prefix |
|
114 + "symbian_os_data_view_chunk_tab"; //$NON-NLS-1$ |
|
115 |
|
116 public static final String s_HelpID_LibraryTab = HelpID_Prefix |
|
117 + "symbian_os_data_view_library_tab"; //$NON-NLS-1$ |
|
118 |
|
119 public static final ImageDescriptor clearImageDesc = AbstractUIPlugin.imageDescriptorFromPlugin( |
|
120 PlatformUI.PLUGIN_ID, "$nl$/icons/full/etool16/clear_co.gif"); //$NON-NLS-1$ |
|
121 |
|
122 private TabItem m_overviewTabItem; |
|
123 |
|
124 private TabItem m_processTabItem; |
|
125 |
|
126 private TabItem m_threadTabItem; |
|
127 |
|
128 private TabItem m_chunkTabItem; |
|
129 |
|
130 private TabItem m_libraryTabItem; |
|
131 |
|
132 private TreeViewer m_overviewTreeViewer; |
|
133 |
|
134 private TableViewer m_processTableViewer; |
|
135 |
|
136 private TableViewer m_threadTableViewer; |
|
137 |
|
138 private TableViewer m_chunkTableViewer; |
|
139 |
|
140 private TableViewer m_libraryTableViewer; |
|
141 |
|
142 private StructuredViewer m_currentViewer; |
|
143 |
|
144 private Session m_currentSession = null; |
|
145 |
|
146 private Action m_actionRefresh; |
|
147 |
|
148 private Action m_actionToggleAutoRefresh; |
|
149 |
|
150 private Action m_actionDebug; |
|
151 |
|
152 private Action m_actionProperties; |
|
153 |
|
154 private Action m_actionSetTimer; |
|
155 |
|
156 private Action m_actionCollapseAll; |
|
157 |
|
158 private Action m_actionDoubleClick; |
|
159 |
|
160 // in seconds. |
|
161 private int m_timedRefreshInterval = 20; |
|
162 |
|
163 // Is the view closed by user ? |
|
164 private boolean m_disposed; |
|
165 |
|
166 // Make this option static so that it's consistent across view sessions. |
|
167 static boolean m_autoRefresh = true; |
|
168 |
|
169 /* |
|
170 * (non-Javadoc) |
|
171 * |
|
172 * @see com.freescale.cdt.debug.cw.core.ui.os.OSView#createPartControl(org.eclipse.swt.widgets.Composite) |
|
173 */ |
|
174 @Override |
|
175 public void createPartControl(Composite parent) { |
|
176 |
|
177 final TabFolder tabFolder = new TabFolder(parent, SWT.NONE); |
|
178 tabFolder.addSelectionListener(new SelectionAdapter() { |
|
179 public void widgetSelected(SelectionEvent e) { |
|
180 DoAction_TabSelection(e.item); |
|
181 } |
|
182 }); |
|
183 |
|
184 ImageDescriptor imageDesc; |
|
185 |
|
186 /*********************************************************************** |
|
187 * Overview (treeview) tab |
|
188 */ |
|
189 m_overviewTabItem = new TabItem(tabFolder, SWT.NONE); |
|
190 m_overviewTabItem |
|
191 .setToolTipText(Messages.getString("SymbianOSView.OverViewToolTip")); //$NON-NLS-1$ |
|
192 m_overviewTabItem.setText(Messages.getString("SymbianOSView.OverViewLabel")); //$NON-NLS-1$ |
|
193 imageDesc = KernelawarePlugin |
|
194 .getImageDescriptor("icons//tab_overview.png"); //$NON-NLS-1$ |
|
195 m_overviewTabItem.setImage(imageDesc.createImage()); |
|
196 |
|
197 m_overviewTreeViewer = (new OverviewTab()).createControl(tabFolder, |
|
198 m_overviewTabItem); |
|
199 |
|
200 /*********************************************************************** |
|
201 * Process Tab |
|
202 */ |
|
203 m_processTabItem = new TabItem(tabFolder, SWT.NONE); |
|
204 m_processTabItem |
|
205 .setToolTipText(Messages.getString("SymbianOSView.ProcessesToolTip")); //$NON-NLS-1$ |
|
206 m_processTabItem.setText(Messages.getString("SymbianOSView.ProcessesLabel")); //$NON-NLS-1$ |
|
207 imageDesc = KernelawarePlugin |
|
208 .getImageDescriptor("icons//tab_process.gif"); //$NON-NLS-1$ |
|
209 m_processTabItem.setImage(imageDesc.createImage()); |
|
210 |
|
211 m_processTableViewer = (new ProcessTab()).createControl(tabFolder, |
|
212 m_processTabItem); |
|
213 |
|
214 /*********************************************************************** |
|
215 * Thread Tab |
|
216 */ |
|
217 m_threadTabItem = new TabItem(tabFolder, SWT.NONE); |
|
218 m_threadTabItem.setToolTipText(Messages.getString("SymbianOSView.ThreadsToolTip")); //$NON-NLS-1$ |
|
219 m_threadTabItem.setText(Messages.getString("SymbianOSView.ThreadsLabel")); //$NON-NLS-1$ |
|
220 imageDesc = KernelawarePlugin |
|
221 .getImageDescriptor("icons//tab_thread.gif"); //$NON-NLS-1$ |
|
222 m_threadTabItem.setImage(imageDesc.createImage()); |
|
223 |
|
224 m_threadTableViewer = (new ThreadTab()).createControl(tabFolder, |
|
225 m_threadTabItem); |
|
226 |
|
227 /*********************************************************************** |
|
228 * Chunk Tab |
|
229 */ |
|
230 m_chunkTabItem = new TabItem(tabFolder, SWT.NONE); |
|
231 m_chunkTabItem.setToolTipText(Messages.getString("SymbianOSView.ChunksToolTip")); //$NON-NLS-1$ |
|
232 m_chunkTabItem.setText(Messages.getString("SymbianOSView.ChunksLabel")); //$NON-NLS-1$ |
|
233 imageDesc = KernelawarePlugin |
|
234 .getImageDescriptor("icons//tab_chunk.gif"); //$NON-NLS-1$ |
|
235 m_chunkTabItem.setImage(imageDesc.createImage()); |
|
236 |
|
237 m_chunkTableViewer = (new ChunkTab()).createControl(tabFolder, |
|
238 m_chunkTabItem); |
|
239 |
|
240 /*********************************************************************** |
|
241 * Library Tab |
|
242 */ |
|
243 m_libraryTabItem = new TabItem(tabFolder, SWT.NONE); |
|
244 m_libraryTabItem |
|
245 .setToolTipText(Messages.getString("SymbianOSView.LibrariesToolTip")); //$NON-NLS-1$ |
|
246 m_libraryTabItem.setText(Messages.getString("SymbianOSView.LibrariesLabel")); //$NON-NLS-1$ |
|
247 imageDesc = KernelawarePlugin |
|
248 .getImageDescriptor("icons//tab_library.gif"); //$NON-NLS-1$ |
|
249 m_libraryTabItem.setImage(imageDesc.createImage()); |
|
250 |
|
251 m_libraryTableViewer = (new LibraryTab()).createControl(tabFolder, |
|
252 m_libraryTabItem); |
|
253 |
|
254 /*********************************************************************** |
|
255 * Other View setting |
|
256 */ |
|
257 // Default current tab. |
|
258 tabFolder.setSelection(0); |
|
259 |
|
260 // Default selection provider. |
|
261 // add a viewer as selection provider of the view, so that selected item |
|
262 // in the viewer can have its properties displayed in Properties View. |
|
263 m_currentViewer = m_overviewTreeViewer; |
|
264 getSite().setSelectionProvider(m_currentViewer); |
|
265 |
|
266 // listen to selection in debug view |
|
267 getSite().getPage().addSelectionListener( |
|
268 IDebugUIConstants.ID_DEBUG_VIEW, this); |
|
269 |
|
270 /*********************************************************************** |
|
271 * Help context IDs. |
|
272 */ |
|
273 PlatformUI.getWorkbench().getHelpSystem() |
|
274 .setHelp(parent, s_HelpID_View); |
|
275 PlatformUI.getWorkbench().getHelpSystem().setHelp( |
|
276 m_overviewTabItem.getControl(), s_HelpID_OverviewTab); |
|
277 PlatformUI.getWorkbench().getHelpSystem().setHelp( |
|
278 m_processTabItem.getControl(), s_HelpID_ProcessTab); |
|
279 PlatformUI.getWorkbench().getHelpSystem().setHelp( |
|
280 m_threadTabItem.getControl(), s_HelpID_ThreadTab); |
|
281 PlatformUI.getWorkbench().getHelpSystem().setHelp( |
|
282 m_chunkTabItem.getControl(), s_HelpID_ChunkTab); |
|
283 PlatformUI.getWorkbench().getHelpSystem().setHelp( |
|
284 m_libraryTabItem.getControl(), s_HelpID_LibraryTab); |
|
285 |
|
286 /*********************************************************************** |
|
287 * Actions |
|
288 */ |
|
289 makeActions(); |
|
290 hookContextMenu(); |
|
291 hookDoubleClickAction(); |
|
292 contributeToActionBars(); |
|
293 |
|
294 hookSelectionChangedListeners(); |
|
295 |
|
296 m_disposed = false; |
|
297 |
|
298 // If there is already a debug session running, try to show OS data for |
|
299 // it. |
|
300 Session currSelectedSession = Session.getUIFocusSession(); |
|
301 if (currSelectedSession != null) { |
|
302 // getUIFocusSession() above may give us a dead session. Excluse |
|
303 // that case. |
|
304 if (currSelectedSession.isActive()){ |
|
305 try { |
|
306 showDataForDevice(currSelectedSession); |
|
307 } |
|
308 catch (InterruptedException e) { |
|
309 e.printStackTrace(); |
|
310 } |
|
311 } |
|
312 } |
|
313 |
|
314 updateActionStatus(); |
|
315 |
|
316 DebugPlugin.getDefault().addDebugEventListener(this); |
|
317 } |
|
318 |
|
319 public void dataDirty() { |
|
320 // Must run this in UI thread. |
|
321 PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { |
|
322 public void run() { |
|
323 showDataAsStale(true); |
|
324 } |
|
325 }); |
|
326 }; |
|
327 |
|
328 private void hookContextMenu() { |
|
329 MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ |
|
330 menuMgr.setRemoveAllWhenShown(true); |
|
331 menuMgr.addMenuListener(new IMenuListener() { |
|
332 public void menuAboutToShow(IMenuManager manager) { |
|
333 SymbianOSView.this.fillContextMenu(manager); |
|
334 } |
|
335 }); |
|
336 |
|
337 // Hook up context menu for each of the viewers. |
|
338 // |
|
339 Menu menu; |
|
340 StructuredViewer viewer = m_overviewTreeViewer; |
|
341 menu = menuMgr.createContextMenu(viewer.getControl()); |
|
342 viewer.getControl().setMenu(menu); |
|
343 getSite().registerContextMenu(menuMgr, viewer); |
|
344 |
|
345 viewer = m_processTableViewer; |
|
346 menu = menuMgr.createContextMenu(viewer.getControl()); |
|
347 viewer.getControl().setMenu(menu); |
|
348 getSite().registerContextMenu(menuMgr, viewer); |
|
349 |
|
350 viewer = m_threadTableViewer; |
|
351 menu = menuMgr.createContextMenu(viewer.getControl()); |
|
352 viewer.getControl().setMenu(menu); |
|
353 getSite().registerContextMenu(menuMgr, viewer); |
|
354 |
|
355 viewer = m_chunkTableViewer; |
|
356 menu = menuMgr.createContextMenu(viewer.getControl()); |
|
357 viewer.getControl().setMenu(menu); |
|
358 getSite().registerContextMenu(menuMgr, viewer); |
|
359 |
|
360 viewer = m_libraryTableViewer; |
|
361 menu = menuMgr.createContextMenu(viewer.getControl()); |
|
362 viewer.getControl().setMenu(menu); |
|
363 getSite().registerContextMenu(menuMgr, viewer); |
|
364 } |
|
365 |
|
366 /** |
|
367 * Hook up listeners for selection change in the view. |
|
368 */ |
|
369 private void hookSelectionChangedListeners() { |
|
370 ISelectionChangedListener listener = new ISelectionChangedListener() { |
|
371 public void selectionChanged(SelectionChangedEvent event) { |
|
372 // Update status of commands. |
|
373 updateActionStatus(); |
|
374 } |
|
375 }; |
|
376 |
|
377 m_overviewTreeViewer.addSelectionChangedListener(listener); |
|
378 m_processTableViewer.addSelectionChangedListener(listener); |
|
379 m_threadTableViewer.addSelectionChangedListener(listener); |
|
380 m_chunkTableViewer.addSelectionChangedListener(listener); |
|
381 m_libraryTableViewer.addSelectionChangedListener(listener); |
|
382 } |
|
383 |
|
384 /* |
|
385 * (non-Javadoc) |
|
386 * |
|
387 * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite, |
|
388 * org.eclipse.ui.IMemento) |
|
389 */ |
|
390 @Override |
|
391 public void init(IViewSite site, IMemento memento) throws PartInitException { |
|
392 super.init(site, memento); |
|
393 FeatureUseTrackerPlugin.getFeatureUseProxy().startUsingFeature(FeatureUseTrackerConsts.CARBIDE_KERNELAWARE); |
|
394 } |
|
395 |
|
396 @Override |
|
397 public void dispose() { |
|
398 // Must do the following, otherwise a zombie will exist after user close |
|
399 // the view. |
|
400 // |
|
401 m_disposed = true; |
|
402 |
|
403 getSite().setSelectionProvider(null); |
|
404 |
|
405 getSite().getPage().removeSelectionListener( |
|
406 IDebugUIConstants.ID_DEBUG_VIEW, this); |
|
407 |
|
408 DebugPlugin.getDefault().removeDebugEventListener(this); |
|
409 |
|
410 // remove the timed task. |
|
411 disableTimedRefresh(); |
|
412 |
|
413 FeatureUseTrackerPlugin.getFeatureUseProxy().stopUsingFeature(FeatureUseTrackerConsts.CARBIDE_KERNELAWARE); |
|
414 |
|
415 super.dispose(); |
|
416 } |
|
417 |
|
418 @Override |
|
419 public void setFocus() { |
|
420 // Make sure the current tab get the focus so that help system can |
|
421 // get the correct context ID for the focused control so as to display |
|
422 // matching context-sensitive help......12/18/06 |
|
423 m_currentViewer.getControl().setFocus(); |
|
424 } |
|
425 |
|
426 // This is called when selection in workbench changes. |
|
427 // We only honor the change in Debug View. |
|
428 public void selectionChanged(IWorkbenchPart part, ISelection selection) { |
|
429 if (!(selection instanceof IStructuredSelection)) |
|
430 return; |
|
431 |
|
432 IStructuredSelection structSel = (IStructuredSelection) selection; |
|
433 if (structSel.size() != 1) |
|
434 return; |
|
435 |
|
436 Object sel = structSel.getFirstElement(); |
|
437 |
|
438 // Allow StackFrame & thread for now. |
|
439 // If we hornor selection of CDebugTarget, debugger may freeze on start |
|
440 // when the OS View is open before debugger starts. |
|
441 // Figure out a solution later..... 11/29/06 |
|
442 // Not a problem any more in Eclipse 3.3 + CDT4.0....... 11/15/07 |
|
443 // |
|
444 if (!(sel instanceof ICStackFrame || sel instanceof ICThread || sel instanceof ICDebugTarget)) |
|
445 return; |
|
446 |
|
447 Session newSession = Session.getSessionFromDebugContext(sel); |
|
448 |
|
449 if (newSession == null) // how come ? |
|
450 return; |
|
451 |
|
452 /* A terminated session, or a special case: |
|
453 * Start the first debug session while the OS View is open, the |
|
454 * CDT Target (process) is created and auto selected in Debug View |
|
455 * but corresponding CWProcess is not created yet. In such case |
|
456 * we should not try to refresh. Part of fix to bug 5320.. 12/04/07 |
|
457 */ |
|
458 if (! newSession.isActive()) |
|
459 return; |
|
460 |
|
461 /* |
|
462 * If user just selects a different item (stackframe, thread, process) |
|
463 * in the same session, and the session's OS data is not dirty, don't |
|
464 * bother to update. |
|
465 */ |
|
466 boolean refresh = false; |
|
467 |
|
468 if (m_currentSession == null) { |
|
469 refresh = true; |
|
470 } |
|
471 else if (!m_currentSession.equals(newSession)) |
|
472 // Different session is selected (by user). |
|
473 refresh = true; |
|
474 else { |
|
475 // The same session is selected (by user or automatically done when debuggee |
|
476 // is suspended). Refresh only when data is dirty and AutoRefresh is |
|
477 // turned on. |
|
478 if (newSession.getOSDataManager().isDataDirty() && m_autoRefresh) { |
|
479 refresh = true; |
|
480 |
|
481 // Check this for stop mode debug. Fix bug 3467...03/28/07 |
|
482 if (newSession.isSystemModeDebug() |
|
483 && newSession.isSystemRunning()) |
|
484 refresh = false; |
|
485 } |
|
486 } |
|
487 |
|
488 if (refresh){ |
|
489 try { |
|
490 showDataForDevice(newSession); |
|
491 } |
|
492 catch (InterruptedException e) { |
|
493 e.printStackTrace(); |
|
494 } |
|
495 } |
|
496 } |
|
497 |
|
498 /** |
|
499 * Asynchronously get the OS data for the given session. Show progress and |
|
500 * allow user cancel. |
|
501 * |
|
502 * @param session - |
|
503 * for which session (i.e. machine) to get the OS data. |
|
504 * @param listener - |
|
505 * who's interested in finish event. |
|
506 * @param userInitiated - |
|
507 * is the compute initiated by user or automatically by program. |
|
508 */ |
|
509 private void computeInput(final Session session, |
|
510 final IDataChangedListener listener, final boolean userInitiated) { |
|
511 |
|
512 // Note the job name is also referenced in Target.java. |
|
513 // So watch out when changing it !....04/07/07 |
|
514 Job refreshJob = new Job(Messages.getString("SymbianOSView.RefreshDataTitle")) { //$NON-NLS-1$ |
|
515 protected IStatus run(IProgressMonitor monitor) { |
|
516 IStatus status = Status.OK_STATUS; |
|
517 try { |
|
518 OSDataManager osDM = (OSDataManager) session |
|
519 .getOSDataManager(); |
|
520 |
|
521 if (osDM != null) { |
|
522 /* |
|
523 * For crash debugger, the refreshing is time consuming |
|
524 * (more than one minute at present). So never do |
|
525 * auto-refresh for it, only user-initiated refreshing |
|
526 * is allowed. This way startup of crash debugger won't |
|
527 * be slow.... [LW_20070213] 02/13/07 |
|
528 */ |
|
529 if (!(session.getLaunchTypeName().contains("crash") && !userInitiated)) //$NON-NLS-1$ |
|
530 status = osDM.updateAll(monitor); |
|
531 } |
|
532 } catch (DebugException e) { |
|
533 status = new Status(IStatus.ERROR, KernelawarePlugin |
|
534 .getUniqueIdentifier(), 0, e.getMessage(), null); |
|
535 } |
|
536 |
|
537 listener.dataUpdated(session, status); |
|
538 |
|
539 monitor.done(); |
|
540 |
|
541 return status; |
|
542 } |
|
543 }; |
|
544 |
|
545 refreshJob.setUser(userInitiated); |
|
546 refreshJob.setPriority(Job.LONG); |
|
547 refreshJob.schedule(); |
|
548 } |
|
549 |
|
550 /** |
|
551 * Given a session (namely a machine, or device), display its OS data in the |
|
552 * view. |
|
553 * |
|
554 * @param newSession |
|
555 */ |
|
556 private void showDataForDevice(Session newSession) throws InterruptedException { |
|
557 // Make the view be listener for dataChanged event from the underlying |
|
558 // session. |
|
559 if (m_currentSession != null) |
|
560 ((OSDataManager) m_currentSession.getOSDataManager()) |
|
561 .removeDataChangedListener(this); |
|
562 |
|
563 ((OSDataManager) newSession.getOSDataManager()) |
|
564 .addDataChangedListener(this); |
|
565 |
|
566 // User selects a debug session of ours. |
|
567 m_currentSession = newSession; |
|
568 |
|
569 // This fixes the timing issue with attaching to a process @bug 7580 |
|
570 Thread.sleep(500); |
|
571 |
|
572 updateActionStatus(); |
|
573 |
|
574 // if the new session is for stop mode, disable timer for auto-refresh. |
|
575 // ...... 12/03/06 |
|
576 if (newSession.isSystemModeDebug()) { |
|
577 // Stop the timed task. |
|
578 disableTimedRefresh(); |
|
579 } |
|
580 // The scheduled refresh may conflict with the computeInput() |
|
581 // below and result in deadlock. |
|
582 // Actually the timed refresh will be scheduled in computeInput(). |
|
583 // So don't do this here......... 12/04/2007 |
|
584 // else if (newSession.isActive()) // Don't if the session is a terminated one |
|
585 // scheduleTimedRefresh(); |
|
586 |
|
587 showDataAsStale(true); |
|
588 |
|
589 computeInput(m_currentSession, this, false); |
|
590 |
|
591 /* |
|
592 * Hide Chunk and Library tabs per debug session type. But I don't see |
|
593 * an easy way in SWT yet.........Nov. 2006 |
|
594 */ |
|
595 } |
|
596 |
|
597 private void packTableViewer(TableViewer viewer) { |
|
598 TableColumn[] cols = viewer.getTable().getColumns(); |
|
599 for (int i = 0; i < cols.length; i++) |
|
600 if (cols[i].getResizable() != false) |
|
601 cols[i].pack(); |
|
602 } |
|
603 |
|
604 private void contributeToActionBars() { |
|
605 IActionBars bars = getViewSite().getActionBars(); |
|
606 fillLocalPullDown(bars.getMenuManager()); |
|
607 fillLocalToolBar(bars.getToolBarManager()); |
|
608 } |
|
609 |
|
610 private void fillContextMenu(IMenuManager manager) { |
|
611 if (m_currentViewer == null) |
|
612 return; |
|
613 |
|
614 ISelection selection = m_currentViewer.getSelection(); |
|
615 if (selection == null) |
|
616 return; |
|
617 |
|
618 Object obj = ((IStructuredSelection) selection).getFirstElement(); |
|
619 if (obj == null) |
|
620 return; |
|
621 |
|
622 // Add "debug" command if selection is a process or thread. |
|
623 if (obj instanceof OSObjectProcess || obj instanceof OSObjectThread) { |
|
624 manager.add(m_actionDebug); |
|
625 } |
|
626 |
|
627 // For all others, add "properties" command. |
|
628 manager.add(m_actionProperties); |
|
629 |
|
630 // Other plug-ins can contribute their actions here |
|
631 manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); |
|
632 } |
|
633 |
|
634 private void fillLocalPullDown(IMenuManager manager) { |
|
635 manager.add(m_actionRefresh); |
|
636 manager.add(m_actionToggleAutoRefresh); |
|
637 manager.add(m_actionDebug); |
|
638 manager.add(new Separator()); |
|
639 manager.add(m_actionProperties); |
|
640 manager.add(m_actionSetTimer); |
|
641 manager.add(m_actionCollapseAll); |
|
642 } |
|
643 |
|
644 private void fillLocalToolBar(IToolBarManager manager) { |
|
645 manager.add(m_actionRefresh); |
|
646 manager.add(m_actionToggleAutoRefresh); |
|
647 manager.add(m_actionDebug); |
|
648 manager.add(m_actionProperties); |
|
649 manager.add(m_actionSetTimer); |
|
650 manager.add(m_actionCollapseAll); |
|
651 } |
|
652 |
|
653 private void makeActions() { |
|
654 m_actionRefresh = new Action(Messages.getString("SymbianOSView.RefreshActionLabel"), IAction.AS_PUSH_BUTTON) { //$NON-NLS-1$ |
|
655 public void run() { |
|
656 DoAction_Refresh(); |
|
657 } |
|
658 }; |
|
659 m_actionRefresh.setToolTipText(Messages.getString("SymbianOSView.RefreshActionToolTip")); //$NON-NLS-1$ |
|
660 m_actionRefresh.setImageDescriptor(KernelawarePlugin |
|
661 .getImageDescriptor("icons//refresh.gif")); //$NON-NLS-1$ |
|
662 |
|
663 m_actionToggleAutoRefresh = new Action(Messages.getString("SymbianOSView.AutoRefreshActionLabel"), //$NON-NLS-1$ |
|
664 IAction.AS_CHECK_BOX) { |
|
665 public void run() { |
|
666 DoAction_ToggleAutoRefresh(); |
|
667 } |
|
668 }; |
|
669 m_actionToggleAutoRefresh |
|
670 .setToolTipText(Messages.getString("SymbianOSView.AutoRefreshActionToolTip")); //$NON-NLS-1$ |
|
671 m_actionToggleAutoRefresh.setChecked(m_autoRefresh); |
|
672 m_actionToggleAutoRefresh.setImageDescriptor(KernelawarePlugin |
|
673 .getImageDescriptor("icons//auto_refresh.gif")); //$NON-NLS-1$ |
|
674 |
|
675 m_actionDebug = new Action(Messages.getString("SymbianOSView.DebugActionLabel"), IAction.AS_PUSH_BUTTON) { //$NON-NLS-1$ |
|
676 public void run() { |
|
677 DoAction_Debug(); |
|
678 } |
|
679 }; |
|
680 m_actionDebug.setToolTipText(Messages.getString("SymbianOSView.DebugActionToolTip")); //$NON-NLS-1$ |
|
681 m_actionDebug.setImageDescriptor(KernelawarePlugin |
|
682 .getImageDescriptor("icons//Debug.png")); //$NON-NLS-1$ |
|
683 |
|
684 m_actionProperties = new Action(Messages.getString("SymbianOSView.PropertiesActionLabel"), IAction.AS_PUSH_BUTTON) { //$NON-NLS-1$ |
|
685 public void run() { |
|
686 DoAction_Properties(); |
|
687 } |
|
688 }; |
|
689 m_actionProperties |
|
690 .setToolTipText(Messages.getString("SymbianOSView.PropertiesActionToolTip")); //$NON-NLS-1$ |
|
691 m_actionProperties.setImageDescriptor(KernelawarePlugin |
|
692 .getImageDescriptor("icons//properties.gif")); //$NON-NLS-1$ |
|
693 |
|
694 m_actionSetTimer = new Action(Messages.getString("SymbianOSView.SetTimerActionLabel"), IAction.AS_PUSH_BUTTON) { //$NON-NLS-1$ |
|
695 public void run() { |
|
696 DoAction_SetTimer(); |
|
697 } |
|
698 }; |
|
699 m_actionSetTimer |
|
700 .setToolTipText(Messages.getString("SymbianOSView.SetTimerActionToolTip")); //$NON-NLS-1$ |
|
701 m_actionSetTimer.setImageDescriptor(KernelawarePlugin |
|
702 .getImageDescriptor("icons//set_timer.gif")); //$NON-NLS-1$ |
|
703 |
|
704 m_actionCollapseAll = new Action(Messages.getString("SymbianOSView.CollapseAllActionLabel"), IAction.AS_PUSH_BUTTON) { //$NON-NLS-1$ |
|
705 public void run() { |
|
706 DoAction_CollapseAll(); |
|
707 } |
|
708 }; |
|
709 m_actionCollapseAll.setToolTipText(Messages.getString("SymbianOSView.CollapseAllActionToolTip")); //$NON-NLS-1$ |
|
710 m_actionCollapseAll.setImageDescriptor(KernelawarePlugin |
|
711 .getImageDescriptor("icons//collapseall.gif")); //$NON-NLS-1$ |
|
712 |
|
713 m_actionDoubleClick = new Action() { |
|
714 public void run() { |
|
715 DoAction_Debug(); |
|
716 } |
|
717 }; |
|
718 } |
|
719 |
|
720 private void hookDoubleClickAction() { |
|
721 IDoubleClickListener listener = new IDoubleClickListener() { |
|
722 public void doubleClick(DoubleClickEvent event) { |
|
723 m_actionDoubleClick.run(); |
|
724 } |
|
725 }; |
|
726 |
|
727 m_processTableViewer.addDoubleClickListener(listener); |
|
728 m_threadTableViewer.addDoubleClickListener(listener); |
|
729 } |
|
730 |
|
731 private void showMessage(String message) { |
|
732 MessageDialog |
|
733 .openInformation(m_processTableViewer.getControl().getShell(), |
|
734 Messages.getString("SymbianOSView.MessageTitle"), Messages.getString("SymbianOSView.MessagePrefix") + message); //$NON-NLS-1$ //$NON-NLS-2$ |
|
735 } |
|
736 |
|
737 private void DoAction_TabSelection(Widget item) { |
|
738 if (item == null) |
|
739 return; |
|
740 |
|
741 if (item.equals(m_overviewTabItem)) { |
|
742 m_currentViewer = m_overviewTreeViewer; |
|
743 } else if (item.equals(m_processTabItem)) |
|
744 m_currentViewer = m_processTableViewer; |
|
745 else if (item.equals(m_threadTabItem)) |
|
746 m_currentViewer = m_threadTableViewer; |
|
747 else if (item.equals(m_chunkTabItem)) |
|
748 m_currentViewer = m_chunkTableViewer; |
|
749 else if (item.equals(m_libraryTabItem)) |
|
750 m_currentViewer = m_libraryTableViewer; |
|
751 |
|
752 getSite().setSelectionProvider(m_currentViewer); |
|
753 |
|
754 /* |
|
755 * Now the tab selection has changed. |
|
756 * |
|
757 * At this time if user selects an item in the tab, the properties of |
|
758 * the item won't be displayed in Properties View. That's because the |
|
759 * above selectionProvider change is not honored until the view loses |
|
760 * and regains focus (a platform bug ?). So we do this: change focus to |
|
761 * any other view (here I choose Variable View as it's most likely |
|
762 * present and in the same pane as this OS View) and then change it back |
|
763 * to this view. This is not a perfect solution, but... |
|
764 * |
|
765 * |
|
766 * This is also needed for the help system to get tab-specific context |
|
767 * ID. See setFocus() for more. |
|
768 */ |
|
769 int viewState_old = IWorkbenchPage.STATE_RESTORED; |
|
770 int viewState_new = IWorkbenchPage.STATE_RESTORED; |
|
771 IWorkbenchPartReference thisRef = getSite().getPage() |
|
772 .getReference(this); |
|
773 if (thisRef != null) |
|
774 viewState_old = getSite().getPage().getPartState(thisRef); |
|
775 |
|
776 try { |
|
777 getSite().getPage().showView(IDebugUIConstants.ID_VARIABLE_VIEW); |
|
778 } catch (PartInitException e) { |
|
779 e.printStackTrace(); |
|
780 } |
|
781 |
|
782 if (thisRef != null) |
|
783 viewState_new = getSite().getPage().getPartState(thisRef); |
|
784 |
|
785 // Put focus back. |
|
786 getSite().getPage().activate(this); |
|
787 |
|
788 // Restore the state. |
|
789 // Added the "new != old" check otherwise the setPartState() would cause |
|
790 // NPE in core code in Eclipse 3.3 |
|
791 if (thisRef != null && viewState_new != viewState_old) |
|
792 getSite().getPage().setPartState(thisRef, viewState_old); |
|
793 |
|
794 // enable/disable actions/commands accordingly. |
|
795 updateActionStatus(); |
|
796 } |
|
797 |
|
798 /** |
|
799 * Force refresh of all data in the view by re-reading from the target |
|
800 * device. |
|
801 * |
|
802 */ |
|
803 private void DoAction_Refresh() { |
|
804 if (m_currentSession == null) |
|
805 return; |
|
806 |
|
807 disableTimedRefresh(); |
|
808 |
|
809 m_currentSession.getOSDataManager().setDataDirty(); |
|
810 |
|
811 computeInput(m_currentSession, this, true); |
|
812 } |
|
813 |
|
814 private void DoAction_ToggleAutoRefresh() { |
|
815 m_autoRefresh = !m_autoRefresh; |
|
816 } |
|
817 |
|
818 private void DoAction_CollapseAll() { |
|
819 if (m_overviewTreeViewer != null) |
|
820 m_overviewTreeViewer.collapseAll(); |
|
821 } |
|
822 |
|
823 private void DoAction_Debug() { |
|
824 /* |
|
825 * Attach debugger to a process or thread. |
|
826 */ |
|
827 if (m_currentViewer == null) |
|
828 return; |
|
829 if (m_currentSession == null || !m_currentSession.isActive()) |
|
830 return; |
|
831 |
|
832 ISelection selection = m_currentViewer.getSelection(); |
|
833 if (selection == null) |
|
834 return; |
|
835 |
|
836 Object obj = ((IStructuredSelection) selection).getFirstElement(); |
|
837 if (obj == null) |
|
838 return; |
|
839 |
|
840 // Only allow attaching to a process |
|
841 int procID, threadID; |
|
842 |
|
843 String procName = ""; //$NON-NLS-1$ |
|
844 if (obj instanceof OSObjectProcess) { |
|
845 |
|
846 // User select to debug a process |
|
847 OSObjectProcess objProcess = (OSObjectProcess) obj; |
|
848 procID = objProcess.getID(); |
|
849 if (m_currentSession.processBeingDebugged(procID)) { |
|
850 showMessage(Messages.getString("SymbianOSView.ProcessUnderDebugMsg")); //$NON-NLS-1$ |
|
851 return; |
|
852 } |
|
853 |
|
854 procName = objProcess.getName(); |
|
855 |
|
856 // Just targetting the first thread in the process |
|
857 OSObjectThread[] threads = objProcess.getThreads(); |
|
858 if (threads.length > 0) |
|
859 threadID = threads[0].getID(); |
|
860 else |
|
861 // no thread, should not happen. |
|
862 return; |
|
863 } else if (obj instanceof OSObjectThread) { |
|
864 |
|
865 OSObjectThread thread = (OSObjectThread) obj; |
|
866 procID = thread.getProcessID(); |
|
867 if (procID == EclipseDEConstants.J_OSObjectID_Invalid) // owner |
|
868 // unknown |
|
869 return; |
|
870 threadID = thread.getID(); |
|
871 |
|
872 if (m_currentSession.threadBeingDebugged(procID, threadID)) { |
|
873 showMessage(Messages.getString("SymbianOSView.ThreadUnderDebugMsg")); //$NON-NLS-1$ |
|
874 return; |
|
875 } |
|
876 |
|
877 if (m_currentSession.processBeingDebugged(procID)) { |
|
878 // the owner process is already under debug |
|
879 // no need to pass process name to backend. |
|
880 procName = ""; //$NON-NLS-1$ |
|
881 } else { |
|
882 procName = (String) thread |
|
883 .getRawPropertyValue(IOSObjectProperties.ID.OwningProcessName); |
|
884 } |
|
885 } else |
|
886 // other objects |
|
887 return; |
|
888 |
|
889 // With TRK, we may get process name like "app[ef1a9bef]0001". |
|
890 // Do some adjustment here. |
|
891 if (procName.length() > 0) { |
|
892 int i = procName.indexOf('['); |
|
893 if (i > 0) |
|
894 procName = procName.substring(0, i); |
|
895 |
|
896 // for a name without extension like "app", add .exe |
|
897 if (!procName.contains(".")) //$NON-NLS-N$ //$NON-NLS-1$ |
|
898 procName = procName + ".exe"; //$NON-NLS-N$ //$NON-NLS-1$ |
|
899 } |
|
900 |
|
901 // Now the real action... |
|
902 try { |
|
903 m_currentSession.attachToThread(procID, threadID, procName); |
|
904 } catch (DebugException e) { |
|
905 showMessage(e.getMessage()); |
|
906 } |
|
907 } |
|
908 |
|
909 /** |
|
910 * Open Properties View and show property of selected item in current tab. |
|
911 */ |
|
912 private void DoAction_Properties() { |
|
913 if (m_currentViewer == null) |
|
914 return; |
|
915 |
|
916 ISelection selection = m_currentViewer.getSelection(); |
|
917 if (selection == null) |
|
918 return; |
|
919 |
|
920 // Open the Properties view in case it's not. |
|
921 try { |
|
922 getSite().getPage().showView( |
|
923 org.eclipse.ui.IPageLayout.ID_PROP_SHEET); |
|
924 } catch (PartInitException e) { |
|
925 e.printStackTrace(); |
|
926 } |
|
927 |
|
928 // Change focus back to this view so that the selection in the viewer is |
|
929 // displayed in the Properties View. |
|
930 getSite().getPage().activate(this); |
|
931 } |
|
932 |
|
933 /** |
|
934 * Pop up a dialog for user to enter the time interval. |
|
935 */ |
|
936 private void DoAction_SetTimer() { |
|
937 // validator for user input. |
|
938 class Validator implements IInputValidator { |
|
939 |
|
940 public String isValid(String newText) { |
|
941 int i; |
|
942 |
|
943 try { |
|
944 i = Integer.valueOf(newText); |
|
945 } catch (Exception e) { |
|
946 return Messages.getString("SymbianOSView.DecimalError"); //$NON-NLS-1$ |
|
947 } |
|
948 |
|
949 if (i < 3 || i > 600) |
|
950 return Messages.getString("SymbianOSView.RangeError"); //$NON-NLS-1$ |
|
951 |
|
952 return null; |
|
953 } |
|
954 } |
|
955 |
|
956 int currentInterval = CWPlugin |
|
957 .getDefault() |
|
958 .getPluginPreferences() |
|
959 .getInt( |
|
960 cwdbg.PreferenceConstants.J_PN_OSViewAutoRefreshInterval); |
|
961 |
|
962 InputDialog dg = new InputDialog( |
|
963 this.getSite().getShell(), |
|
964 Messages.getString("SymbianOSView.MessageTitle"), // $NON-NLS-1$ //$NON-NLS-1$ |
|
965 Messages.getString("SymbianOSView.IntervalMessage"), //$NON-NLS-1$ |
|
966 Integer.toString(currentInterval), new Validator()); |
|
967 |
|
968 if (dg.open() == Window.OK) { |
|
969 String input = dg.getValue(); |
|
970 currentInterval = Integer.valueOf(input); |
|
971 |
|
972 // Save in our global pref storage. |
|
973 CWPlugin.getDefault().getPluginPreferences().setValue( |
|
974 cwdbg.PreferenceConstants.J_PN_OSViewAutoRefreshInterval, |
|
975 currentInterval); |
|
976 } |
|
977 } |
|
978 |
|
979 /** |
|
980 * Enable/disable actions based on current selection. |
|
981 */ |
|
982 private void updateActionStatus() { |
|
983 boolean enableRefresh = false; |
|
984 boolean enableToggleAutoRefresh = true; |
|
985 boolean enableDebug = false; |
|
986 boolean enableProperties = false; |
|
987 boolean enableSetTimer = false; |
|
988 boolean enableCollapseAll = false; |
|
989 |
|
990 if (m_actionRefresh == null) // not created yet. |
|
991 return; |
|
992 |
|
993 if (m_currentSession != null && m_currentSession.isActive()) { |
|
994 enableRefresh = true; |
|
995 |
|
996 if (!m_currentSession.isSystemModeDebug()) |
|
997 // enable this for TRK debugger only. |
|
998 enableSetTimer = true; |
|
999 |
|
1000 if (m_currentSession.getLaunchTypeName().contains("crash")) //$NON-NLS-1$ |
|
1001 // disable auto-refresh for crash debugger. See my comment |
|
1002 // [LW_20070213]. |
|
1003 enableToggleAutoRefresh = false; |
|
1004 |
|
1005 if (m_currentViewer != null) { |
|
1006 |
|
1007 // tab specific commands |
|
1008 // |
|
1009 if (m_currentViewer == m_overviewTreeViewer) |
|
1010 enableCollapseAll = true; |
|
1011 |
|
1012 // Selection specific commands |
|
1013 // |
|
1014 ISelection selection = m_currentViewer.getSelection(); |
|
1015 Object obj = ((IStructuredSelection) selection) |
|
1016 .getFirstElement(); |
|
1017 if (obj != null) { |
|
1018 // This is true as long as there is a valid selection in the |
|
1019 // view. |
|
1020 enableProperties = true; |
|
1021 |
|
1022 if (obj instanceof OSObjectProcess |
|
1023 || obj instanceof OSObjectThread) |
|
1024 enableDebug = true; |
|
1025 |
|
1026 } |
|
1027 } |
|
1028 } |
|
1029 |
|
1030 m_actionRefresh.setEnabled(enableRefresh); |
|
1031 m_actionToggleAutoRefresh.setEnabled(enableToggleAutoRefresh); |
|
1032 m_actionDebug.setEnabled(enableDebug); |
|
1033 m_actionProperties.setEnabled(enableProperties); |
|
1034 m_actionSetTimer.setEnabled(enableSetTimer); |
|
1035 m_actionCollapseAll.setEnabled(enableCollapseAll); |
|
1036 } |
|
1037 |
|
1038 /** |
|
1039 * Give visual hint on whether the data in the view is stale. |
|
1040 * |
|
1041 * @param stale |
|
1042 */ |
|
1043 private void showDataAsStale(boolean stale) { |
|
1044 if (m_disposed) |
|
1045 return; |
|
1046 |
|
1047 Color co = stale ? PlatformUI.getWorkbench().getDisplay() |
|
1048 .getSystemColor(SWT.COLOR_DARK_GRAY) : null; |
|
1049 |
|
1050 /* |
|
1051 * To show that data is stale, I display them in gray text. But the |
|
1052 * grayed out text is kinda hard to read. Another solution is to change |
|
1053 * the background to gray, but not ideal either..... 11/30/06 |
|
1054 */ |
|
1055 // m_overviewTreeViewer.getControl().setBackground(co); |
|
1056 m_overviewTreeViewer.getControl().setForeground(co); |
|
1057 m_processTableViewer.getControl().setForeground(co); |
|
1058 m_threadTableViewer.getControl().setForeground(co); |
|
1059 m_chunkTableViewer.getControl().setForeground(co); |
|
1060 m_libraryTableViewer.getControl().setForeground(co); |
|
1061 } |
|
1062 |
|
1063 private void scheduleTimedRefresh() { |
|
1064 if (m_currentSession == null || !m_currentSession.isActive()) |
|
1065 return; |
|
1066 |
|
1067 // Not for stop mode debug. |
|
1068 if (m_currentSession.isSystemModeDebug()) |
|
1069 return; |
|
1070 |
|
1071 // Honor preference settings real time. |
|
1072 m_timedRefreshInterval = CWPlugin |
|
1073 .getDefault() |
|
1074 .getPluginPreferences() |
|
1075 .getInt( |
|
1076 cwdbg.PreferenceConstants.J_PN_OSViewAutoRefreshInterval); |
|
1077 |
|
1078 Runnable timedRunnable = this; |
|
1079 |
|
1080 PlatformUI.getWorkbench().getDisplay().timerExec( |
|
1081 m_timedRefreshInterval * 1000 /* milliseconds */, |
|
1082 timedRunnable); |
|
1083 |
|
1084 } |
|
1085 |
|
1086 private void disableTimedRefresh() { |
|
1087 Runnable timedRunnable = this; |
|
1088 |
|
1089 PlatformUI.getWorkbench().getDisplay().timerExec(-1, timedRunnable); |
|
1090 } |
|
1091 |
|
1092 /** |
|
1093 * This is for timed auto-refresh of OS data in the view. Refer to where |
|
1094 * Display.timerExec() is invoked. |
|
1095 * |
|
1096 * @see java.lang.Runable#run |
|
1097 */ |
|
1098 public void run() { |
|
1099 // View is closed or session terminated |
|
1100 if (m_disposed || m_currentSession == null) |
|
1101 return; |
|
1102 |
|
1103 // show as stale. |
|
1104 showDataAsStale(true); |
|
1105 |
|
1106 // just in case this is cleared |
|
1107 if (m_currentSession == null) |
|
1108 return; |
|
1109 |
|
1110 // Refresh data if so requested. |
|
1111 if (m_autoRefresh) { |
|
1112 // Mark cache as dirty. |
|
1113 m_currentSession.getOSDataManager().setDataDirty(); |
|
1114 |
|
1115 computeInput(m_currentSession, this, false); |
|
1116 } else |
|
1117 scheduleTimedRefresh(); |
|
1118 } |
|
1119 |
|
1120 public void dataUpdated(final Session session, final IStatus status) { |
|
1121 // User already selected another session during refreshing. |
|
1122 // Just do nothing. "selectionChanged()" will make sure data for the new |
|
1123 // session will be displayed. |
|
1124 if (session != m_currentSession) { |
|
1125 return; |
|
1126 } |
|
1127 |
|
1128 final OSDataManager osDM = (OSDataManager) session.getOSDataManager(); |
|
1129 if (osDM == null) |
|
1130 return; |
|
1131 |
|
1132 /* |
|
1133 * Even if we got error, we treat the data as updated so that no more |
|
1134 * refreshing request will be handled until next auto-refresh or |
|
1135 * user-refresh. This way user won't get repeated error message when he, |
|
1136 * say, clicks on different target/thread of the same session in the debug view. |
|
1137 */ |
|
1138 osDM.setUpdatedFlag(0xFFFF); |
|
1139 |
|
1140 Runnable runnable = new Runnable() { |
|
1141 public void run() { |
|
1142 if (status.isOK()) { |
|
1143 // Remember tree state |
|
1144 Object[] expandedNodes = m_overviewTreeViewer |
|
1145 .getExpandedElements(); |
|
1146 ISelection selection = m_overviewTreeViewer.getSelection(); |
|
1147 |
|
1148 m_overviewTreeViewer.setInput(osDM); |
|
1149 |
|
1150 // Restore tree state |
|
1151 m_overviewTreeViewer.setExpandedElements(expandedNodes); |
|
1152 m_overviewTreeViewer.setSelection(selection); |
|
1153 m_overviewTreeViewer.getTree().showSelection(); |
|
1154 |
|
1155 m_processTableViewer.setInput(osDM); |
|
1156 m_threadTableViewer.setInput(osDM); |
|
1157 m_chunkTableViewer.setInput(osDM); |
|
1158 m_libraryTableViewer.setInput(osDM); |
|
1159 |
|
1160 /* |
|
1161 * The above call will populate the table. Here we can make |
|
1162 * sure each column is packed to show all info in preferred |
|
1163 * size. Do we really want to do this as it may be against |
|
1164 * user's desire ? Let's wait for user feedback....11/02/06 |
|
1165 */ |
|
1166 packTableViewer(m_processTableViewer); |
|
1167 packTableViewer(m_threadTableViewer); |
|
1168 |
|
1169 showDataAsStale(false); |
|
1170 } |
|
1171 |
|
1172 // Data refreshed, reschedule our next timed refresh. |
|
1173 scheduleTimedRefresh(); |
|
1174 |
|
1175 if (status.getSeverity() != IStatus.OK |
|
1176 && status.getSeverity() != IStatus.CANCEL) { |
|
1177 showDataAsStale(true); |
|
1178 // Now the computeInput() is done in a job, and job |
|
1179 // mechanism will display any error automatically. |
|
1180 } |
|
1181 } |
|
1182 }; |
|
1183 |
|
1184 // Don't update UI if the view is already closed by user. |
|
1185 if (!m_disposed) |
|
1186 PlatformUI.getWorkbench().getDisplay().asyncExec(runnable); |
|
1187 } |
|
1188 |
|
1189 public void handleDebugEvents(DebugEvent[] events) { |
|
1190 for (int i = 0; i < events.length; i++) { |
|
1191 DebugEvent event = events[i]; |
|
1192 |
|
1193 if (! (event.getSource() instanceof CDebugElement)) |
|
1194 continue; |
|
1195 |
|
1196 CDebugElement elem = (CDebugElement) event.getSource(); |
|
1197 if (elem == null || ! (elem.getCDISession() instanceof Session)) // not from our debugger |
|
1198 return; |
|
1199 |
|
1200 final Session session = (Session) elem.getCDISession(); |
|
1201 if (session == null) |
|
1202 return; |
|
1203 |
|
1204 if (event.getKind() == DebugEvent.TERMINATE && |
|
1205 elem instanceof ICDebugTarget) |
|
1206 { |
|
1207 // a Target (process) is terminated |
|
1208 if (session == m_currentSession && !session.isActive()) { |
|
1209 // and the session is terminated. |
|
1210 |
|
1211 session.getOSDataManager().setDataDirty(); |
|
1212 |
|
1213 updateActionStatus(); |
|
1214 |
|
1215 // remove timed task, if any. |
|
1216 PlatformUI.getWorkbench().getDisplay().syncExec( |
|
1217 new Runnable() { |
|
1218 public void run() { |
|
1219 disableTimedRefresh(); |
|
1220 |
|
1221 // Show data as stale after end of session. |
|
1222 showDataAsStale(true); |
|
1223 } |
|
1224 }); |
|
1225 |
|
1226 m_currentSession = null; |
|
1227 } |
|
1228 } |
|
1229 else if (event.getKind() == DebugEvent.CREATE && |
|
1230 elem instanceof ICThread) |
|
1231 { |
|
1232 // a thread in our debug session is created. |
|
1233 if (m_currentSession == null) { |
|
1234 // If the OS Data view has no associated session yet, |
|
1235 // associate it with the session so that OS Data View can |
|
1236 // show data for a never-stopped debug session. Fix bug 4428. |
|
1237 // ...... 12/04/07 |
|
1238 // But only do that for run mode debug. For stop mode, |
|
1239 // we should only show data whenever the system is stopped |
|
1240 // and the thread in Debug View is selected...12/05/07 |
|
1241 if (session.isSystemModeDebug()) |
|
1242 return; |
|
1243 |
|
1244 PlatformUI.getWorkbench().getDisplay().syncExec( |
|
1245 new Runnable() { |
|
1246 public void run() { |
|
1247 try { |
|
1248 showDataForDevice(session); |
|
1249 } |
|
1250 catch (InterruptedException e) { |
|
1251 e.printStackTrace(); |
|
1252 } |
|
1253 } |
|
1254 }); |
|
1255 } |
|
1256 } |
|
1257 } |
|
1258 } |
|
1259 } |