KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > navigator > CommonNavigator


1 /*******************************************************************************
2  * Copyright (c) 2003, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.navigator;
12
13 import org.eclipse.core.runtime.IAdaptable;
14 import org.eclipse.core.runtime.IProgressMonitor;
15 import org.eclipse.jface.action.IAction;
16 import org.eclipse.jface.viewers.DoubleClickEvent;
17 import org.eclipse.jface.viewers.IDoubleClickListener;
18 import org.eclipse.jface.viewers.ILabelProvider;
19 import org.eclipse.jface.viewers.ISelection;
20 import org.eclipse.jface.viewers.ISelectionChangedListener;
21 import org.eclipse.jface.viewers.IStructuredSelection;
22 import org.eclipse.jface.viewers.SelectionChangedEvent;
23 import org.eclipse.jface.viewers.StructuredSelection;
24 import org.eclipse.jface.viewers.TreeViewer;
25 import org.eclipse.jface.viewers.ViewerFilter;
26 import org.eclipse.swt.SWT;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.ui.IEditorInput;
29 import org.eclipse.ui.IMemento;
30 import org.eclipse.ui.ISaveablePart;
31 import org.eclipse.ui.ISaveablesLifecycleListener;
32 import org.eclipse.ui.ISaveablesSource;
33 import org.eclipse.ui.IViewSite;
34 import org.eclipse.ui.PartInitException;
35 import org.eclipse.ui.PlatformUI;
36 import org.eclipse.ui.Saveable;
37 import org.eclipse.ui.SaveablesLifecycleEvent;
38 import org.eclipse.ui.actions.ActionGroup;
39 import org.eclipse.ui.internal.navigator.CommonNavigatorActionGroup;
40 import org.eclipse.ui.internal.navigator.CommonNavigatorManager;
41 import org.eclipse.ui.internal.navigator.NavigatorContentService;
42 import org.eclipse.ui.internal.navigator.NavigatorPlugin;
43 import org.eclipse.ui.internal.navigator.extensions.LinkHelperService;
44 import org.eclipse.ui.part.ISetSelectionTarget;
45 import org.eclipse.ui.part.IShowInTarget;
46 import org.eclipse.ui.part.ShowInContext;
47 import org.eclipse.ui.part.ViewPart;
48
49 /**
50  * <p>
51  * This class provides the IViewPart for the Common Navigator framework in the
52  * Eclipse workbench. This class also serves as the backbone for navigational
53  * viewers. The following types are used by this class to render the Common
54  * Navigator:
55  * <ul>
56  * <li>
57  * <p>
58  * {@link org.eclipse.ui.navigator.CommonViewer}: The viewer that renders the
59  * extensible tree. Creates and manages the lifecylce of the Navigator Content
60  * Service (described below).
61  * </p>
62  * </li>
63  * <li>
64  * <p>
65  * {@link org.eclipse.ui.navigator.NavigatorActionService}: Manages instances
66  * of {@link org.eclipse.ui.navigator.CommonActionProvider}s provided by
67  * individual extensions and content extensions.
68  * </p>
69  * </li>
70  * <li>
71  * <p>
72  * {@link org.eclipse.ui.navigator.INavigatorContentService}: Manages instances
73  * of Navigator Content Extensions. Instances are created as needed, and
74  * disposed of upon the disposal of the Navigator Content Service.
75  * </p>
76  * </li>
77  * </ul>
78  * <p>
79  * Clients are not expected to subclass CommonNavigator. Clients that wish to
80  * define their own custom extensible navigator view need to specify an instance
81  * of the <b>org.eclipse.ui.views</b> extension point:
82  *
83  * <pre>
84  *
85  * &lt;extension
86  * point=&quot;org.eclipse.ui.views&quot;&gt;
87  * &lt;view
88  * name=&quot;My Custom View&quot;
89  * icon=&quot;relative/path/to/icon.gif&quot;
90  * category=&quot;org.acme.mycategory&quot;
91  * class=&quot;org.eclipse.ui.navigator.CommonNavigator&quot;
92  * id=&quot;org.acme.MyCustomNavigatorID&quot;&gt;
93  * &lt;/view&gt;
94  * &lt;/extension&gt;
95  *
96  * </pre>
97  *
98  * </p>
99  * Clients that wish to extend the view menu provided via the
100  * <b>org.eclipse.ui.popupMenu</b>s extension may specify the the <i>popupMenuId</i>
101  * specified by <b>org.eclipse.ui.navigator.viewer</b> (or a nested <b>popupMenu</b> element) of their target viewer
102  * as their target menu id.
103  *
104  * <p>
105  * This class may be instantiated; it is not intended to be subclassed.
106  * </p>
107  *
108  * @since 3.2
109  */

