Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/port80/eclipse/xml/editors/XMLOutlinePage.java


1   package com.port80.eclipse.xml.editors;
2   
3   import java.util.ArrayList;
4   import java.util.Iterator;
5   import java.util.List;
6   
7   import org.eclipse.jface.action.Action;
8   import org.eclipse.jface.action.IMenuListener;
9   import org.eclipse.jface.action.IMenuManager;
10  import org.eclipse.jface.action.IToolBarManager;
11  import org.eclipse.jface.action.MenuManager;
12  import org.eclipse.jface.action.Separator;
13  import org.eclipse.jface.dialogs.MessageDialog;
14  import org.eclipse.jface.preference.IPreferenceStore;
15  import org.eclipse.jface.text.DefaultPositionUpdater;
16  import org.eclipse.jface.text.IDocument;
17  import org.eclipse.jface.text.ITextSelection;
18  import org.eclipse.jface.text.Position;
19  import org.eclipse.jface.text.source.SourceViewer;
20  import org.eclipse.jface.util.IPropertyChangeListener;
21  import org.eclipse.jface.util.PropertyChangeEvent;
22  import org.eclipse.jface.viewers.DoubleClickEvent;
23  import org.eclipse.jface.viewers.IDoubleClickListener;
24  import org.eclipse.jface.viewers.ISelection;
25  import org.eclipse.jface.viewers.ISelectionChangedListener;
26  import org.eclipse.jface.viewers.IStructuredSelection;
27  import org.eclipse.jface.viewers.SelectionChangedEvent;
28  import org.eclipse.jface.viewers.StructuredSelection;
29  import org.eclipse.jface.viewers.TreeViewer;
30  import org.eclipse.jface.viewers.Viewer;
31  import org.eclipse.swt.SWT;
32  import org.eclipse.swt.dnd.Clipboard;
33  import org.eclipse.swt.events.KeyEvent;
34  import org.eclipse.swt.events.KeyListener;
35  import org.eclipse.swt.widgets.Composite;
36  import org.eclipse.swt.widgets.Control;
37  import org.eclipse.swt.widgets.Menu;
38  import org.eclipse.ui.IActionBars;
39  import org.eclipse.ui.IPartListener;
40  import org.eclipse.ui.ISelectionListener;
41  import org.eclipse.ui.IWorkbenchPart;
42  import org.eclipse.ui.internal.dialogs.ViewSorter;
43  import org.eclipse.ui.part.IPageSite;
44  import org.eclipse.ui.part.Page;
45  import org.eclipse.ui.texteditor.ITextEditor;
46  import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
47  import org.w3c.dom.Node;
48  
49  import com.port80.eclipse.editors.EditorsPlugin;
50  import com.port80.eclipse.editors.IConstants;
51  import com.port80.eclipse.editors.util.NamedPosition;
52  import com.port80.eclipse.util.IncrementalFindTreeTarget;
53  import com.port80.eclipse.util.UtilPluginImages;
54  import com.port80.eclipse.xml.parser.XElementNS;
55  
56  /**
57   * ContentOutlinePage for XMLEditor to use the Eclipse Outline view to
58   * present an outline of terminal and non-terminals in the document.
59   * 
60   * @author chrisl
61   */
62  public class XMLOutlinePage
63    extends Page
64    implements IContentOutlinePage, ISelectionChangedListener, KeyListener, ISelectionListener, IPropertyChangeListener {
65  
66    ////////////////////////////////////////////////////////////////////////
67  
68    private static final String NAME = "XMLOutlinePage";
69    private static final String VERSION = "v0.1";
70    private static final String CONTEXT_MENU_ID = "XMLOutlinePage";
71    private static final boolean DEBUG = true;
72    //
73    public static final String ID = "com.port80.eclipse.xml.editors.XMLOutlinePage";
74    public static final int SHOW_ALL = 0x01;
75  
76    private static int fDefaultShowLevel = SHOW_ALL;
77  
78    ////////////////////////////////////////////////////////////////////////
79  
80    private Clipboard fClipboard;
81    private XMLEditor fEditor;
82    private SourceViewer fEditorViewer;
83    private Node fInput;
84    //
85    private TreeViewer fViewer;
86    private XMLOutlineContentProvider fProvider;
87    private IPartListener fPartListener;
88    private List fInTextOrder;
89    private ViewSorter fSorter;
90    private DefaultPositionUpdater fPositionUpdater;
91    //
92    private Action fActionHeader;
93    private Action fActionSort;
94    private Action fActionRefresh;
95    private Action fActionGoto;
96    private Action fActionAbout;
97    private Action fActionExpandAll;
98    private Action fActionCollapseAll;
99    private Action fActionExpand2;
100   private Action fActionCollapse2;
101   private List fSelectionListeners;
102   //
103   private IncrementalFindTreeTarget findTarget;
104   private int fShowLevel;
105 
106   ////////////////////////////////////////////////////////////////////////
107 
108   public XMLOutlinePage(XMLEditor editor) {
109     super();
110     fEditor = editor;
111     //
112     fEditorViewer = editor.getViewer();
113     fShowLevel = fDefaultShowLevel;
114     fSelectionListeners = new ArrayList();
115     fInTextOrder = new ArrayList();
116     fSorter = new NameSorter();
117     fProvider = new XMLOutlineContentProvider();
118   }
119 
120   ////////////////////////////////////////////////////////////////////////
121 
122   /**
123    * @see org.eclipse.ui.part.IPageBookViewPage#init(IPageSite)
124    */
125   public void init(IPageSite site) {
126     super.init(site);
127   }
128 
129   /**
130    * @see IWorkbenchPart#dispose()
131    */
132   public void dispose() {
133     EditorsPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
134     disableSyncSelection();
135     fEditor.outlinePageDisposed();
136     super.dispose();
137     fClipboard = null;
138     fEditor = null;
139     fEditorViewer = null;
140     fInput = null;
141     fViewer = null;
142   }
143 
144   /**
145    * This is a callback that will allow us to create the viewer and initialize it.
146    */
147   public void createControl(Composite parent) {
148     fViewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
149     fClipboard = new Clipboard(parent.getDisplay());
150     fViewer.setContentProvider(fProvider);
151     fViewer.setLabelProvider(fProvider);
152     fViewer.setInput(fProvider.getRoot());
153     getSite().setSelectionProvider(fViewer);
154     makeActions();
155     hookContextMenu();
156     hookDoubleClickAction();
157     hookKeyListener();
158     // hookPartListener();
159     contributeToActionBars();
160     IPreferenceStore prefs = EditorsPlugin.getDefault().getPreferenceStore();
161     if (prefs.getBoolean(IConstants.PREF_XML_SYNC_SELECTION)) {
162       enableSyncSelection();
163     }
164     prefs.addPropertyChangeListener(this);
165     if (fEditor.getModel() == null)
166       fEditor.createModel();
167     setInput(fEditor.getModel());
168   }
169 
170   ////////////////////////////////////////////////////////////////////////
171 
172   public void setInput(Node input) {
173     if (fInput != null && input == fInput)
174       return;
175     if (!isValidInput(input)) {
176       setInput(null);
177       return;
178     }
179     //fViewer.collapseAll();
180     fInput = input;
181     refresh();
182     // fViewer.reveal(fProvider.getTop());
183   }
184 
185   public ITextEditor getEditor() {
186     return fEditor;
187   }
188 
189   Node getInput() {
190     return fInput;
191   }
192 
193   private void refresh() {
194     IStructuredSelection selection = (IStructuredSelection) fViewer.getSelection();
195     TreeObject a = null;
196     if (selection != null && !selection.isEmpty()) {
197       a = (TreeObject) selection.getFirstElement();
198     }
199     fViewer.setSelection(StructuredSelection.EMPTY);
200     fInTextOrder.clear();
201     if (fInput != null) {
202       TreeFolder top = new TreeFolder(fEditor.getEditorInput().getName());
203       IDocument doc = fEditorViewer.getDocument();
204       int tabwidth = fEditor.getConfiguration().getTabWidth(fEditorViewer);
205       addPositions(fInput, doc, top, tabwidth);
206       //
207       fProvider.setInput(top);
208     } else {
209       fProvider.setInput(new TreeFolder("Outline not available"));
210     }
211     // Added folders are collapsed by default, expand interesting ones.
212     // NOTE: Need to refresh() before expandTree(), otherwise, collapsing to object do not work.
213     fViewer.setInput(fProvider.getRoot());
214     fViewer.refresh();
215     fProvider.expandTree(fViewer);
216     if (fEditorViewer != null
217       && a != null
218       && a.getElement() != null
219       && (a.getElement() instanceof NamedPosition)) {
220       a = findElement(a.getElement());
221       if (a != null)
222         fViewer.setSelection(new StructuredSelection(a), true);
223     }
224   }
225 
226   public TreeViewer getViewer() {
227     return fViewer;
228   }
229 
230   /**
231    * @see org.eclipse.ui.part.IPage#getControl()
232    */
233   public Control getControl() {
234     return fViewer.getControl();
235   }
236 
237   /**
238    * @see org.eclipse.ui.views.contentoutline.ContentOutlinePage#getTreeViewer()
239    */
240   protected TreeViewer getTreeViewer() {
241     return fViewer;
242   }
243 
244   public TreeObject findElement(Object a) {
245     return fProvider.findElement(a);
246   }
247 
248   public void setShowLevel(int level) {
249     this.fShowLevel = level;
250     fDefaultShowLevel = fShowLevel;
251   }
252 
253   /**
254    * Passing the focus request to the viewer's control.
255    */
256   public void setFocus() {
257     fViewer.getControl().setFocus();
258   }
259 
260   ////////////////////////////////////////////////////////////////////////
261 
262   private void makeActions() {
263     //    fActionShowInEditor = new ShowInEditorAction();
264     //
265     fActionHeader = new Action() {
266       public void run() {
267       }
268     };
269     fActionHeader.setText("XML Outline Menu:");
270     fActionHeader.setEnabled(false);
271     //
272     fActionSort = new Action() {
273       public void run() {
274         setToolTipText(
275           isChecked() ? "Sort in document location order" : "Sort in lexical order");
276         sortAction(isChecked());
277       }
278     };
279     fActionSort.setChecked(false);
280     fActionSort.setText("Sort in lexical order");
281     fActionSort.setToolTipText("Sort in lexical order");
282     UtilPluginImages.setLocalImageDescriptors(fActionSort, UtilPluginImages.IMG_SORT);
283     //
284     fActionGoto = new Action() {
285       public void run() {
286         gotoAction();
287       }
288     };
289     fActionGoto.setText("Goto");
290     fActionGoto.setToolTipText("Goto item");
291     UtilPluginImages.setLocalImageDescriptors(fActionGoto, UtilPluginImages.IMG_GOTO);
292     //
293     fActionRefresh = new Action() {
294       public void run() {
295         refreshAction();
296       }
297     };
298     fActionRefresh.setText("Refresh");
299     fActionRefresh.setToolTipText("Refresh");
300     UtilPluginImages.setLocalImageDescriptors(fActionRefresh, UtilPluginImages.IMG_REFRESH);
301     //
302     fActionAbout = new Action() {
303       public void run() {
304         showMessage(NAME + " " + VERSION);
305       }
306     };
307     fActionAbout.setText("About");
308     fActionAbout.setToolTipText("About MethodView");
309     fActionAbout.setImageDescriptor(UtilPluginImages.DESC_INFO);
310     //
311     fActionExpandAll = new Action() {
312       public void run() {
313         IStructuredSelection selection = (IStructuredSelection) getSelection();
314         if (selection != null)
315           for (Iterator it = selection.iterator(); it.hasNext();)
316             expandAllAction(it.next());
317       }
318     };
319     fActionExpandAll.setText("Expand All");
320     fActionExpandAll.setToolTipText("Expand all");
321     UtilPluginImages.setLocalImageDescriptors(fActionExpandAll, UtilPluginImages.IMG_REFRESH);
322     //
323     fActionCollapseAll = new Action() {
324       public void run() {
325         IStructuredSelection selection = (IStructuredSelection) getSelection();
326         if (selection != null)
327           for (Iterator it = selection.iterator(); it.hasNext();)
328             collapseAllAction(it.next());
329       }
330     };
331     fActionCollapseAll.setText("Collapse All");
332     fActionCollapseAll.setToolTipText("Collapse all");
333     UtilPluginImages.setLocalImageDescriptors(fActionCollapseAll, UtilPluginImages.IMG_REFRESH);
334     //
335     fActionExpand2 = new Action() {
336       public void run() {
337         IStructuredSelection selection = (IStructuredSelection) getSelection();
338         if (selection != null)
339           for (Iterator it = selection.iterator(); it.hasNext();)
340             expand2Action(it.next());
341       }
342     };
343     fActionExpand2.setText("Expand 2");
344     fActionExpand2.setToolTipText("Expand two levels");
345     UtilPluginImages.setLocalImageDescriptors(fActionExpand2, UtilPluginImages.IMG_REFRESH);
346     //
347     fActionCollapse2 = new Action() {
348       public void run() {
349         IStructuredSelection selection = (IStructuredSelection) getSelection();
350         if (selection != null)
351           for (Iterator it = selection.iterator(); it.hasNext();)
352             collapse2Action(it.next());
353       }
354     };
355     fActionCollapse2.setText("Collapse 2");
356     fActionCollapse2.setToolTipText("Collapse two levels");
357     UtilPluginImages.setLocalImageDescriptors(fActionCollapse2, UtilPluginImages.IMG_REFRESH);
358   }
359 
360   private void contributeToActionBars() {
361     IActionBars bars = getSite().getActionBars();
362     fillLocalPullDown(bars.getMenuManager());
363     fillLocalToolBar(bars.getToolBarManager());
364   }
365 
366   private void fillLocalPullDown(IMenuManager manager) {
367     manager.add(fActionAbout);
368   }
369 
370   private void fillLocalToolBar(IToolBarManager manager) {
371     manager.add(fActionRefresh);
372     manager.add(fActionSort);
373     manager.add(new Separator());
374     //JdtPlugin.getNavHistory().addNavigationActions(manager);
375     manager.add(new Separator());
376   }
377 
378   private void hookContextMenu() {
379     MenuManager menuMgr = new MenuManager(CONTEXT_MENU_ID);
380     menuMgr.setRemoveAllWhenShown(true);
381     menuMgr.addMenuListener(new IMenuListener() {
382       public void menuAboutToShow(IMenuManager manager) {
383         XMLOutlinePage.this.fillContextMenu(manager);
384       }
385     });
386     Menu menu = menuMgr.createContextMenu(fViewer.getControl());
387     fViewer.getControl().setMenu(menu);
388     // Register menu so that other plugin can contribute to it.
389     getSite().registerContextMenu(CONTEXT_MENU_ID, menuMgr, fViewer);
390   }
391 
392   void fillContextMenu(IMenuManager manager) {
393     manager.add(fActionHeader);
394     manager.add(new Separator());
395     manager.add(fActionExpandAll);
396     manager.add(fActionCollapseAll);
397     manager.add(fActionExpand2);
398     manager.add(fActionCollapse2);
399     // Other plug-ins can contribute there actions here
400     manager.add(new Separator("Additions"));
401   }
402 
403   private void hookDoubleClickAction() {
404     fViewer.addDoubleClickListener(new IDoubleClickListener() {
405       public void doubleClick(DoubleClickEvent event) {
406         gotoAction();
407       }
408     });
409   }
410 
411   /** Temporary hack to do the incremental search.  Should move to StructuredViewer later.              */
412   private void hookKeyListener() {
413     fViewer.getControl().addKeyListener(this);
414   }
415 
416   void showMessage(String message) {
417     MessageDialog.openInformation(fViewer.getControl().getShell(), NAME, message);
418   }
419 
420   // Actions /////////////////////////////////////////////////////////////
421   //
422 
423   void expandAllAction(Object a) {
424     fViewer.expandToLevel(a, TreeViewer.ALL_LEVELS);
425   }
426 
427   void collapseAllAction(Object a) {
428     fViewer.collapseToLevel(a, TreeViewer.ALL_LEVELS);
429   }
430 
431   void expand2Action(Object a) {
432     fViewer.expandToLevel(a, 2);
433   }
434 
435   void collapse2Action(Object a) {
436     fViewer.collapseToLevel(a, 2);
437   }
438 
439   void refreshAction() {
440     EditorsPlugin.deleteProblemMarkers(fEditor.getEditorInput(), IConstants.FormatActionProblemMarker);
441     fEditor.createModel();
442     fInput=fEditor.getModel();
443     refresh();
444   }
445 
446   void sortAction(boolean on) {
447     if (fViewer == null)
448       return;
449     fViewer.setSorter(on ? fSorter : null);
450   }
451 
452   void gotoAction() {
453     IStructuredSelection selection = (IStructuredSelection) fViewer.getSelection();
454     if (selection == null || selection.isEmpty())
455       return;
456     Object a = selection.getFirstElement();
457     if (!(a instanceof TreeObject))
458       return;
459     Object element = ((TreeObject) a).getElement();
460     if (element == null || !(element instanceof Position))
461       return;
462     Position position = (Position) element;
463     int len = position.length;
464     if (a instanceof TreeFolder)
465       len = 0;
466     fEditorViewer.setSelectedRange(position.offset, len);
467     fEditorViewer.revealRange(position.offset, len);
468     getSite().getActionBars().getStatusLineManager().setMessage(a.toString());
469   }
470 
471   // ISelectionChangeListener /////////////////////////////////////////
472 
473   /**
474    * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
475    */
476   public void selectionChanged(SelectionChangedEvent event) {
477   }
478 
479   /**
480    * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(ISelectionChangedListener)
481    */
482   public void addSelectionChangedListener(ISelectionChangedListener listener) {
483     fSelectionListeners.add(listener);
484   }
485 
486   /**
487    * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(ISelectionChangedListener)
488    */
489   public void removeSelectionChangedListener(ISelectionChangedListener listener) {
490     fSelectionListeners.remove(listener);
491   }
492 
493   /**
494    * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(ISelection)
495    */
496   public void setSelection(ISelection selection) {
497     if (fViewer != null) {
498       fViewer.setSelection(selection);
499     }
500   }
501 
502   public ISelection getSelection() {
503     if (fViewer == null)
504       return StructuredSelection.EMPTY;
505     return (IStructuredSelection) fViewer.getSelection();
506   }
507 
508   /**
509    * Fires a selection changed event.
510    *
511    * @param selction the new selection
512    */
513   protected void fireSelectionChanged(ISelection selection) {
514     // create an event
515     SelectionChangedEvent event = new SelectionChangedEvent(this, selection);
516     // fire the event
517     for (int i = 0; i < fSelectionListeners.size(); ++i) {
518       ((ISelectionChangedListener) fSelectionListeners.get(i)).selectionChanged(event);
519     }
520   }
521 
522   // ISelectionListener //////////////////////////////////////////////////
523 
524   /**
525    * @see ISelectionListener#selectionChanged(IWorkbenchPart, ISelection)
526    */
527   public void selectionChanged(IWorkbenchPart part, ISelection selection) {
528     if (part != fEditor)
529       return;
530     //if (viewIsOnTop()) {
531     setSelectionFromEditor(selection, true);
532     //}
533   }
534 
535   // IPropertyChangeListener /////////////////////////////////////////////
536 
537   /**
538    * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
539    */
540   public void propertyChange(PropertyChangeEvent event) {
541     if (IConstants.PREF_XML_SYNC_SELECTION.equals(event.getProperty())) {
542       Boolean enable = (Boolean) event.getNewValue();
543       if (enable.booleanValue())
544         enableSyncSelection();
545       else
546         disableSyncSelection();
547     }
548   }
549 
550   private void enableSyncSelection() {
551     getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(this);
552   }
553 
554   private void disableSyncSelection() {
555     getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(this);
556   }
557 
558   // KeyListener ///////////////////////////////////////////////////////
559 
560   public void keyPressed(KeyEvent event) {
561     if (DEBUG)
562       System.out.println(
563         NAME
564           + ".keyPressed(): mask="
565           + event.stateMask
566           + ", character="
567           + event.character
568           + ", keycode="
569           + event.keyCode);
570     // if (event.stateMask == (SWT.CTRL | SWT.ALT | SWT.SHIFT) && event.character == 0x73) {
571     if (event.stateMask == 0 && event.character == 0x73) {
572       // 'C-s' is trapped by eclipse. For now, use 'M-C-s' instead.
573       beginSession(true);
574     } else if (event.stateMask == 0 && event.character == 0x72) {
575       // 'C-r' keyPressed() for 'M-C-r'  are trapped by eclipse. For now, use 'M-C-r' keyReleased() instead.
576       beginSession(false);
577     }
578   }
579   public void keyReleased(KeyEvent event) {
580     if (DEBUG)
581       System.out.println(
582         NAME
583           + ".keyReleased(): mask="
584           + event.stateMask
585           + ", character="
586           + event.character
587           + ", keycode="
588           + event.keyCode);
589     // if (event.stateMask == (SWT.CTRL | SWT.ALT | SWT.SHIFT) && event.character == 0x72) {
590   }
591 
592   public void beginSession(boolean forward) {
593     findTarget =
594       new IncrementalFindTreeTarget(fViewer, getSite().getActionBars().getStatusLineManager(), this);
595     String defaultString = null;
596     findTarget.beginSession(forward, defaultString);
597   }
598 
599   // Update View on editor activation ///////////////////////////
600 
601   public void setSelectionFromEditor(ISelection selection, boolean reveal) {
602     if (selection == null)
603       return;
604     if (!(selection instanceof ITextSelection))
605       return;
606     if (((ITextSelection) selection).getLength() == 0)
607       return;
608     int offset = ((ITextSelection) selection).getOffset();
609     TreeObject a = findElementAtOffset(offset);
610     if (false)
611       System.err.println(NAME + ".setSelectionFromEditor(): offset=" + offset + ", a=" + a);
612     if (a == null)
613       fViewer.setSelection(StructuredSelection.EMPTY);
614     else
615       fViewer.setSelection(new StructuredSelection(a), reveal);
616   }
617 
618   /**
619    * Answers if the given <code>element</code> is a valid
620    * element for this part.  For MethodView only IType is valid.
621    * 
622    * @param       element the object to test
623    * @return      <true> if the given element is a valid element
624    */
625   protected boolean isValidInput(Object element) {
626     return (element == null || element instanceof Node);
627   }
628 
629   /** Return an error message for the given Java element.*/
630   private String errorMessage(String method, Node node) {
631     String ret = NAME + method;
632     if (node != null)
633       return (ret + ": node=" + node.toString());
634     else
635       return ret;
636   }
637 
638   private void addPositions(Node node, IDocument doc, TreeFolder parent, int tabwidth) {
639     TreeFolder child = parent;
640     if (node instanceof XElementNS) {
641       if (node.getNodeType() == Node.ELEMENT_NODE) {
642         XElementNS element = (XElementNS) node;
643         NamedPosition position = (NamedPosition) element.getUserData();
644         if (position != null) {
645           child = new TreeFolder(position);
646           parent.addChild(child);
647           fInTextOrder.add(child);
648         }
649       }
650     }
651     for (Node n = node.getFirstChild(); n != null; n = n.getNextSibling())
652       addPositions(n, doc, child, tabwidth);
653   }
654 
655   /**
656    * @enter Tree element must be sorted in text order in source file.
657    */
658   private TreeObject findElementAtOffset(int offset) {
659     if (fInTextOrder == null || fInTextOrder.size() == 0)
660       return null;
661     TreeObject child;
662     TreeObject ret = null;
663     Position p;
664     for (int i = 0; i < fInTextOrder.size(); ++i) {
665       child = (TreeObject) fInTextOrder.get(i);
666       p = (Position) child.getElement();
667       if (p != null && p.offset <= offset) {
668         if (p.offset + p.length > offset)
669           ret = child;
670       } else
671         break;
672     }
673     return ret;
674   }
675 
676   ////////////////////////////////////////////////////////////////////////
677 
678   static class NameSorter extends ViewSorter {
679     public NameSorter() {
680       super(null);
681     }
682     /**
683      * @see org.eclipse.ui.internal.dialogs.ViewSorter#compare(Viewer, Object, Object)
684      */
685     public int compare(Viewer viewer, Object e1, Object e2) {
686       TreeObject a = (TreeObject) e1;
687       TreeObject b = (TreeObject) e2;
688       int akind = a.fKind;
689       int bkind = b.fKind;
690       if (akind > bkind)
691         return 1;
692       if (bkind > akind)
693         return -1;
694       return a.toString().compareTo(b.toString());
695     }
696   }
697 
698   ////////////////////////////////////////////////////////////////////////
699 
700 }