| /******************************************************************************* |
| * Copyright (c) 2000, 2015 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Wind River - Pawel Piech - Busy status while updates in progress (Bug 206822) |
| * Pawel Piech (Wind River) - added a breadcrumb mode to Debug view (Bug 252677) |
| * Andrey Loskutov <loskutov@gmx.de> - fixed memory leak due the breadcrumb (Bug 466789) |
| *******************************************************************************/ |
| package org.eclipse.debug.internal.ui.views.launch; |
| |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.io.OutputStreamWriter; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.TreeSet; |
| |
| import org.eclipse.core.commands.IHandler2; |
| import org.eclipse.core.commands.contexts.ContextManagerEvent; |
| import org.eclipse.core.commands.contexts.IContextManagerListener; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.ILaunch; |
| import org.eclipse.debug.core.commands.IRestartHandler; |
| import org.eclipse.debug.core.model.IDebugTarget; |
| import org.eclipse.debug.core.model.IProcess; |
| import org.eclipse.debug.core.model.IStackFrame; |
| import org.eclipse.debug.internal.ui.DebugUIPlugin; |
| import org.eclipse.debug.internal.ui.DelegatingModelPresentation; |
| import org.eclipse.debug.internal.ui.IDebugHelpContextIds; |
| import org.eclipse.debug.internal.ui.actions.AddToFavoritesAction; |
| import org.eclipse.debug.internal.ui.actions.EditLaunchConfigurationAction; |
| import org.eclipse.debug.internal.ui.commands.actions.DisconnectCommandAction; |
| import org.eclipse.debug.internal.ui.commands.actions.DropToFrameCommandAction; |
| import org.eclipse.debug.internal.ui.commands.actions.RestartCommandAction; |
| import org.eclipse.debug.internal.ui.commands.actions.ResumeCommandAction; |
| import org.eclipse.debug.internal.ui.commands.actions.StepIntoCommandAction; |
| import org.eclipse.debug.internal.ui.commands.actions.StepOverCommandAction; |
| import org.eclipse.debug.internal.ui.commands.actions.StepReturnCommandAction; |
| import org.eclipse.debug.internal.ui.commands.actions.SuspendCommandAction; |
| import org.eclipse.debug.internal.ui.commands.actions.TerminateAllAction; |
| import org.eclipse.debug.internal.ui.commands.actions.TerminateAndRelaunchAction; |
| import org.eclipse.debug.internal.ui.commands.actions.TerminateAndRemoveAction; |
| import org.eclipse.debug.internal.ui.commands.actions.TerminateCommandAction; |
| import org.eclipse.debug.internal.ui.commands.actions.ToggleStepFiltersAction; |
| import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; |
| import org.eclipse.debug.internal.ui.sourcelookup.EditSourceLookupPathAction; |
| import org.eclipse.debug.internal.ui.sourcelookup.LookupSourceAction; |
| import org.eclipse.debug.internal.ui.viewers.model.InternalTreeModelViewer; |
| import org.eclipse.debug.internal.ui.viewers.model.VirtualFindAction; |
| import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; |
| import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; |
| import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDeltaVisitor; |
| import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; |
| import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; |
| import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; |
| import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener; |
| import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer; |
| import org.eclipse.debug.internal.ui.views.DebugModelPresentationContext; |
| import org.eclipse.debug.internal.ui.views.ViewContextService; |
| import org.eclipse.debug.ui.AbstractDebugView; |
| import org.eclipse.debug.ui.DebugUITools; |
| import org.eclipse.debug.ui.IDebugModelPresentation; |
| import org.eclipse.debug.ui.IDebugUIConstants; |
| import org.eclipse.debug.ui.actions.DebugCommandAction; |
| import org.eclipse.debug.ui.contexts.AbstractDebugContextProvider; |
| import org.eclipse.debug.ui.contexts.DebugContextEvent; |
| import org.eclipse.debug.ui.contexts.IDebugContextListener; |
| import org.eclipse.debug.ui.contexts.IDebugContextProvider; |
| import org.eclipse.jface.action.ActionContributionItem; |
| import org.eclipse.jface.action.GroupMarker; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IMenuListener; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.IToolBarManager; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.action.Separator; |
| import org.eclipse.jface.commands.ActionHandler; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.viewers.DoubleClickEvent; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.ITreeSelection; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.StructuredViewer; |
| import org.eclipse.jface.viewers.TreePath; |
| import org.eclipse.jface.viewers.TreeSelection; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.ControlEvent; |
| import org.eclipse.swt.events.ControlListener; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.ui.IActionBars; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.IPageListener; |
| import org.eclipse.ui.IPartListener2; |
| import org.eclipse.ui.IPerspectiveDescriptor; |
| import org.eclipse.ui.IPerspectiveListener2; |
| import org.eclipse.ui.IViewSite; |
| import org.eclipse.ui.IWorkbenchActionConstants; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPartReference; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.WorkbenchException; |
| import org.eclipse.ui.XMLMemento; |
| import org.eclipse.ui.actions.SelectionListenerAction; |
| import org.eclipse.ui.contexts.IContextService; |
| import org.eclipse.ui.dialogs.PropertyDialogAction; |
| import org.eclipse.ui.part.IPageBookViewPage; |
| import org.eclipse.ui.part.IPageSite; |
| import org.eclipse.ui.part.IShowInSource; |
| import org.eclipse.ui.part.IShowInTarget; |
| import org.eclipse.ui.part.IShowInTargetList; |
| import org.eclipse.ui.part.Page; |
| import org.eclipse.ui.part.ShowInContext; |
| import org.eclipse.ui.progress.IWorkbenchSiteProgressService; |
| import org.eclipse.ui.progress.UIJob; |
| import org.eclipse.ui.texteditor.IUpdate; |
| |
| public class LaunchView extends AbstractDebugView |
| implements ISelectionChangedListener, IPerspectiveListener2, IPageListener, IShowInTarget, IShowInSource, |
| IShowInTargetList, IPartListener2, IViewerUpdateListener, IContextManagerListener, IModelChangedListener |
| { |
| |
| public static final String ID_CONTEXT_ACTIVITY_BINDINGS = "contextActivityBindings"; //$NON-NLS-1$ |
| |
| private static final String TERMINATE = "terminate"; //$NON-NLS-1$ |
| |
| private static final String DISCONNECT = "disconnect"; //$NON-NLS-1$ |
| |
| private static final String SUSPEND = "suspend"; //$NON-NLS-1$ |
| |
| private static final String RESUME = "resume"; //$NON-NLS-1$ |
| |
| private static final String STEP_RETURN = "step_return"; //$NON-NLS-1$ |
| |
| private static final String STEP_OVER = "step_over"; //$NON-NLS-1$ |
| |
| private static final String DROP_TO_FRAME = "drop_to_frame"; //$NON-NLS-1$ |
| |
| private static final String STEP_INTO = "step_into"; //$NON-NLS-1$ |
| |
| public static final String TERMINATE_AND_REMOVE = "terminate_and_remove"; //$NON-NLS-1$ |
| |
| private static final String TERMINATE_ALL = "terminate_all"; //$NON-NLS-1$ |
| |
| public static final String TERMINATE_AND_RELAUNCH = "terminate_relaunch"; //$NON-NLS-1$ |
| |
| private static final String TOGGLE_STEP_FILTERS = "toggle_step_filters"; //$NON-NLS-1$ |
| |
| private static final String RESTART = "restart"; //$NON-NLS-1$ |
| |
| private static final int BREADCRUMB_TRIGGER_HEIGHT_DEFAULT = 30; // pixels |
| |
| private static final int BREADCRUMB_TRIGGER_RANGE = 5; // pixels |
| |
| private static final int BREADCRUMB_STICKY_RANGE = 20; // pixels |
| |
| /** |
| * Whether this view is in the active page of a perspective. |
| */ |
| private boolean fIsActive = true; |
| |
| /** |
| * Model presentation or <code>null</code> if none |
| */ |
| private IDebugModelPresentation fPresentation = null; |
| |
| private IPresentationContext fPresentationContext; |
| |
| private EditLaunchConfigurationAction fEditConfigAction = null; |
| private AddToFavoritesAction fAddToFavoritesAction = null; |
| private EditSourceLookupPathAction fEditSourceAction = null; |
| private LookupSourceAction fLookupAction = null; |
| |
| /** |
| * Current view mode (auto vs. breadcrumb, vs. tree view). |
| * |
| * @since 3.5 |
| */ |
| private String fCurrentViewMode = IDebugPreferenceConstants.DEBUG_VIEW_MODE_AUTO; |
| |
| /** |
| * Actions for selecting the view mode (auto vs. breadcrumb, vs. tree view). |
| * |
| * @since 3.5 |
| */ |
| private DebugViewModeAction[] fDebugViewModeActions; |
| |
| /** |
| * Action which shows or hides the Debug view toolbar. |
| */ |
| private DebugToolBarAction fDebugToolBarAction; |
| |
| /** |
| * Action that controls the breadcrumb drop-down auto-expand behavior. |
| * |
| * @since 3.5 |
| */ |
| private BreadcrumbDropDownAutoExpandAction fBreadcrumbDropDownAutoExpandAction; |
| |
| /** |
| * Context service for this view. Used to track whether debug toolbar |
| * action set is active. |
| * |
| * @since 3.8 |
| */ |
| private IContextService fContextService; |
| |
| /** |
| * Preference name for the view's memento. |
| * |
| * @since 3.5 |
| */ |
| private String PREF_STATE_MEMENTO = "pref_state_memento."; //$NON-NLS-1$ |
| |
| /** |
| * Key for a view preference for whether the elements in breadcrumb's |
| * drop-down viewer should be automatically expanded. |
| * |
| * @since 3.5 |
| */ |
| private static final String BREADCRUMB_DROPDOWN_AUTO_EXPAND = DebugUIPlugin.getUniqueIdentifier() + ".BREADCRUMB_DROPDOWN_AUTO_EXPAND"; //$NON-NLS-1$ |
| |
| /** |
| * Preference for whether the elements in breadcrumb's |
| * drop-down viewer should be automatically expanded. |
| * |
| * @since 3.5 |
| */ |
| private boolean fBreadcrumbDropDownAutoExpand = false; |
| |
| /** |
| * Action handlers. Maps action identifiers to IHandler's. |
| * |
| * @since 3.6 |
| */ |
| private Map<String, IHandler2> fHandlers = new HashMap<String, IHandler2>(); |
| |
| private boolean fDebugToolbarInView = true; |
| |
| private Set<String> fDebugToolbarPerspectives = new TreeSet<String>(); |
| |
| /** |
| * Page-book page for the breadcrumb viewer. This page is activated in |
| * Debug view when the height of the view is reduced to just one line. |
| * |
| * @since 3.5 |
| */ |
| private class BreadcrumbPage extends Page { |
| |
| LaunchViewBreadcrumb fCrumb; |
| Control fControl; |
| |
| @Override |
| public void createControl(Composite parent) { |
| fCrumb = new LaunchViewBreadcrumb(LaunchView.this, (TreeModelViewer)getViewer(), fTreeViewerDebugContextProvider); |
| fControl = fCrumb.createContent(parent); |
| } |
| |
| @Override |
| public void init(IPageSite pageSite) { |
| super.init(pageSite); |
| pageSite.setSelectionProvider(fCrumb.getSelectionProvider()); |
| } |
| |
| @Override |
| public Control getControl() { |
| return fControl; |
| } |
| |
| @Override |
| public void setFocus() { |
| fCrumb.activate(); |
| } |
| |
| IDebugContextProvider getContextProvider() { |
| return fCrumb.getContextProvider(); |
| } |
| |
| int getHeight() { |
| return fCrumb.getHeight(); |
| } |
| |
| @Override |
| public void dispose() { |
| fCrumb.dispose(); |
| } |
| } |
| |
| private BreadcrumbPage fBreadcrumbPage; |
| |
| class TreeViewerContextProvider extends AbstractDebugContextProvider implements IModelChangedListener { |
| |
| private ISelection fContext = null; |
| private TreeModelViewer fViewer = null; |
| private Visitor fVisitor = new Visitor(); |
| |
| class Visitor implements IModelDeltaVisitor { |
| @Override |
| public boolean visit(IModelDelta delta, int depth) { |
| if ((delta.getFlags() & (IModelDelta.STATE | IModelDelta.CONTENT)) > 0) { |
| // state and/or content change |
| if ((delta.getFlags() & IModelDelta.SELECT) == 0) { |
| // no select flag |
| if ((delta.getFlags() & IModelDelta.CONTENT) > 0) { |
| // content has changed without select >> possible re-activation |
| possibleChange(getViewerTreePath(delta), DebugContextEvent.ACTIVATED); |
| } else if ((delta.getFlags() & IModelDelta.STATE) > 0) { |
| // state has changed without select >> possible state change of active context |
| possibleChange(getViewerTreePath(delta), DebugContextEvent.STATE); |
| } |
| } |
| } |
| return true; |
| } |
| } |
| |
| /** |
| * Returns a tree path for the node, *not* including the root element. |
| * |
| * @param node |
| * model delta |
| * @return corresponding tree path |
| */ |
| private TreePath getViewerTreePath(IModelDelta node) { |
| ArrayList<Object> list = new ArrayList<Object>(); |
| IModelDelta parentDelta = node.getParentDelta(); |
| while (parentDelta != null) { |
| list.add(0, node.getElement()); |
| node = parentDelta; |
| parentDelta = node.getParentDelta(); |
| } |
| return new TreePath(list.toArray()); |
| } |
| |
| public TreeViewerContextProvider(TreeModelViewer viewer) { |
| super(LaunchView.this); |
| fViewer = viewer; |
| fViewer.addModelChangedListener(this); |
| } |
| |
| protected void dispose() { |
| fContext = null; |
| fViewer.removeModelChangedListener(this); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.contexts.IDebugContextProvider#getActiveContext() |
| */ |
| @Override |
| public synchronized ISelection getActiveContext() { |
| return fContext; |
| } |
| |
| protected void activate(ISelection selection) { |
| synchronized (this) { |
| fContext = selection; |
| } |
| fire(new DebugContextEvent(this, selection, DebugContextEvent.ACTIVATED)); |
| } |
| |
| protected void possibleChange(TreePath element, int type) { |
| DebugContextEvent event = null; |
| synchronized (this) { |
| if (fContext instanceof ITreeSelection) { |
| ITreeSelection ss = (ITreeSelection) fContext; |
| TreePath[] ssPaths = ss.getPaths(); |
| for (int i = 0; i < ssPaths.length; i++) { |
| if (ssPaths[i].startsWith(element, null)) { |
| if (ssPaths[i].getSegmentCount() == element.getSegmentCount()) { |
| event = new DebugContextEvent(this, fContext, type); |
| } else { |
| // if parent of the currently selected element |
| // changes, issue event to update STATE only |
| event = new DebugContextEvent(this, fContext, DebugContextEvent.STATE); |
| } |
| } |
| } |
| } |
| } |
| if (event == null) { |
| return; |
| } |
| if (getControl().getDisplay().getThread() == Thread.currentThread()) { |
| fire(event); |
| } else { |
| final DebugContextEvent finalEvent = event; |
| Job job = new UIJob("context change") { //$NON-NLS-1$ |
| @Override |
| public IStatus runInUIThread(IProgressMonitor monitor) { |
| // verify selection is still the same context since job was scheduled |
| synchronized (TreeViewerContextProvider.this) { |
| if (fContext instanceof IStructuredSelection) { |
| IStructuredSelection ss = (IStructuredSelection) fContext; |
| Object changed = ((IStructuredSelection)finalEvent.getContext()).getFirstElement(); |
| if (!(ss.size() == 1 && ss.getFirstElement().equals(changed))) { |
| return Status.OK_STATUS; |
| } |
| } |
| } |
| fire(finalEvent); |
| return Status.OK_STATUS; |
| } |
| }; |
| job.setSystem(true); |
| job.schedule(); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener#modelChanged(org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta) |
| */ |
| @Override |
| public void modelChanged(IModelDelta delta, IModelProxy proxy) { |
| delta.accept(fVisitor); |
| } |
| |
| } |
| |
| /** |
| * Context provider |
| */ |
| private TreeViewerContextProvider fTreeViewerDebugContextProvider; |
| |
| /** |
| * The PageBookView, which is a base class of this class does not make it |
| * easy to control which page is currently active. It is intended that the |
| * page book pages are associated with workbench parts, and the parts are |
| * in turn associated with PageRec records. |
| * <p> |
| * PageRec is needed in order to properly active a page book page, by |
| * calling showPageRec(), so in this class we need to add some hooks in |
| * order to obtain the page record for the tree viewer page and the |
| * breadcrumb page.</p><p> |
| * For the default page, we override the showPageRec() |
| * to determine if the default page is being shown and if it is, we save |
| * its record for later use. showPageRec() is always called for the default |
| * page after it is created. For the breadcrumb page, we use the page book |
| * view mechanism to create the page based on a workbench part, but we have |
| * to create a dummy part in order for this to work. |
| * </p> |
| * <p> |
| * See bug 262845 and 262870. |
| * </p> |
| * |
| * @see #createPartControl(Composite) |
| * @see BreadcrumbWorkbenchPart |
| * @eee #doCreatePage(IWorkbenchPart) |
| * @see #isImportant(IWorkbenchPart) |
| * @see #autoSelectViewPage(Composite) |
| * @see #showTreeViewerPage() |
| * @see #showBreadcrumbPage() |
| */ |
| private PageRec fDefaultPageRec = null; |
| |
| private ISelectionChangedListener fTreeViewerSelectionChangedListener = new ISelectionChangedListener() { |
| @Override |
| public void selectionChanged(SelectionChangedEvent event) { |
| fTreeViewerDebugContextProvider.activate(event.getSelection()); |
| } |
| }; |
| |
| private class ContextProviderProxy extends AbstractDebugContextProvider implements IDebugContextListener { |
| private IDebugContextProvider fActiveProvider; |
| private IDebugContextProvider[] fProviders; |
| |
| ContextProviderProxy(IDebugContextProvider[] providers) { |
| super(LaunchView.this); |
| fProviders = providers; |
| fActiveProvider = providers[0]; |
| for (int i = 0; i < fProviders.length; i++) { |
| fProviders[i].addDebugContextListener(this); |
| } |
| } |
| |
| void setActiveProvider(IDebugContextProvider provider) { |
| if (!provider.equals(fActiveProvider)) { |
| ISelection activeContext = getActiveContext(); |
| fActiveProvider = provider; |
| ISelection newActiveContext = getActiveContext(); |
| if (!activeContext.equals(newActiveContext)) { |
| fire(new DebugContextEvent(this, getActiveContext(), DebugContextEvent.ACTIVATED)); |
| } |
| } |
| } |
| |
| @Override |
| public ISelection getActiveContext() { |
| ISelection activeContext = fActiveProvider.getActiveContext(); |
| if (activeContext != null) { |
| return activeContext; |
| } |
| return TreeSelection.EMPTY; |
| } |
| |
| @Override |
| public void debugContextChanged(DebugContextEvent event) { |
| if (event.getSource().equals(fActiveProvider)) { |
| fire(new DebugContextEvent(this, event.getContext(), event.getFlags())); |
| } |
| } |
| |
| void dispose() { |
| for (int i = 0; i < fProviders.length; i++) { |
| fProviders[i].removeDebugContextListener(this); |
| } |
| fProviders = null; |
| fActiveProvider = null; |
| } |
| } |
| |
| private ContextProviderProxy fContextProviderProxy; |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.AbstractDebugView#getHelpContextId() |
| */ |
| @Override |
| protected String getHelpContextId() { |
| return IDebugHelpContextIds.DEBUG_VIEW; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.AbstractDebugView#createActions() |
| */ |
| @Override |
| protected void createActions() { |
| setAction("Properties", new PropertyDialogAction(getSite(), getSite().getSelectionProvider())); //$NON-NLS-1$ |
| fEditConfigAction = new EditLaunchConfigurationAction(); |
| fAddToFavoritesAction = new AddToFavoritesAction(); |
| fEditSourceAction = new EditSourceLookupPathAction(this); |
| fLookupAction = new LookupSourceAction(this); |
| setAction(FIND_ACTION, new VirtualFindAction((TreeModelViewer) getViewer())); |
| |
| addCapabilityAction(new TerminateCommandAction(), TERMINATE); |
| addCapabilityAction(new DisconnectCommandAction(), DISCONNECT); |
| addCapabilityAction(new SuspendCommandAction(), SUSPEND); |
| addCapabilityAction(new ResumeCommandAction(), RESUME); |
| addCapabilityAction(new StepReturnCommandAction(), STEP_RETURN); |
| addCapabilityAction(new StepOverCommandAction(), STEP_OVER); |
| addCapabilityAction(new StepIntoCommandAction(), STEP_INTO); |
| addCapabilityAction(new DropToFrameCommandAction(), DROP_TO_FRAME); |
| DebugCommandAction action = new TerminateAndRemoveAction(); |
| addCapabilityAction(action, TERMINATE_AND_REMOVE); |
| setHandler(TERMINATE_AND_REMOVE, new ActionHandler(action)); |
| action = new TerminateAndRelaunchAction(); |
| addCapabilityAction(action, TERMINATE_AND_RELAUNCH); |
| setHandler(TERMINATE_AND_RELAUNCH, new ActionHandler(action)); |
| addCapabilityAction(new RestartCommandAction(), RESTART); |
| addCapabilityAction(new TerminateAllAction(), TERMINATE_ALL); |
| addCapabilityAction(new ToggleStepFiltersAction(), TOGGLE_STEP_FILTERS); |
| } |
| |
| /** |
| * Sets the handler associated with the given action identifier. |
| * |
| * @param id action identifier |
| * @param handler handler |
| */ |
| private void setHandler(String id, IHandler2 handler) { |
| fHandlers.put(id, handler); |
| } |
| |
| /** |
| * Returns the handler associated with the given action identifier or <code>null</code>. |
| * |
| * @param id action identifier |
| * @return handler or <code>null</code> |
| */ |
| public IHandler2 getHandler(String id) { |
| return fHandlers.get(id); |
| } |
| |
| /** |
| * Initializes the action and associates it with the given id. |
| * |
| * @param capability |
| * @param actionID |
| */ |
| private void addCapabilityAction(DebugCommandAction capability, String actionID) { |
| capability.init(this); |
| setAction(actionID, capability); |
| } |
| |
| /** |
| * Disposes the given action. |
| * |
| * @param actionID |
| */ |
| private void disposeCommandAction(String actionID) { |
| DebugCommandAction action = (DebugCommandAction) getAction(actionID); |
| action.dispose(); |
| } |
| |
| /** |
| * Override the default implementation to create the breadcrumb page. |
| * |
| * @since 3.5 |
| * @see #fDefaultPageRec |
| */ |
| @Override |
| public void createPartControl(final Composite parent) { |
| super.createPartControl(parent); |
| |
| // Copy the global action handlers to the default page. |
| setGlobalActionBarsToPage((IPageBookViewPage)getDefaultPage()); |
| |
| // Add view as a selection listener to the site. |
| getSite().getSelectionProvider().addSelectionChangedListener(this); |
| |
| // Set the tree viewer as the selection provider to the default page. |
| // The page book view handles switching the between page selection |
| // providers as needed. |
| ((IPageBookViewPage)getDefaultPage()).getSite().setSelectionProvider(getViewer()); |
| |
| // Call the PageBookView part listener to indirectly create the breadcrumb page. |
| // This call eventually calls doCreatePage() implemented below. |
| partActivated(new BreadcrumbWorkbenchPart(getSite())); |
| |
| fContextProviderProxy = new ContextProviderProxy( |
| new IDebugContextProvider[] {fTreeViewerDebugContextProvider, fBreadcrumbPage.getContextProvider()}); |
| DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow()).addDebugContextProvider(fContextProviderProxy); |
| |
| // Create and configure actions for selecting view mode. |
| createViewModeActions(parent); |
| IPreferenceStore prefStore = DebugUIPlugin.getDefault().getPreferenceStore(); |
| String mode = prefStore.getString(IDebugPreferenceConstants.DEBUG_VIEW_MODE); |
| setViewMode(mode, parent); |
| for (int i = 0; i < fDebugViewModeActions.length; i++) { |
| fDebugViewModeActions[i].setChecked(fDebugViewModeActions[i].getMode().equals(mode)); |
| } |
| |
| createDebugToolBarInViewActions(parent); |
| |
| // Add a resize listener for the view to activate breadcrumb as needed. |
| parent.addControlListener(new ControlListener() { |
| @Override |
| public void controlMoved(ControlEvent e) { |
| } |
| @Override |
| public void controlResized(ControlEvent e) { |
| if (parent.isDisposed()) { |
| return; |
| } |
| if (IDebugPreferenceConstants.DEBUG_VIEW_MODE_AUTO.equals(fCurrentViewMode)) { |
| autoSelectViewPage(parent); |
| } |
| } |
| }); |
| |
| fContextService.addContextManagerListener(this); |
| } |
| |
| /** |
| * Copies the view's global action handlers created by createActions(), |
| * into the page site's action bars. This is necessary because the page |
| * book view resets the view site's global actions after each page switch |
| * (see bug 264618). |
| * |
| * @param page Page to copy the global actions into. |
| * |
| * @since 3.5 |
| */ |
| private void setGlobalActionBarsToPage(IPageBookViewPage page) { |
| IActionBars pageActionBars = page.getSite().getActionBars(); |
| // Set the view site action bars created by createActions() to the |
| // default page site. |
| IActionBars bars = getViewSite().getActionBars(); |
| pageActionBars.setGlobalActionHandler(FIND_ACTION, bars.getGlobalActionHandler(FIND_ACTION)); |
| pageActionBars.setGlobalActionHandler(COPY_ACTION, bars.getGlobalActionHandler(COPY_ACTION)); |
| } |
| |
| /** |
| * Override the default implementation to create the breadcrumb page. |
| * |
| * @since 3.5 |
| * @see #fDefaultPageRec |
| */ |
| @Override |
| protected PageRec doCreatePage(IWorkbenchPart part) { |
| if (part instanceof BreadcrumbWorkbenchPart) { |
| fBreadcrumbPage = new BreadcrumbPage(); |
| fBreadcrumbPage.createControl(getPageBook()); |
| initPage(fBreadcrumbPage); |
| setGlobalActionBarsToPage(fBreadcrumbPage); |
| return new PageRec(part, fBreadcrumbPage); |
| } |
| return null; |
| } |
| |
| /** |
| * Override the default implementation to create the breadcrumb page. |
| * |
| * @since 3.5 |
| * @see #fDefaultPageRec |
| */ |
| @Override |
| protected boolean isImportant(IWorkbenchPart part) { |
| return part instanceof BreadcrumbWorkbenchPart; |
| } |
| |
| /** |
| * Override the default implementation to gain access at the default |
| * page record. |
| * |
| * @since 3.5 |
| * @see #fDefaultPageRec |
| */ |
| @Override |
| protected void showPageRec(PageRec pageRec) { |
| if (pageRec.page == getDefaultPage()) { |
| fDefaultPageRec = pageRec; |
| } |
| |
| super.showPageRec(pageRec); |
| } |
| |
| /** |
| * Creates actions for controlling view mode. |
| * |
| * @param parent The view's parent control used to calculate view size |
| * in auto mode. |
| */ |
| private void createViewModeActions(final Composite parent) { |
| IActionBars actionBars = getViewSite().getActionBars(); |
| IMenuManager viewMenu = actionBars.getMenuManager(); |
| |
| fDebugViewModeActions = new DebugViewModeAction[3]; |
| fDebugViewModeActions[0] = new DebugViewModeAction(this, IDebugPreferenceConstants.DEBUG_VIEW_MODE_AUTO, parent); |
| fDebugViewModeActions[1] = new DebugViewModeAction(this, IDebugPreferenceConstants.DEBUG_VIEW_MODE_FULL, parent); |
| fDebugViewModeActions[2] = new DebugViewModeAction(this, IDebugPreferenceConstants.DEBUG_VIEW_MODE_COMPACT, parent); |
| fBreadcrumbDropDownAutoExpandAction = new BreadcrumbDropDownAutoExpandAction(this); |
| viewMenu.add(new Separator()); |
| |
| final MenuManager modeSubmenu = new MenuManager(LaunchViewMessages.LaunchView_ViewModeMenu_label); |
| modeSubmenu.setRemoveAllWhenShown(true); |
| modeSubmenu.add(fDebugViewModeActions[0]); |
| modeSubmenu.add(fDebugViewModeActions[1]); |
| modeSubmenu.add(fDebugViewModeActions[2]); |
| modeSubmenu.add(new Separator()); |
| modeSubmenu.add(fBreadcrumbDropDownAutoExpandAction); |
| viewMenu.add(modeSubmenu); |
| |
| modeSubmenu.addMenuListener(new IMenuListener() { |
| @Override |
| public void menuAboutToShow(IMenuManager manager) { |
| modeSubmenu.add(fDebugViewModeActions[0]); |
| modeSubmenu.add(fDebugViewModeActions[1]); |
| modeSubmenu.add(fDebugViewModeActions[2]); |
| modeSubmenu.add(new Separator()); |
| modeSubmenu.add(fBreadcrumbDropDownAutoExpandAction); |
| } |
| }); |
| } |
| |
| /** |
| * Creates actions for controlling view mode. |
| * |
| * @param parent The view's parent control used to calculate view size |
| * in auto mode. |
| */ |
| private void createDebugToolBarInViewActions(final Composite parent) { |
| IActionBars actionBars = getViewSite().getActionBars(); |
| IMenuManager viewMenu = actionBars.getMenuManager(); |
| |
| fDebugToolBarAction = new DebugToolBarAction(this); |
| viewMenu.add(fDebugToolBarAction); |
| updateCheckedDebugToolBarAction(); |
| } |
| |
| |
| /** |
| * Sets the current view mode. If needed, the active view page is changed. |
| * |
| * @param mode New mode to set. |
| * @param parent The view's parent control used to calculate view size |
| * in auto mode. |
| * |
| * @since 3.5 |
| */ |
| void setViewMode(String mode, Composite parent) { |
| if (fCurrentViewMode.equals(mode)) { |
| return; |
| } |
| |
| fCurrentViewMode = mode; |
| if (IDebugPreferenceConstants.DEBUG_VIEW_MODE_COMPACT.equals(mode)) { |
| showBreadcrumbPage(); |
| } else if (IDebugPreferenceConstants.DEBUG_VIEW_MODE_FULL.equals(mode)) { |
| showTreeViewerPage(); |
| } else { |
| autoSelectViewPage(parent); |
| } |
| DebugUIPlugin.getDefault().getPreferenceStore().setValue(IDebugPreferenceConstants.DEBUG_VIEW_MODE, mode); |
| } |
| |
| /** |
| * Based on the current view size, select the active view page |
| * (tree viewer vs. breadcrumb). |
| * |
| * @param parent View pane control. |
| * |
| * @since 3.5 |
| */ |
| private void autoSelectViewPage(Composite parent) { |
| int breadcrumbHeight = fBreadcrumbPage.getHeight(); |
| // Breadcrumb may report size 0 if it hasn't been shown yet. |
| // Bug 335536. |
| if (breadcrumbHeight == 0) { |
| breadcrumbHeight = BREADCRUMB_TRIGGER_HEIGHT_DEFAULT; |
| } |
| if (parent.getClientArea().height < breadcrumbHeight + BREADCRUMB_TRIGGER_RANGE) { |
| showBreadcrumbPage(); |
| } |
| else if (parent.getClientArea().height > breadcrumbHeight + BREADCRUMB_STICKY_RANGE) |
| { |
| showTreeViewerPage(); |
| } |
| } |
| |
| |
| /** |
| * Shows the tree viewer in the Debug view. |
| * |
| * @since 3.5 |
| */ |
| void showTreeViewerPage() { |
| if (fDefaultPageRec != null && !getDefaultPage().equals(getCurrentPage())) { |
| showPageRec(fDefaultPageRec); |
| fContextProviderProxy.setActiveProvider(fTreeViewerDebugContextProvider); |
| // Clear the selection in the breadcrumb to avoid having it re-selected |
| // when the breadcrumb is activated again (bug 268124). |
| fBreadcrumbPage.fCrumb.clearSelection(); |
| } |
| } |
| |
| /** |
| * Shows the breadcrumb in the Debug view. |
| * |
| * @since 3.5 |
| */ |
| void showBreadcrumbPage() { |
| PageRec rec = getPageRec(fBreadcrumbPage); |
| if (rec != null && !fBreadcrumbPage.equals(getCurrentPage())) { |
| showPageRec(rec); |
| // Ask the breadcrumb to take focus if we're the active part. |
| if (getSite().getPage().getActivePart() == this) { |
| setFocus(); |
| } |
| fBreadcrumbPage.fCrumb.debugContextChanged(new DebugContextEvent( |
| fTreeViewerDebugContextProvider, |
| fTreeViewerDebugContextProvider.getActiveContext(), |
| DebugContextEvent.ACTIVATED)); |
| fContextProviderProxy.setActiveProvider(fBreadcrumbPage.getContextProvider()); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.AbstractDebugView#createViewer(org.eclipse.swt.widgets.Composite) |
| */ |
| @Override |
| protected Viewer createViewer(Composite parent) { |
| fPresentation = new DelegatingModelPresentation(); |
| fPresentationContext = new DebugModelPresentationContext(IDebugUIConstants.ID_DEBUG_VIEW, this, fPresentation); |
| TreeModelViewer viewer = new TreeModelViewer(parent, |
| SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.VIRTUAL, |
| fPresentationContext); |
| |
| viewer.addSelectionChangedListener(fTreeViewerSelectionChangedListener); |
| viewer.addViewerUpdateListener(this); |
| viewer.addModelChangedListener(this); |
| |
| viewer.setInput(DebugPlugin.getDefault().getLaunchManager()); |
| //setEventHandler(new LaunchViewEventHandler(this)); |
| fTreeViewerDebugContextProvider = new TreeViewerContextProvider(viewer); |
| |
| return viewer; |
| } |
| |
| private void commonInit(IViewSite site) { |
| site.getPage().addPartListener((IPartListener2) this); |
| site.getWorkbenchWindow().addPageListener(this); |
| site.getWorkbenchWindow().addPerspectiveListener(this); |
| } |
| |
| private void preferenceInit(IViewSite site) { |
| PREF_STATE_MEMENTO = PREF_STATE_MEMENTO + site.getId(); |
| IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore(); |
| String string = store.getString(PREF_STATE_MEMENTO); |
| if(string.length() > 0) { |
| try (ByteArrayInputStream bin = new ByteArrayInputStream(string.getBytes()); InputStreamReader reader = new InputStreamReader(bin)) { |
| XMLMemento stateMemento = XMLMemento.createReadRoot(reader); |
| setMemento(stateMemento); |
| } catch (WorkbenchException e) { |
| } catch (IOException e1) { |
| } |
| } |
| IMemento mem = getMemento(); |
| |
| if (mem != null) { |
| Boolean auto = mem.getBoolean(BREADCRUMB_DROPDOWN_AUTO_EXPAND); |
| if(auto != null) { |
| setBreadcrumbDropDownAutoExpand(auto.booleanValue()); |
| } |
| } |
| |
| String preference = DebugUIPlugin.getDefault().getPreferenceStore().getString( |
| IDebugPreferenceConstants.DEBUG_VIEW_TOOLBAR_HIDDEN_PERSPECTIVES); |
| if (preference != null) { |
| fDebugToolbarPerspectives = ViewContextService.parseList(preference); |
| } |
| IPerspectiveDescriptor perspective = getSite().getPage().getPerspective(); |
| fDebugToolbarInView = isDebugToolbarShownInPerspective(perspective); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite) |
| */ |
| @Override |
| public void init(IViewSite site) throws PartInitException { |
| super.init(site); |
| commonInit(site); |
| preferenceInit(site); |
| fContextService = site.getService(IContextService.class); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento) |
| */ |
| @Override |
| public void init(IViewSite site, IMemento memento) throws PartInitException { |
| super.init(site, memento); |
| commonInit(site); |
| preferenceInit(site); |
| fContextService = site.getService(IContextService.class); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.part.PageBookView#partDeactivated(org.eclipse.ui.IWorkbenchPart) |
| */ |
| @Override |
| public void partDeactivated(IWorkbenchPart part) { |
| String id = part.getSite().getId(); |
| if (id.equals(getSite().getId())) { |
| try (ByteArrayOutputStream bout = new ByteArrayOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(bout);) { |
| XMLMemento memento = XMLMemento.createWriteRoot("DebugViewMemento"); //$NON-NLS-1$ |
| saveViewerState(memento); |
| memento.save(writer); |
| |
| IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore(); |
| String xmlString = bout.toString(); |
| store.putValue(PREF_STATE_MEMENTO, xmlString); |
| } catch (IOException e) { |
| } |
| } |
| |
| StringBuffer buffer= new StringBuffer(); |
| for (Iterator<String> itr = fDebugToolbarPerspectives.iterator(); itr.hasNext();) { |
| buffer.append(itr.next()).append(','); |
| } |
| getPreferenceStore().setValue(IDebugPreferenceConstants.DEBUG_VIEW_TOOLBAR_HIDDEN_PERSPECTIVES, buffer.toString()); |
| |
| super.partDeactivated(part); |
| } |
| |
| /** |
| * Saves the current state of the viewer |
| * @param memento the memento to write the viewer state into |
| */ |
| public void saveViewerState(IMemento memento) { |
| memento.putBoolean(BREADCRUMB_DROPDOWN_AUTO_EXPAND, getBreadcrumbDropDownAutoExpand()); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.AbstractDebugView#configureToolBar(org.eclipse.jface.action.IToolBarManager) |
| */ |
| @Override |
| protected void configureToolBar(IToolBarManager tbm) { |
| tbm.add(new Separator(IDebugUIConstants.THREAD_GROUP)); |
| tbm.add(new Separator(IDebugUIConstants.STEP_GROUP)); |
| tbm.add(new GroupMarker(IDebugUIConstants.STEP_INTO_GROUP)); |
| tbm.add(new GroupMarker(IDebugUIConstants.STEP_OVER_GROUP)); |
| tbm.add(new GroupMarker(IDebugUIConstants.STEP_RETURN_GROUP)); |
| tbm.add(new GroupMarker(IDebugUIConstants.EMPTY_STEP_GROUP)); |
| tbm.add(new Separator(IDebugUIConstants.RENDER_GROUP)); |
| |
| if (fDebugToolbarInView) { |
| addDebugToolbarActions(tbm); |
| } |
| } |
| |
| protected void addDebugToolbarActions(IToolBarManager tbm) { |
| tbm.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(RESUME)); |
| tbm.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(SUSPEND)); |
| tbm.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(TERMINATE)); |
| tbm.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(DISCONNECT)); |
| |
| tbm.appendToGroup(IDebugUIConstants.STEP_INTO_GROUP, getAction(STEP_INTO)); |
| tbm.appendToGroup(IDebugUIConstants.STEP_OVER_GROUP, getAction(STEP_OVER)); |
| tbm.appendToGroup(IDebugUIConstants.STEP_RETURN_GROUP, getAction(STEP_RETURN)); |
| |
| tbm.appendToGroup(IDebugUIConstants.EMPTY_STEP_GROUP, getAction(DROP_TO_FRAME)); |
| |
| tbm.appendToGroup(IDebugUIConstants.RENDER_GROUP, getAction(TOGGLE_STEP_FILTERS)); |
| } |
| |
| /** |
| * Removes the toolbar actions contributed by this view from the toolbar |
| * manager. |
| * @param tbm |
| */ |
| protected void removeDebugToolbarActions(IToolBarManager tbm) { |
| tbm.remove(new ActionContributionItem(getAction(RESUME))); |
| tbm.remove(new ActionContributionItem(getAction(SUSPEND))); |
| tbm.remove(new ActionContributionItem(getAction(TERMINATE))); |
| tbm.remove(new ActionContributionItem(getAction(DISCONNECT))); |
| |
| tbm.remove(new ActionContributionItem(getAction(STEP_INTO))); |
| tbm.remove(new ActionContributionItem(getAction(STEP_OVER))); |
| tbm.remove(new ActionContributionItem(getAction(STEP_RETURN))); |
| |
| tbm.remove(new ActionContributionItem(getAction(DROP_TO_FRAME))); |
| |
| tbm.remove(new ActionContributionItem(getAction(TOGGLE_STEP_FILTERS))); |
| } |
| |
| public boolean isDebugToolbarInView() { |
| return fDebugToolbarInView; |
| } |
| |
| public boolean isDebugToolbarShownInPerspective(IPerspectiveDescriptor perspective) { |
| return perspective == null || fDebugToolbarPerspectives.contains(perspective.getId()); |
| } |
| |
| public void setDebugToolbarInView(boolean show) { |
| if (show == isDebugToolbarInView()) { |
| return; |
| } |
| fDebugToolbarInView = show; |
| |
| // Update the perspectives set. |
| IPerspectiveDescriptor perspective = getSite().getPage().getPerspective(); |
| if (perspective != null) { |
| if (show) { |
| fDebugToolbarPerspectives.add(perspective.getId()); |
| } else { |
| fDebugToolbarPerspectives.remove(perspective.getId()); |
| } |
| } |
| |
| // Update the toolbar manager. |
| IToolBarManager tbm = getViewSite().getActionBars().getToolBarManager(); |
| if (show) { |
| addDebugToolbarActions(tbm); |
| } else { |
| removeDebugToolbarActions(tbm); |
| } |
| getViewSite().getActionBars().updateActionBars(); |
| |
| // Update system property used by contributed actions. |
| System.setProperty(IDebugUIConstants.DEBUG_VIEW_TOOBAR_VISIBLE, Boolean.toString(show)); |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IWorkbenchPart#dispose() |
| */ |
| @Override |
| public void dispose() { |
| fContextService.removeContextManagerListener(this); |
| getSite().getSelectionProvider().removeSelectionChangedListener(this); |
| DebugUITools.getDebugContextManager().getContextService(getSite().getWorkbenchWindow()).removeDebugContextProvider(fContextProviderProxy); |
| fContextProviderProxy.dispose(); |
| fTreeViewerDebugContextProvider.dispose(); |
| disposeActions(); |
| Viewer viewer = getViewer(); |
| if (viewer != null) { |
| viewer.removeSelectionChangedListener(fTreeViewerSelectionChangedListener); |
| ((TreeModelViewer)viewer).removeViewerUpdateListener(this); |
| ((TreeModelViewer)viewer).removeModelChangedListener(this); |
| } |
| if (fPresentationContext != null) { |
| fPresentationContext.dispose(); |
| } |
| IWorkbenchPage page = getSite().getPage(); |
| page.removePartListener((IPartListener2) this); |
| IWorkbenchWindow window = getSite().getWorkbenchWindow(); |
| window.removePerspectiveListener(this); |
| window.removePageListener(this); |
| for (IHandler2 handler : fHandlers.values()) { |
| handler.dispose(); |
| } |
| fHandlers.clear(); |
| if (fBreadcrumbPage != null) { |
| fBreadcrumbPage.dispose(); |
| fBreadcrumbPage = null; |
| } |
| super.dispose(); |
| } |
| |
| private void disposeActions() { |
| PropertyDialogAction properties = (PropertyDialogAction) getAction("Properties"); //$NON-NLS-1$ |
| properties.dispose(); |
| |
| disposeCommandAction(TERMINATE); |
| disposeCommandAction(DISCONNECT); |
| disposeCommandAction(SUSPEND); |
| disposeCommandAction(RESUME); |
| disposeCommandAction(STEP_RETURN); |
| disposeCommandAction(STEP_OVER); |
| disposeCommandAction(STEP_INTO); |
| disposeCommandAction(DROP_TO_FRAME); |
| disposeCommandAction(TERMINATE_AND_REMOVE); |
| disposeCommandAction(TERMINATE_AND_RELAUNCH); |
| disposeCommandAction(RESTART); |
| disposeCommandAction(TERMINATE_ALL); |
| disposeCommandAction(TOGGLE_STEP_FILTERS); |
| } |
| |
| /** |
| * The selection has changed in the viewer. Show the |
| * associated source code if it is a stack frame. |
| * |
| * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent) |
| */ |
| @Override |
| public void selectionChanged(SelectionChangedEvent event) { |
| updateObjects(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent) |
| */ |
| @Override |
| public void doubleClick(DoubleClickEvent event) { |
| ISelection selection= event.getSelection(); |
| if (!(selection instanceof IStructuredSelection)) { |
| return; |
| } |
| IStructuredSelection ss= (IStructuredSelection)selection; |
| Object o= ss.getFirstElement(); |
| if (o == null || o instanceof IStackFrame) { |
| return; |
| } |
| StructuredViewer viewer = (StructuredViewer) getViewer(); |
| viewer.refresh(o); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPerspectiveListener#perspectiveActivated(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor) |
| */ |
| @Override |
| public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) { |
| setActive(page.findView(getSite().getId()) != null); |
| updateObjects(); |
| setDebugToolbarInView( isDebugToolbarShownInPerspective(getSite().getPage().getPerspective()) ); |
| updateCheckedDebugToolBarAction(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPerspectiveListener#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, java.lang.String) |
| */ |
| @Override |
| public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId) { |
| setActive(page.findView(getSite().getId()) != null); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPerspectiveListener2#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, org.eclipse.ui.IWorkbenchPartReference, java.lang.String) |
| */ |
| @Override |
| public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, IWorkbenchPartReference partRef, String changeId) { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPageListener#pageActivated(org.eclipse.ui.IWorkbenchPage) |
| */ |
| @Override |
| public void pageActivated(IWorkbenchPage page) { |
| if (getSite().getPage().equals(page)) { |
| setActive(true); |
| updateObjects(); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPageListener#pageClosed(org.eclipse.ui.IWorkbenchPage) |
| */ |
| @Override |
| public void pageClosed(IWorkbenchPage page) { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPageListener#pageOpened(org.eclipse.ui.IWorkbenchPage) |
| */ |
| @Override |
| public void pageOpened(IWorkbenchPage page) { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.IDebugView#getPresentation(java.lang.String) |
| */ |
| @Override |
| public IDebugModelPresentation getPresentation(String id) { |
| return ((DelegatingModelPresentation)fPresentation).getPresentation(id); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.AbstractDebugView#fillContextMenu(org.eclipse.jface.action.IMenuManager) |
| */ |
| @Override |
| protected void fillContextMenu(IMenuManager menu) { |
| TreeSelection sel = (TreeSelection) fTreeViewerDebugContextProvider.getActiveContext(); |
| Object element = sel != null && sel.size() > 0 ? sel.getFirstElement() : null; |
| |
| menu.add(new Separator(IDebugUIConstants.EMPTY_EDIT_GROUP)); |
| menu.add(new Separator(IDebugUIConstants.EDIT_GROUP)); |
| menu.add(getAction(FIND_ACTION)); |
| menu.add(new Separator(IDebugUIConstants.EMPTY_STEP_GROUP)); |
| menu.add(new Separator(IDebugUIConstants.STEP_GROUP)); |
| menu.add(new GroupMarker(IDebugUIConstants.STEP_INTO_GROUP)); |
| menu.add(new GroupMarker(IDebugUIConstants.STEP_OVER_GROUP)); |
| menu.add(new GroupMarker(IDebugUIConstants.STEP_RETURN_GROUP)); |
| menu.add(new Separator(IDebugUIConstants.RENDER_GROUP)); |
| menu.add(new Separator(IDebugUIConstants.EMPTY_THREAD_GROUP)); |
| menu.add(new Separator(IDebugUIConstants.THREAD_GROUP)); |
| menu.add(new Separator(IDebugUIConstants.EMPTY_LAUNCH_GROUP)); |
| menu.add(new Separator(IDebugUIConstants.LAUNCH_GROUP)); |
| IStructuredSelection selection = (IStructuredSelection) getSite().getSelectionProvider().getSelection(); |
| updateAndAdd(menu, fEditConfigAction, selection); |
| updateAndAdd(menu, fAddToFavoritesAction, selection); |
| updateAndAdd(menu, fEditSourceAction, selection); |
| updateAndAdd(menu, fLookupAction, selection); |
| menu.add(new Separator(IDebugUIConstants.EMPTY_RENDER_GROUP)); |
| menu.add(new Separator(IDebugUIConstants.RENDER_GROUP)); |
| menu.add(new Separator(IDebugUIConstants.PROPERTY_GROUP)); |
| PropertyDialogAction action = (PropertyDialogAction)getAction("Properties"); //$NON-NLS-1$ |
| /** |
| * TODO hack to get around bug 148424, remove if UI ever fixes the PropertyDialogAction to respect enablesWhen conditions |
| */ |
| action.setEnabled(action.isApplicableForSelection() && !(element instanceof ILaunch)); |
| menu.add(action); |
| menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); |
| |
| menu.appendToGroup(IDebugUIConstants.LAUNCH_GROUP, getAction(TERMINATE_AND_REMOVE)); |
| menu.appendToGroup(IDebugUIConstants.LAUNCH_GROUP, getAction(TERMINATE_ALL)); |
| |
| menu.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(RESUME)); |
| menu.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(SUSPEND)); |
| menu.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(TERMINATE)); |
| menu.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(TERMINATE_AND_RELAUNCH)); |
| if (element instanceof IAdaptable && ((IAdaptable)element).getAdapter(IRestartHandler.class) != null) { |
| menu.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(RESTART)); |
| } |
| menu.appendToGroup(IDebugUIConstants.THREAD_GROUP, getAction(DISCONNECT)); |
| |
| menu.appendToGroup(IDebugUIConstants.STEP_INTO_GROUP, getAction(STEP_INTO)); |
| menu.appendToGroup(IDebugUIConstants.STEP_OVER_GROUP, getAction(STEP_OVER)); |
| menu.appendToGroup(IDebugUIConstants.STEP_RETURN_GROUP, getAction(STEP_RETURN)); |
| |
| menu.appendToGroup(IDebugUIConstants.EMPTY_STEP_GROUP, getAction(DROP_TO_FRAME)); |
| |
| menu.appendToGroup(IDebugUIConstants.RENDER_GROUP, getAction(TOGGLE_STEP_FILTERS)); |
| } |
| |
| @Override |
| public void contextManagerChanged(ContextManagerEvent event) { |
| if (event.isActiveContextsChanged()) { |
| Set<?> oldContexts = event.getPreviouslyActiveContextIds(); |
| Set<?> newContexts = event.getContextManager().getActiveContextIds(); |
| if (oldContexts.contains(IDebugUIConstants.DEBUG_TOOLBAR_ACTION_SET) != |
| newContexts.contains(IDebugUIConstants.DEBUG_TOOLBAR_ACTION_SET)) |
| { |
| updateCheckedDebugToolBarAction(); |
| } |
| } |
| } |
| |
| private void updateCheckedDebugToolBarAction() { |
| fDebugToolBarAction.setChecked(isDebugToolbarInView()); |
| } |
| |
| /** |
| * Updates the enabled state of the given action based on the selection |
| * and adds to the menu if enabled. |
| * |
| * @param menu menu to add the action to |
| * @param action action to add if enabled |
| * @param selection selection to update enabled state for |
| */ |
| private void updateAndAdd(IMenuManager menu, SelectionListenerAction action, IStructuredSelection selection) { |
| action.selectionChanged(selection); |
| if (action.isEnabled()) { |
| menu.add(action); |
| } |
| } |
| |
| /** |
| * Sets whether this view is in the active page of a |
| * perspective. Since a page can have more than one |
| * perspective, this view only show's source when in |
| * the active perspective/page. |
| * |
| * @param active whether this view is in the active page of a |
| * perspective |
| */ |
| protected void setActive(boolean active) { |
| fIsActive = active; |
| } |
| |
| /** |
| * Returns whether this view is in the active page of |
| * the active perspective and has been fully created. |
| * |
| * @return whether this view is in the active page of |
| * the active perspective and has been fully created. |
| */ |
| protected boolean isActive() { |
| return fIsActive && getViewer() != null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.part.IShowInTarget#show(org.eclipse.ui.part.ShowInContext) |
| */ |
| @Override |
| public boolean show(ShowInContext context) { |
| ISelection selection = context.getSelection(); |
| if (selection != null) { |
| if (selection instanceof IStructuredSelection) { |
| IStructuredSelection ss = (IStructuredSelection)selection; |
| if (ss.size() == 1) { |
| Object obj = ss.getFirstElement(); |
| if (obj instanceof IDebugTarget || obj instanceof IProcess) { |
| Viewer viewer = getViewer(); |
| if (viewer instanceof InternalTreeModelViewer) { |
| InternalTreeModelViewer tv = (InternalTreeModelViewer) viewer; |
| tv.setSelection(selection, true, true); |
| } else { |
| viewer.setSelection(selection, true); |
| } |
| return true; |
| } |
| } |
| } |
| } |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.part.IShowInSource#getShowInContext() |
| */ |
| @Override |
| public ShowInContext getShowInContext() { |
| if (isActive()) { |
| IStructuredSelection selection = (IStructuredSelection)getViewer().getSelection(); |
| if (selection.size() == 1) { |
| Object object = selection.getFirstElement(); |
| if (object instanceof IAdaptable) { |
| IAdaptable adaptable = (IAdaptable) object; |
| IShowInSource show = adaptable.getAdapter(IShowInSource.class); |
| if (show != null) { |
| return show.getShowInContext(); |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.part.IShowInTargetList#getShowInTargetIds() |
| */ |
| @Override |
| public String[] getShowInTargetIds() { |
| if (isActive()) { |
| IStructuredSelection selection = (IStructuredSelection)getViewer().getSelection(); |
| if (selection.size() == 1) { |
| Object object = selection.getFirstElement(); |
| if (object instanceof IAdaptable) { |
| IAdaptable adaptable = (IAdaptable) object; |
| IShowInTargetList show = adaptable.getAdapter(IShowInTargetList.class); |
| if (show != null) { |
| return show.getShowInTargetIds(); |
| } |
| } |
| } |
| } |
| return new String[0]; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partClosed(IWorkbenchPartReference partRef) { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partVisible(IWorkbenchPartReference partRef) { |
| IWorkbenchPart part = partRef.getPart(false); |
| if (part == this) { |
| setActive(true); |
| // TODO: Workaround for Bug #63332. Reexamine after M9. |
| // updateContextListener(); |
| // When the launch view becomes visible, turn on the |
| // debug action set. Note that the workbench will handle the |
| // case where the user really doesn't want the action set |
| // enabled - showActionSet(String) will do nothing for an |
| // action set that's been manually disabled. |
| getSite().getPage().showActionSet(IDebugUIConstants.DEBUG_ACTION_SET); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPartListener2#partOpened(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partOpened(IWorkbenchPartReference partRef) { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPartListener2#partActivated(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partActivated(IWorkbenchPartReference partRef) { |
| // Ensure that the system property matches the debug toolbar state. |
| // Bug 385400 |
| System.setProperty(IDebugUIConstants.DEBUG_VIEW_TOOBAR_VISIBLE, |
| Boolean.toString(isDebugToolbarShownInPerspective(getSite().getPage().getPerspective())) ); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPartListener2#partBroughtToTop(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partBroughtToTop(IWorkbenchPartReference partRef) { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPartListener2#partDeactivated(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partDeactivated(IWorkbenchPartReference partRef) { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPartListener2#partHidden(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partHidden(IWorkbenchPartReference partRef) { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPartListener2#partInputChanged(org.eclipse.ui.IWorkbenchPartReference) |
| */ |
| @Override |
| public void partInputChanged(IWorkbenchPartReference partRef) { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.ui.AbstractDebugView#becomesVisible() |
| */ |
| @Override |
| protected void becomesVisible() { |
| super.becomesVisible(); |
| getViewer().refresh(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IViewerUpdateListener#updateComplete(org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor) |
| */ |
| @Override |
| public void updateComplete(IViewerUpdate update) { |
| if (!update.isCanceled()) { |
| if (TreePath.EMPTY.equals(update.getElementPath())) { |
| updateFindAction(); |
| } |
| } |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IViewerUpdateListener#updateStarted(org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor) |
| */ |
| @Override |
| public void updateStarted(IViewerUpdate update) { |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IViewerUpdateListener#viewerUpdatesBegin() |
| */ |
| @Override |
| public synchronized void viewerUpdatesBegin() { |
| IWorkbenchSiteProgressService progressService = |
| getSite().getAdapter(IWorkbenchSiteProgressService.class); |
| if (progressService != null) { |
| progressService.incrementBusy(); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IViewerUpdateListener#viewerUpdatesComplete() |
| */ |
| @Override |
| public synchronized void viewerUpdatesComplete() { |
| IWorkbenchSiteProgressService progressService = |
| getSite().getAdapter(IWorkbenchSiteProgressService.class); |
| if (progressService != null) { |
| progressService.decrementBusy(); |
| } |
| } |
| |
| @Override |
| public void modelChanged(IModelDelta delta, IModelProxy proxy) { |
| updateFindAction(); |
| } |
| |
| private void updateFindAction() { |
| IAction action= getAction(FIND_ACTION); |
| if (action instanceof IUpdate) { |
| ((IUpdate) action).update(); |
| } |
| } |
| |
| /** |
| * Returns whether the breadcrumb viewer is currently visible in the view. |
| * |
| * @since 3.5 |
| */ |
| boolean isBreadcrumbVisible() { |
| return fBreadcrumbPage.equals(getCurrentPage()); |
| } |
| |
| /** |
| * Returns whether the elements in breadcrumb's drop-down viewer should be |
| * automatically expanded. |
| * |
| * @since 3.5 |
| */ |
| boolean getBreadcrumbDropDownAutoExpand() { |
| return fBreadcrumbDropDownAutoExpand; |
| } |
| |
| /** |
| * Sets whether the elements in breadcrumb's drop-down viewer should be |
| * automatically expanded. |
| * |
| * @since 3.5 |
| */ |
| void setBreadcrumbDropDownAutoExpand(boolean expand) { |
| fBreadcrumbDropDownAutoExpand = expand; |
| } |
| |
| } |