110 public class CommonNavigator extends ViewPart implements ISetSelectionTarget, ISaveablePart, ISaveablesSource, IShowInTarget {
111  
112     private static final Class JavaDoc INAVIGATOR_CONTENT_SERVICE = INavigatorContentService.class;
113     private static final Class JavaDoc COMMON_VIEWER_CLASS = CommonViewer.class;
114     private static final Class JavaDoc ISHOW_IN_TARGET_CLASS = IShowInTarget.class;
115     
116     private static final String JavaDoc HELP_CONTEXT = NavigatorPlugin.PLUGIN_ID + ".common_navigator"; //$NON-NLS-1$
117

118     /**
119      * <p>
120      * Used to track changes to the {@link #isLinkingEnabled}&nbsp;property.
121      * </p>
122      */

123     public static final int IS_LINKING_ENABLED_PROPERTY = 1;
124
125     private CommonViewer commonViewer;
126
127     private CommonNavigatorManager commonManager;
128
129     private ActionGroup commonActionGroup;
130
131     private IMemento memento;
132
133     private boolean isLinkingEnabled = false;
134
135     private String JavaDoc LINKING_ENABLED = "CommonNavigator.LINKING_ENABLED"; //$NON-NLS-1$
136

137     private LinkHelperService linkService;
138     
139     /**
140      *
141      */

142     public CommonNavigator() {
143         super();
144     }
145
146     /**
147      * <p>
148      * Create the CommonViewer part control and setup the default providers as
149      * necessary.
150      * </p>
151      *
152      *
153      * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
154      */

155     public void createPartControl(Composite aParent) {
156
157         commonViewer = createCommonViewer(aParent);
158
159         try {
160             commonViewer.getControl().setRedraw(false);
161             
162             INavigatorFilterService filterService = commonViewer
163                     .getNavigatorContentService().getFilterService();
164             ViewerFilter[] visibleFilters = filterService.getVisibleFilters(true);
165             for (int i = 0; i < visibleFilters.length; i++) {
166                 commonViewer.addFilter(visibleFilters[i]);
167             }
168     
169             commonViewer.setSorter(new CommonViewerSorter());
170     
171             /*
172              * make sure input is set after sorters and filters to avoid unnecessary
173              * refreshes
174              */

175             commonViewer.setInput(getInitialInput());
176     
177             getSite().setSelectionProvider(commonViewer);
178     
179             updateTitle();
180         } finally {
181             commonViewer.getControl().setRedraw(true);
182         }
183
184         /*
185          * Create the CommonNavigatorManager last because information about the
186          * state of the CommonNavigator is required for the initialization of
187          * the CommonNavigatorManager
188          */

189         commonManager = createCommonManager();
190         if (memento != null) {
191             commonViewer.getNavigatorContentService().restoreState(memento);
192         }
193
194         commonActionGroup = createCommonActionGroup();
195         commonActionGroup.fillActionBars(getViewSite().getActionBars());
196         
197         ISaveablesLifecycleListener saveablesLifecycleListener = new ISaveablesLifecycleListener() {
198             ISaveablesLifecycleListener siteSaveablesLifecycleListener = (ISaveablesLifecycleListener) getSite()
199                     .getService(ISaveablesLifecycleListener.class);
200
201             public void handleLifecycleEvent(SaveablesLifecycleEvent event) {
202                 if (event.getEventType() == SaveablesLifecycleEvent.DIRTY_CHANGED) {
203                     firePropertyChange(PROP_DIRTY);
204                 }
205                 siteSaveablesLifecycleListener.handleLifecycleEvent(event);
206             }
207         };
208         commonViewer.getNavigatorContentService()
209                 .getSaveablesService().init(this, getCommonViewer(),
210                         saveablesLifecycleListener);
211         
212         commonViewer.addSelectionChangedListener(new ISelectionChangedListener() {
213
214             public void selectionChanged(SelectionChangedEvent event) {
215                 firePropertyChange(PROP_DIRTY);
216             }});
217         
218           PlatformUI.getWorkbench().getHelpSystem().setHelp(commonViewer.getControl(), HELP_CONTEXT);
219     }
220
221     /**
222      * <p>
223      * Note: This method is for internal use only. Clients should not call this
224      * method.
225      * </p>
226      * <p>
227      * This method will be invoked when the DisposeListener is notified of the
228      * disposal of the Eclipse view part.
229      * </p>
230      *
231      * @see org.eclipse.ui.part.WorkbenchPart#dispose()
232      */

233     public void dispose() {
234         if (commonManager != null) {
235             commonManager.dispose();
236         }
237         if(commonActionGroup != null) {
238             commonActionGroup.dispose();
239         }
240         super.dispose();
241     }
242
243     /**
244      * <p>
245      * Note: This method is for internal use only. Clients should not call this
246      * method.
247      * </p>
248      *
249      * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite,
250      * org.eclipse.ui.IMemento)
251      */

252     public void init(IViewSite aSite, IMemento aMemento)
253             throws PartInitException {
254         super.init(aSite, aMemento);
255         memento = aMemento;
256         if (memento != null) {
257             Integer JavaDoc linkingEnabledInteger = memento.getInteger(LINKING_ENABLED);
258             setLinkingEnabled(((linkingEnabledInteger != null) ? linkingEnabledInteger
259                     .intValue() == 1
260                     : false));
261         }
262
263     }
264
265     /**
266      *
267      * <p>
268      * Note: This method is for internal use only. Clients should not call this
269      * method.
270      * </p>
271      *
272      * @see org.eclipse.ui.part.ViewPart#saveState(org.eclipse.ui.IMemento)
273      */

274     public void saveState(IMemento aMemento) {
275         aMemento.putInteger(LINKING_ENABLED, (isLinkingEnabled) ? 1 : 0);
276         super.saveState(aMemento);
277         commonManager.saveState(aMemento);
278         commonViewer.getNavigatorContentService().saveState(aMemento);
279     }
280
281     /**
282      * <p>
283      * Force the workbench to focus on the Common Navigator tree.
284      * </p>
285      *
286      * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
287      */

288     public void setFocus() {
289         if (commonViewer != null) {
290             commonViewer.getTree().setFocus();
291         }
292     }
293
294     /**
295      * <p>
296      * Set the selection to the Common Navigator tree, and expand nodes if
297      * necessary. Use caution when invoking this method as it can cause
298      * Navigator Content Extensions to load, thus causing plugin activation.
299      * </p>
300      *
301      * @see org.eclipse.ui.part.ISetSelectionTarget#selectReveal(org.eclipse.jface.viewers.ISelection)
302      */

303     public void selectReveal(ISelection selection) {
304         if (commonViewer != null) {
305             if(selection instanceof IStructuredSelection) {
306                 Object JavaDoc[] newSelection = ((IStructuredSelection)selection).toArray();
307                 Object JavaDoc[] expandedElements = commonViewer.getExpandedElements();
308                 Object JavaDoc[] newExpandedElements = new Object JavaDoc[newSelection.length + expandedElements.length];
309                 System.arraycopy(expandedElements, 0, newExpandedElements, 0, expandedElements.length);
310                 System.arraycopy(newSelection, 0, newExpandedElements, expandedElements.length, newSelection.length);
311                 commonViewer.setExpandedElements(newExpandedElements);
312             }
313             commonViewer.setSelection(selection, true);
314         }
315     }
316
317     /**
318      * <p>
319      * Linking is handled by an action which listens for
320      * changes to the {@link CommonNavigator#IS_LINKING_ENABLED_PROPERTY}.
321      * Custom implementations that wish to override this functionality, need to
322      * override the action used by the default ActionGroup and listen for
323      * changes to the above property.
324      *
325      * @param toEnableLinking
326      * True enables linking the current selection with open editors
327      */

328     public final void setLinkingEnabled(boolean toEnableLinking) {
329         isLinkingEnabled = toEnableLinking;
330         firePropertyChange(IS_LINKING_ENABLED_PROPERTY);
331     }
332
333     /**
334      * @return Whether linking the current selection with open editors is
335      * enabled.
336      */

337     public final boolean isLinkingEnabled() {
338         return isLinkingEnabled;
339     }
340
341     /**
342      * <p>
343      * Provides access to the commonViewer used by the current CommonNavigator.
344      * The field will not be valid until after
345      * {@link #init(IViewSite, IMemento)}&nbsp;has been called by the
346      * Workbench.
347      * </p>
348      *
349      * @return The (already created) instance of Common Viewer.
350      */

351     public CommonViewer getCommonViewer() {
352         return commonViewer;
353     }
354
355     /**
356      * @return The Navigator Content Service which populates this instance of
357      * Common Navigator
358      */

359     public INavigatorContentService getNavigatorContentService() {
360         return getCommonViewer().getNavigatorContentService();
361     }
362
363     /**
364      * Returns an object which is an instance of the given class
365      * associated with this object. Returns <code>null</code> if
366      * no such object can be found.
367      *
368      * @param adapter the adapter class to look up
369      * @return a object castable to the given class,
370      * or <code>null</code> if this object does not
371      * have an adapter for the given class
372      */

373     public Object JavaDoc getAdapter(Class JavaDoc adapter) {
374         if (adapter == COMMON_VIEWER_CLASS) {
375             return getCommonViewer();
376         } else if (adapter == INAVIGATOR_CONTENT_SERVICE) {
377             return getCommonViewer().getNavigatorContentService();
378         } else if ( adapter == ISHOW_IN_TARGET_CLASS) {
379             return this;
380         }
381         return super.getAdapter(adapter);
382     }
383
384     /**
385      * @return The Navigator Content Service which populates this instance of
386      * Common Navigator
387      */

388     public NavigatorActionService getNavigatorActionService() {
389         return commonManager.getNavigatorActionService();
390     }
391
392     /**
393      * <p>
394      * Constructs and returns an instance of {@link CommonViewer}. The ID of
395      * the Eclipse view part will be used to create the viewer. The ID is
396      * important as some extensions indicate they should only be used with a
397      * particular viewer ID.
398      * <p>
399      *
400      * @param aParent
401      * A composite parent to contain the Common Viewer
402      * @return An initialized instance of CommonViewer
403      */

404     protected CommonViewer createCommonViewer(Composite aParent) {
405         CommonViewer aViewer = new CommonViewer(getViewSite().getId(), aParent,
406                 SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
407         initListeners(aViewer);
408         aViewer.getNavigatorContentService().restoreState(memento);
409         return aViewer;
410     }
411
412     /**
413      * <p>
414      * Adds the listeners to the Common Viewer.
415      * </p>
416      *
417      * @param viewer
418      * The viewer
419      * @since 2.0
420      */

421     protected void initListeners(TreeViewer viewer) {
422
423         viewer.addDoubleClickListener(new IDoubleClickListener() {
424
425             public void doubleClick(DoubleClickEvent event) {
426                 try {
427                     handleDoubleClick(event);
428                 } catch (RuntimeException JavaDoc re) {
429                     re.printStackTrace();
430                 }
431             }
432         });
433     }
434
435     /**
436      * <p>
437      * Note: This method is for internal use only. Clients should not call this
438      * method.
439      * </p>
440      *
441      * @param anEvent
442      * Supplied by the DoubleClick listener.
443      */

444     protected void handleDoubleClick(DoubleClickEvent anEvent) {
445
446         IAction openHandler = getViewSite().getActionBars().getGlobalActionHandler(ICommonActionConstants.OPEN);
447         
448         if(openHandler == null) {
449             IStructuredSelection selection = (IStructuredSelection) anEvent
450                     .getSelection();
451             Object JavaDoc element = selection.getFirstElement();
452     
453             TreeViewer viewer = getCommonViewer();
454             if (viewer.isExpandable(element)) {
455                 viewer.setExpandedState(element, !viewer.getExpandedState(element));
456             }
457         }
458     }
459
460     /**
461      * <p>
462      * The Common Navigator Manager handles the setup of the Common Navigator
463      * Menu, manages updates to the ActionBars from
464      * {@link CommonActionProvider}&nbsp; extensions as the user's selection
465      * changes, and also updates the status bar based on the current selection.
466      *
467      * @return The Common Navigator Manager class which handles menu population
468      * and ActionBars
469      */

470     protected CommonNavigatorManager createCommonManager() {
471         return new CommonNavigatorManager(this, memento);
472     }
473
474     /**
475      * <p>
476      * The ActionGroup is used to populate the ActionBars of Common Navigator
477      * View Part, and the returned implementation will have an opportunity to
478      * fill the ActionBars of the view as soon as it is created. ({@link ActionGroup#fillActionBars(org.eclipse.ui.IActionBars)}.
479      * </p>
480      * <p>
481      * The default implementation returns an action group which will add the
482      * following actions:
483      * <ul>
484      * <li>
485      * <p>
486      * Link with editor support. Allows the user to toggling linking the current
487      * selection with the active editors.
488      * </p>
489      * <li>
490      * <p>
491      * Collapse all. Collapses all expanded nodes.
492      * </p>
493      * <li>
494      * <p>
495      * Select Filters. Provides access to the "Select Filters" dialog that
496      * allows users to enable/disable filters and also the Content Extension
497      * activations.
498      * </p>
499      * </ul>
500      *
501      * @return The Action Group to be associated with the Common Navigator View
502      * Part.
503      */

504     protected ActionGroup createCommonActionGroup() {
505         return new CommonNavigatorActionGroup(this, commonViewer, getLinkHelperService());
506     }
507
508     /**
509      * @return The initial input for the viewer. Defaults to
510      * getSite().getPage().getInput()
511      */

512     protected IAdaptable getInitialInput() {
513         return getSite().getPage().getInput();
514     }
515
516     /**
517      * <p>
518      * Updates the title text and title tool tip. Called whenever the input of
519      * the viewer changes.
520      * </p>
521      */

522     protected void updateTitle() {
523
524         if (commonViewer == null) {
525             return;
526         }
527
528         Object JavaDoc input = commonViewer.getInput();
529         String JavaDoc viewName = getConfigurationElement().getAttribute("name"); //$NON-NLS-1$
530
// IWorkingSet workingSet = workingSetFilter.getWorkingSet();
531

532         if (input == null) {
533             setPartName(viewName);
534             setTitleToolTip(""); //$NON-NLS-1$
535
} else {
536             String JavaDoc inputToolTip = getFrameToolTipText(input);
537
538             setPartName(viewName);
539             setTitleToolTip(inputToolTip);
540         }
541     }
542
543     /**
544      * <p>
545      * Returns the tool tip text for the given element. Used as the tool tip
546      * text for the current frame, and for the view title tooltip.
547      * </p>
548      */

549     protected String JavaDoc getFrameToolTipText(Object JavaDoc anElement) {
550         if (commonViewer != null) {
551             return ((ILabelProvider) commonViewer.getLabelProvider())
552                     .getText(anElement);
553         }
554         return ""; //$NON-NLS-1$
555
}
556
557     /* (non-Javadoc)
558      * @see org.eclipse.ui.ISaveablesSource#getSaveables()
559      */

560     public Saveable[] getSaveables() {
561         return getNavigatorContentService().getSaveablesService().getSaveables();
562     }
563
564     /* (non-Javadoc)
565      * @see org.eclipse.ui.ISaveablesSource#getActiveSaveables()
566      */

567     public Saveable[] getActiveSaveables() {
568         return getNavigatorContentService().getSaveablesService().getActiveSaveables();
569     }
570
571     /* (non-Javadoc)
572      * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
573      */

574     public void doSave(IProgressMonitor monitor) {
575         // Ignore. This method is not called because CommonNavigator implements
576
// ISaveablesSource. All saves will go through the ISaveablesSource /
577
// Saveable protocol.
578
}
579
580     /* (non-Javadoc)
581      * @see org.eclipse.ui.ISaveablePart#doSaveAs()
582      */

583     public void doSaveAs() {
584         // ignore
585
}
586
587     /* (non-Javadoc)
588      * @see org.eclipse.ui.ISaveablePart#isDirty()
589      */

590     public boolean isDirty() {
591         Saveable[] saveables = getSaveables();
592         for (int i = 0; i < saveables.length; i++) {
593             if(saveables[i].isDirty()) {
594                 return true;
595             }
596         }
597         return false;
598     }
599
600     /* (non-Javadoc)
601      * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
602      */

603     public boolean isSaveAsAllowed() {
604         return false;
605     }
606
607     /* (non-Javadoc)
608      * @see org.eclipse.ui.ISaveablePart#isSaveOnCloseNeeded()
609      */

610     public boolean isSaveOnCloseNeeded() {
611         return isDirty();
612     }
613
614     /* (non-Javadoc)
615      * @see org.eclipse.ui.part.IShowInTarget#show(org.eclipse.ui.part.ShowInContext)
616      */

617     public boolean show(ShowInContext context) {
618         IStructuredSelection selection = getSelection(context);
619         if (selection != null && !selection.isEmpty()) {
620             selectReveal(selection);
621             return true;
622         }
623         return false;
624     }
625
626     private IStructuredSelection getSelection(ShowInContext context) {
627         if (context == null)
628             return StructuredSelection.EMPTY;
629         ISelection selection = context.getSelection();
630         if (selection != null && !selection.isEmpty() && selection instanceof IStructuredSelection)
631             return (IStructuredSelection)selection;
632         Object JavaDoc input = context.getInput();
633         if (input instanceof IEditorInput) {
634             LinkHelperService lhs = getLinkHelperService();
635             return lhs.getSelectionFor((IEditorInput) input);
636         }
637         if (input != null) {
638             return new StructuredSelection(input);
639         }
640         return StructuredSelection.EMPTY;
641     }
642
643     private synchronized LinkHelperService getLinkHelperService() {
644         if (linkService == null)
645             linkService = new LinkHelperService((NavigatorContentService)getCommonViewer().getNavigatorContentService());
646         return linkService;
647     }
648  
649 }
650
Popular Tags