debuggercdi/com.nokia.carbide.cpp.debug.kernelaware/src/com/nokia/carbide/cpp/debug/kernelaware/ui/SymbianOSView.java
changeset 2 d760517a8095
child 20 5c466f93ffe1
equal deleted inserted replaced
-1:000000000000 2:d760517a8095
       
     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 }