| /******************************************************************************* |
| * Copyright (c) 2003, 2005 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 |
| *******************************************************************************/ |
| package org.eclipse.ui.navigator; |
| |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.jface.viewers.DoubleClickEvent; |
| import org.eclipse.jface.viewers.IDoubleClickListener; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.ViewerFilter; |
| import org.eclipse.jface.viewers.ViewerSorter; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.DisposeEvent; |
| import org.eclipse.swt.events.DisposeListener; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.IViewSite; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.actions.ActionGroup; |
| import org.eclipse.ui.navigator.internal.CommonNavigatorActionGroup; |
| import org.eclipse.ui.navigator.internal.CommonSorter; |
| import org.eclipse.ui.navigator.internal.NavigatorContentService; |
| import org.eclipse.ui.navigator.internal.actions.CollapseAllAction; |
| import org.eclipse.ui.navigator.internal.actions.LinkEditorAction; |
| import org.eclipse.ui.navigator.internal.filters.CommonViewerFilter; |
| import org.eclipse.ui.navigator.internal.filters.ExtensionFilterRegistryManager; |
| import org.eclipse.ui.navigator.internal.filters.SelectFiltersAction; |
| import org.eclipse.ui.part.ISetSelectionTarget; |
| import org.eclipse.ui.part.ViewPart; |
| |
| /** |
| * <p> |
| * This class provides the IViewPart for the Common Navigator |
| * framework in the Eclipse workbench. This class also serves |
| * as the backbone for navigational viewers. The following types |
| * are used by this class to render the Common Navigator: |
| * <ul> |
| * <li> |
| * <p> |
| * {@link org.eclipse.ui.navigator.CommonViewer}: The viewer |
| * that renders the extensible tree. Creates and manages the |
| * lifecylce of the Navigator Content Service (described below). |
| * </p> |
| * </li> |
| * <li> |
| * <p> |
| * {@link org.eclipse.ui.navigator.CommonNavigatorManager}: |
| * Handles auxillary functions, such as updating the status bar, |
| * populating popup menus, and managing the Navigator Action |
| * Service (described below). Not expected to be needed by clients. |
| * </p> |
| * </li> |
| * <li> |
| * <p> |
| * {@link org.eclipse.ui.navigator.NavigatorActionService}: |
| * Manages instances of {@link org.eclipse.ui.navigator.CommonActionProvider}s |
| * provided by individual extensions and content extensions. |
| * </p> |
| * </li> |
| * <li> |
| * <p> |
| * {@link org.eclipse.ui.navigator.INavigatorContentService}: |
| * Manages instances of Navigator Content Extensions. Instances are |
| * created as needed, and disposed of upon the disposal of the |
| * Navigator Content Service. |
| * </p> |
| * </li> |
| * </ul> |
| * <p> |
| * Clients are not expected to subclass CommonNavigator. Clients |
| * that wish to define their own custom extensible navigator |
| * view need to specify an instance of the <b>org.eclipse.ui.views</b> |
| * extension point: |
| * |
| * <pre> |
| * <extension |
| * point="org.eclipse.ui.views"> |
| * <view |
| * name="My Custom View" |
| * icon="relative/path/to/icon.gif" |
| * category="org.acme.mycategory" |
| * class="org.eclipse.ui.navigator.CommonNavigator" |
| * id="org.acme.MyCustomNavigatorID"> |
| * </view> |
| * </extension> |
| * |
| * </pre> |
| * |
| * </p> |
| * <p> |
| * In the event that a consumer of the Common Navigator does need to change the actual behavior, |
| * methods are provided to override specific pieces of functionality. Each of these methods begin |
| * with <i>create </i> and explain what modular component they are responsible for creating. Each of |
| * these pieces may take the instance of the Common Viewer ( |
| * {@link org.eclipse.ui.navigator.CommonViewer}) and have depedencies to that object, |
| * but the instance of the Common Viewer should never assume more than the standard Eclipse |
| * interfaces when working with these components. |
| * </p> |
| * <p> |
| * Clients that wish to extend the view menu provided via the <b>org.eclipse.ui.popupMenu</b>s extension |
| * may specify the the popupMenuId specified by <b>org.eclipse.ui.navigator.viewer</b> of their |
| * target viewer as their target menu id. |
| * |
| * <p> |
| * This class may be instantiated; it is not intended to be subclassed. |
| * </p> |
| * |
| * <p> |
| * <strong>EXPERIMENTAL</strong>. This class or interface has been added as |
| * part of a work in progress. There is a guarantee neither that this API will |
| * work nor that it will remain the same. Please do not use this API without |
| * consulting with the Platform/UI team. |
| * </p> |
| * @since 3.2 |
| */ |
| public class CommonNavigator extends ViewPart implements ISetSelectionTarget { |
| |
| /** |
| * <p> |
| * Used to track changes to the {@link #isLinkingEnabled} property. |
| * </p> |
| */ |
| public static final int IS_LINKING_ENABLED_PROPERTY = 1; |
| |
| private CommonViewer commonViewer; |
| private CommonNavigatorManager commonManager; |
| private ActionGroup commonActionGroup; |
| |
| private IMemento memento; |
| private boolean isLinkingEnabled = false; |
| private String LINKING_ENABLED = "CommonNavigator.LINKING_ENABLED"; //$NON-NLS-1$ |
| |
| /** |
| * |
| */ |
| public CommonNavigator() { |
| super(); |
| } |
| |
| /** |
| * <p> |
| * Create the CommonViewer part control and setup the default providers as necessary. |
| * </p> |
| * |
| * |
| * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) |
| */ |
| public void createPartControl(Composite aParent) { |
| |
| commonViewer = createCommonViewer(aParent); |
| commonViewer.addFilter(createCommonFilter(commonViewer)); |
| commonViewer.setSorter(createCommonSorter(commonViewer)); |
| |
| |
| /* make sure input is set after sorters and filters to avoid unnecessary refreshes */ |
| commonViewer.setInput(getInitialInput()); |
| commonViewer.getControl().addDisposeListener(createDisposeListener()); |
| |
| getSite().setSelectionProvider(commonViewer); |
| |
| |
| updateTitle(); |
| |
| /* |
| * Create the CommonNavigatorManager last because information about the state of the |
| * CommonNavigator is required for the initialization of the CommonNavigatorManager |
| */ |
| commonManager = createCommonManager(); |
| if (memento != null) { |
| commonManager.restoreState(memento); |
| commonViewer.getNavigatorContentService().restoreState(memento); |
| } |
| |
| commonActionGroup = createCommonActionGroup(); |
| commonActionGroup.fillActionBars(getViewSite().getActionBars()); |
| |
| } |
| |
| /** |
| * <p> |
| * Note: This method is for internal use only. Clients should not call this method. |
| * </p> |
| * <p> |
| * This method will be invoked when the DisposeListener is notified of the disposal of the |
| * Eclipse view part. |
| * </p> |
| * |
| * @see org.eclipse.ui.part.WorkbenchPart#dispose() |
| */ |
| public void dispose() { |
| if (commonManager != null) |
| commonManager.dispose(); |
| super.dispose(); |
| } |
| |
| /** |
| * <p> |
| * Note: This method is for internal use only. Clients should not call this method. |
| * </p> |
| * |
| * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento) |
| */ |
| public void init(IViewSite aSite, IMemento aMemento) throws PartInitException { |
| super.init(aSite, aMemento); |
| memento = aMemento; |
| if (memento != null) { |
| Integer linkingEnabledInteger = memento.getInteger(LINKING_ENABLED); |
| setLinkingEnabled(((linkingEnabledInteger != null) ? linkingEnabledInteger.intValue() == 1 : false)); |
| } |
| |
| } |
| |
| /** |
| * |
| * <p> |
| * Note: This method is for internal use only. Clients should not call this method. |
| * </p> |
| * |
| * @see org.eclipse.ui.part.ViewPart#saveState(org.eclipse.ui.IMemento) |
| */ |
| public void saveState(IMemento aMemento) { |
| aMemento.putInteger(LINKING_ENABLED, (isLinkingEnabled) ? 1 : 0); |
| super.saveState(aMemento); |
| commonManager.saveState(aMemento); |
| commonViewer.getNavigatorContentService().saveState(aMemento); |
| } |
| |
| /** |
| * <p> |
| * Force the workbench to focus on the Common Navigator tree. |
| * </p> |
| * |
| * @see org.eclipse.ui.part.WorkbenchPart#setFocus() |
| */ |
| public void setFocus() { |
| if (commonViewer != null) |
| commonViewer.getTree().setFocus(); |
| } |
| |
| /** |
| * <p> |
| * Set the selection to the Common Navigator tree, and expand nodes if necessary. Use caution |
| * when invoking this method as it can cause Navigator Content Extensions to load, thus causing |
| * plugin activation. |
| * </p> |
| * |
| * @see org.eclipse.ui.part.ISetSelectionTarget#selectReveal(org.eclipse.jface.viewers.ISelection) |
| */ |
| public void selectReveal(ISelection selection) { |
| if (commonViewer != null) |
| commonViewer.setSelection(selection, true); |
| } |
| |
| /** |
| * <p> |
| * Linking is handled by |
| * {@link LinkEditorAction}, which |
| * listens for changes to the {@link CommonNavigator#IS_LINKING_ENABLED_PROPERTY}. Custom |
| * implementations that wish to override this functionality, need to override the action used by |
| * CommonNavigatorActionGroup and listen for changes to the above property. |
| * |
| * @param toEnableLinking |
| * True enables linking the current selection with open editors |
| */ |
| public final void setLinkingEnabled(boolean toEnableLinking) { |
| isLinkingEnabled = toEnableLinking; |
| firePropertyChange(IS_LINKING_ENABLED_PROPERTY); |
| } |
| |
| /** |
| * @return Whether linking the current selection with open editors is enabled. |
| */ |
| public final boolean isLinkingEnabled() { |
| return isLinkingEnabled; |
| } |
| |
| /** |
| * <p> |
| * Provides access to the commonViewer used by the current CommonNavigator. The field will not |
| * be valid until after {@link #init(IViewSite, IMemento)} has been called by the Workbench. |
| * </p> |
| * |
| * @see CommonNavigator#createCommonViewer(Composite) |
| * @return The (already created) instance of Common Viewer. |
| */ |
| public CommonViewer getCommonViewer() { |
| return commonViewer; |
| } |
| |
| /** |
| * @return The Navigator Content Service which populates this instance of Common Navigator |
| */ |
| public INavigatorContentService getNavigatorContentService() { |
| return getCommonViewer().getNavigatorContentService(); |
| } |
| |
| public Object getAdapter(Class adapter) { |
| if(adapter == CommonViewer.class) |
| return getCommonViewer(); |
| else if(adapter == NavigatorContentService.class) |
| return getCommonViewer().getNavigatorContentService(); |
| return super.getAdapter(adapter); |
| } |
| |
| |
| /** |
| * @return The Navigator Content Service which populates this instance of Common Navigator |
| */ |
| public NavigatorActionService getNavigatorActionService() { |
| return commonManager.getNavigatorActionService(); |
| } |
| |
| /** |
| * <p> |
| * Constructs and returns an instance of {@link CommonViewer}. The ID of the Eclipse view part |
| * will be used to create the viewer. The ID is important as some extensions indicate they |
| * should only be used with a particular viewer ID. |
| * <p> |
| * |
| * @param aParent |
| * A composite parent to contain the Common Viewer |
| * @return An initialized instance of CommonViewer |
| */ |
| protected CommonViewer createCommonViewer(Composite aParent) { |
| CommonViewer aViewer = new CommonViewer(getViewSite().getId(), aParent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); |
| initListeners(aViewer); |
| aViewer.getNavigatorContentService().restoreState(memento); |
| return aViewer; |
| } |
| |
| /** |
| * <p> |
| * Adds the listeners to the Common Viewer. |
| * </p> |
| * |
| * @param viewer |
| * The viewer |
| * @since 2.0 |
| */ |
| protected void initListeners(TreeViewer viewer) { |
| |
| viewer.addDoubleClickListener(new IDoubleClickListener() { |
| |
| public void doubleClick(DoubleClickEvent event) { |
| try { |
| handleDoubleClick(event); |
| } catch(RuntimeException re) { |
| re.printStackTrace(); |
| } |
| } |
| }); |
| } |
| |
| /** |
| * <p> |
| * Note: This method is for internal use only. Clients should not call this method. |
| * </p> |
| * |
| * @param anEvent |
| * Supplied by the DoubleClick listener. |
| */ |
| protected void handleDoubleClick(DoubleClickEvent anEvent) { |
| |
| IStructuredSelection selection = (IStructuredSelection) anEvent.getSelection(); |
| Object element = selection.getFirstElement(); |
| |
| TreeViewer viewer = getCommonViewer(); |
| if (viewer.isExpandable(element)) { |
| viewer.setExpandedState(element, !viewer.getExpandedState(element)); |
| } |
| } |
| |
| /** |
| * <p> |
| * The Common Navigator Manager handles the setup of the Common Navigator Menu, manages updates |
| * to the ActionBars from |
| * {@link ICommonActionProvider} |
| * extensions as the user's selection changes, and also updates the status bar based on the |
| * current selection. |
| * |
| * @return The Common Navigator Manager class which handles menu population and ActionBars |
| */ |
| protected CommonNavigatorManager createCommonManager() { |
| return new CommonNavigatorManager(this); |
| } |
| |
| /** |
| * <p> |
| * The ActionGroup is used to populate the ActionBars of Common Navigator View Part, and the |
| * returned implementation will have an opportunity to fill the ActionBars of the view as soon |
| * as it is created. ({@link ActionGroup#fillActionBars(org.eclipse.ui.IActionBars)}. |
| * </p> |
| * <p> |
| * The default implementation returns an instance of {@link CommonNavigatorActionGroup} which |
| * will add the following actions: |
| * <ul> |
| * <li> |
| * <p> |
| * Link with editor support ( |
| * {@link LinkEditorAction}). Allows the |
| * user to toggling linking the current selection with the active editors. |
| * </p> |
| * <li> |
| * <p> |
| * Collapse all ( |
| * {@link CollapseAllAction}). Collapses |
| * all expanded nodes. |
| * </p> |
| * <li> |
| * <p> |
| * Select Filters ( |
| * {@link SelectFiltersAction}). |
| * Provides access to the "Select Filters" dialog that allows users to enable/disable filters |
| * and also the Content Extension activations. |
| * </p> |
| * </ul> |
| * |
| * @return The Action Group to be associated with the Common Navigator View Part. |
| */ |
| protected ActionGroup createCommonActionGroup() { |
| return new CommonNavigatorActionGroup(this, commonViewer); |
| } |
| |
| /** |
| * <p> |
| * The default implementation hooks into the extensible navigator's framework for extensions to |
| * provide filters. Custom implementations will probably require some changes to |
| * {@link SelectFiltersAction} as |
| * well. |
| * </p> |
| * |
| * @see CommonViewerFilter |
| * @see ExtensionFilterRegistryManager |
| * @return The ViewerFilter to provide the desired extensibility for Filters |
| */ |
| protected ViewerFilter createCommonFilter(CommonViewer aViewer) { |
| return new CommonViewerFilter(aViewer); |
| } |
| |
| |
| |
| /** |
| * <p> |
| * The following method creates a basic sorter for the M3 release. This functionality will |
| * change substantially for the M4 release. |
| * </p> |
| * |
| * @return The ViewerSorter to sort the contents of the Common Viewer |
| */ |
| protected ViewerSorter createCommonSorter(CommonViewer aViewer) { |
| return new CommonSorter(aViewer.getNavigatorContentService()); |
| } |
| |
| /** |
| * @return A listener to track the disposal of the Eclipse view part in order to dispose of the |
| * framework state. |
| */ |
| protected DisposeListener createDisposeListener() { |
| return new DisposeListener() { |
| /** |
| * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) |
| */ |
| public void widgetDisposed(DisposeEvent e) { |
| dispose(); |
| } |
| }; |
| } |
| |
| /** |
| * @return The initial input for the viewer. Defaults to getSite().getPage().getInput() |
| */ |
| protected IAdaptable getInitialInput() { |
| return getSite().getPage().getInput(); |
| } |
| |
| |
| /** |
| * <p> |
| * Updates the title text and title tool tip. Called whenever the input of the viewer changes. |
| * </p> |
| */ |
| protected void updateTitle() { |
| |
| if (commonViewer == null) |
| return; |
| |
| Object input = commonViewer.getInput(); |
| String viewName = getConfigurationElement().getAttribute("name"); //$NON-NLS-1$ |
| // IWorkingSet workingSet = workingSetFilter.getWorkingSet(); |
| |
| if (input == null) { |
| setPartName(viewName); |
| setTitleToolTip(""); //$NON-NLS-1$ |
| } else { |
| String inputToolTip = getFrameToolTipText(input); |
| |
| setPartName(viewName); |
| setTitleToolTip(inputToolTip); |
| } |
| } |
| |
| /** |
| * <p> |
| * Returns the tool tip text for the given element. Used as the tool tip text for the current |
| * frame, and for the view title tooltip. |
| * </p> |
| */ |
| protected String getFrameToolTipText(Object anElement) { |
| if (commonViewer != null) |
| return ((ILabelProvider) commonViewer.getLabelProvider()).getText(anElement); |
| return ""; //$NON-NLS-1$ |
| } |
| |
| } |