Java tutorial
/* * Copyright (c) 2013-2014, Neuro4j.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.neuro4j.studio.debug.ui.views; 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 org.eclipse.core.commands.IHandler2; 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.viewers.model.InternalTreeModelViewer; 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.views.launch.LaunchViewMessages; 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.GroupMarker; 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.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.part.PageBookView.PageRec; //import org.eclipse.debug.internal.ui.views.launch.DebugViewModeAction; public class FlowLaunchView extends AbstractDebugView implements ISelectionChangedListener, IPerspectiveListener2, IPageListener, IShowInTarget, IShowInSource, IShowInTargetList, IPartListener2, IViewerUpdateListener { 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_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; @Override public void showViewer() { // TODO Auto-generated method stub super.showViewer(); } /** * 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 that controls the breadcrumb drop-down auto-expand behavior. * * @since 3.5 */ private BreadcrumbDropDownAutoExpandAction fBreadcrumbDropDownAutoExpandAction; /** * 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 fHandlers = new HashMap(); /** * 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; public void createControl(Composite parent) { fCrumb = new LaunchViewBreadcrumb(FlowLaunchView.this, (TreeModelViewer) getViewer(), fTreeViewerDebugContextProvider); fControl = fCrumb.createContent(parent); } public void init(IPageSite pageSite) { super.init(pageSite); pageSite.setSelectionProvider(fCrumb.getSelectionProvider()); } public Control getControl() { return fControl; } public void setFocus() { fCrumb.activate(); } IDebugContextProvider getContextProvider() { return fCrumb.getContextProvider(); } int getHeight() { return fCrumb.getHeight(); } } 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 { 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 list = new ArrayList(); 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(FlowLaunchView.this); this.fViewer = viewer; fViewer.addModelChangedListener(this); } protected void dispose() { fContext = null; fViewer.removeModelChangedListener(this); } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.contexts.IDebugContextProvider#getActiveContext() */ public synchronized ISelection getActiveContext() { return fContext; } protected void activate(ISelection selection) { synchronized (this) { fContext = selection; } fire(new DebugContextEventAdapter(this, selection, DebugContextEvent.ACTIVATED)); } protected void possibleChange(TreePath element, int type) { DebugContextEvent event = null; synchronized (this) { if (fContext instanceof ITreeSelection) { ITreeSelection ss = (ITreeSelection) fContext; if (ss.size() == 1) { TreePath current = ss.getPaths()[0]; if (current.startsWith(element, null)) { if (current.getSegmentCount() == element.getSegmentCount()) { event = new DebugContextEventAdapter(this, fContext, type); } else { // if parent of the currently selected element // changes, issue event to update STATE only event = new DebugContextEventAdapter(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$ 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) */ 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() { 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(FlowLaunchView.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 DebugContextEventAdapter(this, getActiveContext(), DebugContextEvent.ACTIVATED)); } } } public ISelection getActiveContext() { ISelection activeContext = fActiveProvider.getActiveContext(); if (activeContext != null) { return activeContext; } return TreeSelection.EMPTY; } public void debugContextChanged(DebugContextEvent event) { if (event.getSource().equals(fActiveProvider)) { fire(new DebugContextEventAdapter(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() */ protected String getHelpContextId() { return IDebugHelpContextIds.DEBUG_VIEW; } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.AbstractDebugView#createActions() */ 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 (IHandler2) 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 */ 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)); } // Add a resize listener for the view to activate breadcrumb as needed. parent.addControlListener(new ControlListener() { public void controlMoved(ControlEvent e) { } public void controlResized(ControlEvent e) { if (parent.isDisposed()) { return; } if (IDebugPreferenceConstants.DEBUG_VIEW_MODE_AUTO.equals(fCurrentViewMode)) { autoSelectViewPage(parent); } } }); } /** * 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 */ 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 */ 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 */ 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); viewMenu.add(new Separator()); modeSubmenu.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { modeSubmenu.add(fDebugViewModeActions[0]); modeSubmenu.add(fDebugViewModeActions[1]); modeSubmenu.add(fDebugViewModeActions[2]); modeSubmenu.add(new Separator()); modeSubmenu.add(fBreadcrumbDropDownAutoExpandAction); } }); } /** * 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(); 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 DebugContextEventAdapter(fTreeViewerDebugContextProvider, fTreeViewerDebugContextProvider.getActiveContext(), DebugContextEvent.ACTIVATED)); fContextProviderProxy.setActiveProvider(fBreadcrumbPage.getContextProvider()); } } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.AbstractDebugView#createViewer(org.eclipse.swt.widgets.Composite) */ protected Viewer createViewer(Composite parent) { fPresentation = new DelegatingModelPresentation(); // fPresentationContext = new DebugModelPresentationContext(IDebugUIConstants.ID_DEBUG_VIEW, this, // fPresentation); //"org.neuro4j.studio.debug.ui.debugging" 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.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) { ByteArrayInputStream bin = new ByteArrayInputStream(string.getBytes()); InputStreamReader reader = new InputStreamReader(bin); try { XMLMemento stateMemento = XMLMemento.createReadRoot(reader); setMemento(stateMemento); } catch (WorkbenchException e) { } finally { try { reader.close(); bin.close(); } catch (IOException e) { } } } IMemento mem = getMemento(); if (mem != null) { Boolean auto = mem.getBoolean(BREADCRUMB_DROPDOWN_AUTO_EXPAND); if (auto != null) { setBreadcrumbDropDownAutoExpand(auto.booleanValue()); } } } /* * (non-Javadoc) * * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite) */ public void init(IViewSite site) throws PartInitException { super.init(site); commonInit(site); preferenceInit(site); } /* * (non-Javadoc) * * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento) */ public void init(IViewSite site, IMemento memento) throws PartInitException { super.init(site, memento); commonInit(site); preferenceInit(site); } /* * (non-Javadoc) * * @see org.eclipse.ui.part.PageBookView#partDeactivated(org.eclipse.ui.IWorkbenchPart) */ public void partDeactivated(IWorkbenchPart part) { String id = part.getSite().getId(); if (id.equals(getSite().getId())) { ByteArrayOutputStream bout = new ByteArrayOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(bout); try { 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) { } finally { try { writer.close(); bout.close(); } catch (IOException e) { } } } 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) */ 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)); 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)); } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbenchPart#dispose() */ public void dispose() { 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); } if (fPresentationContext != null) { fPresentationContext.dispose(); } IWorkbenchPage page = getSite().getPage(); page.removePartListener((IPartListener2) this); IWorkbenchWindow window = getSite().getWorkbenchWindow(); window.removePerspectiveListener(this); window.removePageListener(this); Iterator iterator = fHandlers.values().iterator(); while (iterator.hasNext()) { IHandler2 hander = (IHandler2) iterator.next(); hander.dispose(); } fHandlers.clear(); 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); } /** * 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) */ public void selectionChanged(SelectionChangedEvent event) { updateObjects(); } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent) */ 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) */ public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) { setActive(page.findView(getSite().getId()) != null); updateObjects(); } /* * (non-Javadoc) * * @see org.eclipse.ui.IPerspectiveListener#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, * org.eclipse.ui.IPerspectiveDescriptor, java.lang.String) */ 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) */ public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, IWorkbenchPartReference partRef, String changeId) { } /* * (non-Javadoc) * * @see org.eclipse.ui.IPageListener#pageActivated(org.eclipse.ui.IWorkbenchPage) */ 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) */ public void pageClosed(IWorkbenchPage page) { } /* * (non-Javadoc) * * @see org.eclipse.ui.IPageListener#pageOpened(org.eclipse.ui.IWorkbenchPage) */ public void pageOpened(IWorkbenchPage page) { } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.IDebugView#getPresentation(java.lang.String) */ public IDebugModelPresentation getPresentation(String id) { return ((DelegatingModelPresentation) fPresentation).getPresentation(id); } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.AbstractDebugView#fillContextMenu(org.eclipse.jface.action.IMenuManager) */ 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)); } /** * 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) */ 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() */ 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 = (IShowInSource) adaptable.getAdapter(IShowInSource.class); if (show != null) { return show.getShowInContext(); } } } } return null; } /* * (non-Javadoc) * * @see org.eclipse.ui.part.IShowInTargetList#getShowInTargetIds() */ 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 = (IShowInTargetList) 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) */ public void partClosed(IWorkbenchPartReference partRef) { } /* * (non-Javadoc) * * @see org.eclipse.ui.IPartListener2#partVisible(org.eclipse.ui.IWorkbenchPartReference) */ 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) */ public void partOpened(IWorkbenchPartReference partRef) { } /* * (non-Javadoc) * * @see org.eclipse.ui.IPartListener2#partActivated(org.eclipse.ui.IWorkbenchPartReference) */ public void partActivated(IWorkbenchPartReference partRef) { } /* * (non-Javadoc) * * @see org.eclipse.ui.IPartListener2#partBroughtToTop(org.eclipse.ui.IWorkbenchPartReference) */ public void partBroughtToTop(IWorkbenchPartReference partRef) { } /* * (non-Javadoc) * * @see org.eclipse.ui.IPartListener2#partDeactivated(org.eclipse.ui.IWorkbenchPartReference) */ public void partDeactivated(IWorkbenchPartReference partRef) { } /* * (non-Javadoc) * * @see org.eclipse.ui.IPartListener2#partHidden(org.eclipse.ui.IWorkbenchPartReference) */ public void partHidden(IWorkbenchPartReference partRef) { } /* * (non-Javadoc) * * @see org.eclipse.ui.IPartListener2#partInputChanged(org.eclipse.ui.IWorkbenchPartReference) */ public void partInputChanged(IWorkbenchPartReference partRef) { } /* * (non-Javadoc) * * @see org.eclipse.debug.ui.AbstractDebugView#becomesVisible() */ 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) */ public void updateComplete(IViewerUpdate update) { } /* * (non-Javadoc) * * @see * org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IViewerUpdateListener#updateStarted(org.eclipse * .debug.internal.ui.viewers.provisional.IAsynchronousRequestMonitor) */ public void updateStarted(IViewerUpdate update) { } /* * (non-Javadoc) * * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IViewerUpdateListener#viewerUpdatesBegin() */ public synchronized void viewerUpdatesBegin() { IWorkbenchSiteProgressService progressService = (IWorkbenchSiteProgressService) getSite() .getAdapter(IWorkbenchSiteProgressService.class); if (progressService != null) { progressService.incrementBusy(); } } /* * (non-Javadoc) * * @see * org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.IViewerUpdateListener#viewerUpdatesComplete() */ public synchronized void viewerUpdatesComplete() { IWorkbenchSiteProgressService progressService = (IWorkbenchSiteProgressService) getSite() .getAdapter(IWorkbenchSiteProgressService.class); if (progressService != null) { progressService.decrementBusy(); } } /** * 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; } }