KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > javaeditor > JavaOutlinePage


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.jdt.internal.ui.javaeditor;
12
13
14 import java.util.Enumeration JavaDoc;
15 import java.util.Hashtable JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Vector JavaDoc;
18
19 import org.eclipse.core.runtime.Assert;
20 import org.eclipse.core.runtime.IAdaptable;
21 import org.eclipse.core.runtime.ListenerList;
22
23 import org.eclipse.core.resources.IResource;
24
25 import org.eclipse.swt.SWT;
26 import org.eclipse.swt.custom.BusyIndicator;
27 import org.eclipse.swt.dnd.DND;
28 import org.eclipse.swt.dnd.Transfer;
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Control;
31 import org.eclipse.swt.widgets.Display;
32 import org.eclipse.swt.widgets.Item;
33 import org.eclipse.swt.widgets.Menu;
34 import org.eclipse.swt.widgets.Tree;
35 import org.eclipse.swt.widgets.Widget;
36
37 import org.eclipse.jface.action.Action;
38 import org.eclipse.jface.action.IAction;
39 import org.eclipse.jface.action.IMenuListener;
40 import org.eclipse.jface.action.IMenuManager;
41 import org.eclipse.jface.action.IStatusLineManager;
42 import org.eclipse.jface.action.IToolBarManager;
43 import org.eclipse.jface.action.MenuManager;
44 import org.eclipse.jface.action.Separator;
45 import org.eclipse.jface.preference.IPreferenceStore;
46 import org.eclipse.jface.util.IPropertyChangeListener;
47 import org.eclipse.jface.util.PropertyChangeEvent;
48 import org.eclipse.jface.util.TransferDragSourceListener;
49 import org.eclipse.jface.util.TransferDropTargetListener;
50 import org.eclipse.jface.viewers.IBaseLabelProvider;
51 import org.eclipse.jface.viewers.IPostSelectionProvider;
52 import org.eclipse.jface.viewers.ISelection;
53 import org.eclipse.jface.viewers.ISelectionChangedListener;
54 import org.eclipse.jface.viewers.ISelectionProvider;
55 import org.eclipse.jface.viewers.IStructuredSelection;
56 import org.eclipse.jface.viewers.ITreeContentProvider;
57 import org.eclipse.jface.viewers.LabelProviderChangedEvent;
58 import org.eclipse.jface.viewers.SelectionChangedEvent;
59 import org.eclipse.jface.viewers.StructuredSelection;
60 import org.eclipse.jface.viewers.TreeViewer;
61 import org.eclipse.jface.viewers.Viewer;
62 import org.eclipse.jface.viewers.ViewerFilter;
63
64 import org.eclipse.jface.text.ITextSelection;
65
66 import org.eclipse.ui.IActionBars;
67 import org.eclipse.ui.PlatformUI;
68 import org.eclipse.ui.actions.ActionContext;
69 import org.eclipse.ui.actions.ActionGroup;
70 import org.eclipse.ui.model.IWorkbenchAdapter;
71 import org.eclipse.ui.model.WorkbenchAdapter;
72 import org.eclipse.ui.part.IPageSite;
73 import org.eclipse.ui.part.IShowInSource;
74 import org.eclipse.ui.part.IShowInTarget;
75 import org.eclipse.ui.part.IShowInTargetList;
76 import org.eclipse.ui.part.Page;
77 import org.eclipse.ui.part.ShowInContext;
78 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
79 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
80 import org.eclipse.ui.texteditor.IUpdate;
81
82 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
83 import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
84
85 import org.eclipse.jdt.core.ElementChangedEvent;
86 import org.eclipse.jdt.core.IClassFile;
87 import org.eclipse.jdt.core.ICompilationUnit;
88 import org.eclipse.jdt.core.IElementChangedListener;
89 import org.eclipse.jdt.core.IField;
90 import org.eclipse.jdt.core.IInitializer;
91 import org.eclipse.jdt.core.IJavaElement;
92 import org.eclipse.jdt.core.IJavaElementDelta;
93 import org.eclipse.jdt.core.IMember;
94 import org.eclipse.jdt.core.IMethod;
95 import org.eclipse.jdt.core.IParent;
96 import org.eclipse.jdt.core.ISourceRange;
97 import org.eclipse.jdt.core.ISourceReference;
98 import org.eclipse.jdt.core.IType;
99 import org.eclipse.jdt.core.ITypeRoot;
100 import org.eclipse.jdt.core.JavaCore;
101 import org.eclipse.jdt.core.JavaModelException;
102
103 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
104
105 import org.eclipse.jdt.ui.JavaElementComparator;
106 import org.eclipse.jdt.ui.JavaElementLabels;
107 import org.eclipse.jdt.ui.JavaUI;
108 import org.eclipse.jdt.ui.PreferenceConstants;
109 import org.eclipse.jdt.ui.ProblemsLabelDecorator.ProblemsLabelChangedEvent;
110 import org.eclipse.jdt.ui.actions.CCPActionGroup;
111 import org.eclipse.jdt.ui.actions.CustomFiltersActionGroup;
112 import org.eclipse.jdt.ui.actions.GenerateActionGroup;
113 import org.eclipse.jdt.ui.actions.JavaSearchActionGroup;
114 import org.eclipse.jdt.ui.actions.MemberFilterActionGroup;
115 import org.eclipse.jdt.ui.actions.OpenViewActionGroup;
116 import org.eclipse.jdt.ui.actions.RefactorActionGroup;
117
118 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
119 import org.eclipse.jdt.internal.ui.JavaPlugin;
120 import org.eclipse.jdt.internal.ui.JavaPluginImages;
121 import org.eclipse.jdt.internal.ui.actions.AbstractToggleLinkingAction;
122 import org.eclipse.jdt.internal.ui.actions.CategoryFilterActionGroup;
123 import org.eclipse.jdt.internal.ui.actions.CompositeActionGroup;
124 import org.eclipse.jdt.internal.ui.dnd.DelegatingDropAdapter;
125 import org.eclipse.jdt.internal.ui.dnd.JdtViewerDragAdapter;
126 import org.eclipse.jdt.internal.ui.packageview.SelectionTransferDragAdapter;
127 import org.eclipse.jdt.internal.ui.packageview.SelectionTransferDropAdapter;
128 import org.eclipse.jdt.internal.ui.preferences.MembersOrderPreferenceCache;
129 import org.eclipse.jdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
130 import org.eclipse.jdt.internal.ui.viewsupport.ColoredViewersManager;
131 import org.eclipse.jdt.internal.ui.viewsupport.DecoratingJavaLabelProvider;
132 import org.eclipse.jdt.internal.ui.viewsupport.SourcePositionComparator;
133 import org.eclipse.jdt.internal.ui.viewsupport.StatusBarUpdater;
134
135
136 /**
137  * The content outline page of the Java editor. The viewer implements a proprietary
138  * update mechanism based on Java model deltas. It does not react on domain changes.
139  * It is specified to show the content of ICompilationUnits and IClassFiles.
140  * Publishes its context menu under <code>JavaPlugin.getDefault().getPluginId() + ".outline"</code>.
141  */

142 public class JavaOutlinePage extends Page implements IContentOutlinePage, IAdaptable , IPostSelectionProvider {
143
144             static Object JavaDoc[] NO_CHILDREN= new Object JavaDoc[0];
145
146             /**
147              * The element change listener of the java outline viewer.
148              * @see IElementChangedListener
149              */

150             protected class ElementChangedListener implements IElementChangedListener {
151
152                 public void elementChanged(final ElementChangedEvent e) {
153
154                     if (getControl() == null)
155                         return;
156
157                     Display d= getControl().getDisplay();
158                     if (d != null) {
159                         d.asyncExec(new Runnable JavaDoc() {
160                             public void run() {
161                                 ICompilationUnit cu= (ICompilationUnit) fInput;
162                                 IJavaElement base= cu;
163                                 if (fTopLevelTypeOnly) {
164                                     base= cu.findPrimaryType();
165                                     if (base == null) {
166                                         if (fOutlineViewer != null)
167                                             fOutlineViewer.refresh(true);
168                                         return;
169                                     }
170                                 }
171                                 IJavaElementDelta delta= findElement(base, e.getDelta());
172                                 if (delta != null && fOutlineViewer != null) {
173                                     fOutlineViewer.reconcile(delta);
174                                 }
175                             }
176                         });
177                     }
178                 }
179
180                 private boolean isPossibleStructuralChange(IJavaElementDelta cuDelta) {
181                     if (cuDelta.getKind() != IJavaElementDelta.CHANGED) {
182                         return true; // add or remove
183
}
184                     int flags= cuDelta.getFlags();
185                     if ((flags & IJavaElementDelta.F_CHILDREN) != 0) {
186                         return true;
187                     }
188                     return (flags & (IJavaElementDelta.F_CONTENT | IJavaElementDelta.F_FINE_GRAINED)) == IJavaElementDelta.F_CONTENT;
189                 }
190
191                 protected IJavaElementDelta findElement(IJavaElement unit, IJavaElementDelta delta) {
192
193                     if (delta == null || unit == null)
194                         return null;
195
196                     IJavaElement element= delta.getElement();
197
198                     if (unit.equals(element)) {
199                         if (isPossibleStructuralChange(delta)) {
200                             return delta;
201                         }
202                         return null;
203                     }
204
205
206                     if (element.getElementType() > IJavaElement.CLASS_FILE)
207                         return null;
208
209                     IJavaElementDelta[] children= delta.getAffectedChildren();
210                     if (children == null || children.length == 0)
211                         return null;
212
213                     for (int i= 0; i < children.length; i++) {
214                         IJavaElementDelta d= findElement(unit, children[i]);
215                         if (d != null)
216                             return d;
217                     }
218
219                     return null;
220                 }
221             }
222
223             static class NoClassElement extends WorkbenchAdapter implements IAdaptable {
224                 /*
225                  * @see java.lang.Object#toString()
226                  */

227                 public String JavaDoc toString() {
228                     return JavaEditorMessages.JavaOutlinePage_error_NoTopLevelType;
229                 }
230
231                 /*
232                  * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class)
233                  */

234                 public Object JavaDoc getAdapter(Class JavaDoc clas) {
235                     if (clas == IWorkbenchAdapter.class)
236                         return this;
237                     return null;
238                 }
239             }
240
241             /**
242              * Content provider for the children of an ICompilationUnit or
243              * an IClassFile
244              * @see ITreeContentProvider
245              */

246             protected class ChildrenProvider implements ITreeContentProvider {
247
248                 private Object JavaDoc[] NO_CLASS= new Object JavaDoc[] {new NoClassElement()};
249                 private ElementChangedListener fListener;
250
251                 protected boolean matches(IJavaElement element) {
252                     if (element.getElementType() == IJavaElement.METHOD) {
253                         String JavaDoc name= element.getElementName();
254                         return (name != null && name.indexOf('<') >= 0);
255                     }
256                     return false;
257                 }
258
259                 protected IJavaElement[] filter(IJavaElement[] children) {
260                     boolean initializers= false;
261                     for (int i= 0; i < children.length; i++) {
262                         if (matches(children[i])) {
263                             initializers= true;
264                             break;
265                         }
266                     }
267
268                     if (!initializers)
269                         return children;
270
271                     Vector JavaDoc v= new Vector JavaDoc();
272                     for (int i= 0; i < children.length; i++) {
273                         if (matches(children[i]))
274                             continue;
275                         v.addElement(children[i]);
276                     }
277
278                     IJavaElement[] result= new IJavaElement[v.size()];
279                     v.copyInto(result);
280                     return result;
281                 }
282
283                 public Object JavaDoc[] getChildren(Object JavaDoc parent) {
284                     if (parent instanceof IParent) {
285                         IParent c= (IParent) parent;
286                         try {
287                             return filter(c.getChildren());
288                         } catch (JavaModelException x) {
289                             // https://bugs.eclipse.org/bugs/show_bug.cgi?id=38341
290
// don't log NotExist exceptions as this is a valid case
291
// since we might have been posted and the element
292
// removed in the meantime.
293
if (JavaPlugin.isDebug() || !x.isDoesNotExist())
294                                 JavaPlugin.log(x);
295                         }
296                     }
297                     return NO_CHILDREN;
298                 }
299
300                 public Object JavaDoc[] getElements(Object JavaDoc parent) {
301                     if (fTopLevelTypeOnly) {
302                         if (parent instanceof ITypeRoot) {
303                             try {
304                                 IType type= ((ITypeRoot) parent).findPrimaryType();
305                                 return type != null ? type.getChildren() : NO_CLASS;
306                             } catch (JavaModelException e) {
307                                 JavaPlugin.log(e);
308                             }
309                         }
310                     }
311                     return getChildren(parent);
312                 }
313
314                 public Object JavaDoc getParent(Object JavaDoc child) {
315                     if (child instanceof IJavaElement) {
316                         IJavaElement e= (IJavaElement) child;
317                         return e.getParent();
318                     }
319                     return null;
320                 }
321
322                 public boolean hasChildren(Object JavaDoc parent) {
323                     if (parent instanceof IParent) {
324                         IParent c= (IParent) parent;
325                         try {
326                             IJavaElement[] children= filter(c.getChildren());
327                             return (children != null && children.length > 0);
328                         } catch (JavaModelException x) {
329                             // https://bugs.eclipse.org/bugs/show_bug.cgi?id=38341
330
// don't log NotExist exceptions as this is a valid case
331
// since we might have been posted and the element
332
// removed in the meantime.
333
if (JavaPlugin.isDebug() || !x.isDoesNotExist())
334                                 JavaPlugin.log(x);
335                         }
336                     }
337                     return false;
338                 }
339
340                 public boolean isDeleted(Object JavaDoc o) {
341                     return false;
342                 }
343
344                 public void dispose() {
345                     if (fListener != null) {
346                         JavaCore.removeElementChangedListener(fListener);
347                         fListener= null;
348                     }
349                 }
350
351                 /*
352                  * @see IContentProvider#inputChanged(Viewer, Object, Object)
353                  */

354                 public void inputChanged(Viewer viewer, Object JavaDoc oldInput, Object JavaDoc newInput) {
355                     boolean isCU= (newInput instanceof ICompilationUnit);
356
357                     if (isCU && fListener == null) {
358                         fListener= new ElementChangedListener();
359                         JavaCore.addElementChangedListener(fListener);
360                     } else if (!isCU && fListener != null) {
361                         JavaCore.removeElementChangedListener(fListener);
362                         fListener= null;
363                     }
364                 }
365             }
366
367             /**
368              * The tree viewer used for displaying the outline.
369              *
370              * @see TreeViewer
371              */

372             protected class JavaOutlineViewer extends TreeViewer {
373
374                 /**
375                  * Indicates an item which has been reused. At the point of
376                  * its reuse it has been expanded. This field is used to
377                  * communicate between <code>internalExpandToLevel</code> and
378                  * <code>reuseTreeItem</code>.
379                  */

380                 private Item fReusedExpandedItem;
381                 private boolean fReorderedMembers;
382                 private boolean fForceFireSelectionChanged;
383
384                 public JavaOutlineViewer(Tree tree) {
385                     super(tree);
386                     setAutoExpandLevel(ALL_LEVELS);
387                     setUseHashlookup(true);
388                 }
389
390                 /**
391                  * Investigates the given element change event and if affected
392                  * incrementally updates the Java outline.
393                  *
394                  * @param delta the Java element delta used to reconcile the Java outline
395                  */

396                 public void reconcile(IJavaElementDelta delta) {
397                     fReorderedMembers= false;
398                     fForceFireSelectionChanged= false;
399                     if (getComparator() == null) {
400                         if (fTopLevelTypeOnly
401                             && delta.getElement() instanceof IType
402                             && (delta.getKind() & IJavaElementDelta.ADDED) != 0)
403                         {
404                             refresh(true);
405
406                         } else {
407                             Widget w= findItem(fInput);
408                             if (w != null && !w.isDisposed())
409                                 update(w, delta);
410                             if (fForceFireSelectionChanged)
411                                 fireSelectionChanged(new SelectionChangedEvent(getSite().getSelectionProvider(), this.getSelection()));
412                             if (fReorderedMembers) {
413                                 refresh(false);
414                                 fReorderedMembers= false;
415                         }
416                         }
417                     } else {
418                         // just for now
419
refresh(true);
420                     }
421                 }
422
423                 /*
424                  * @see TreeViewer#internalExpandToLevel
425                  */

426                 protected void internalExpandToLevel(Widget node, int level) {
427                     if (node instanceof Item) {
428                         Item i= (Item) node;
429                         if (i.getData() instanceof IJavaElement) {
430                             IJavaElement je= (IJavaElement) i.getData();
431                             if (je.getElementType() == IJavaElement.IMPORT_CONTAINER || isInnerType(je)) {
432                                 if (i != fReusedExpandedItem) {
433                                     setExpanded(i, false);
434                                     return;
435                                 }
436                             }
437                         }
438                     }
439                     super.internalExpandToLevel(node, level);
440                 }
441
442                 protected void reuseTreeItem(Item item, Object JavaDoc element) {
443
444                     // remove children
445
Item[] c= getChildren(item);
446                     if (c != null && c.length > 0) {
447
448                         if (getExpanded(item))
449                             fReusedExpandedItem= item;
450
451                         for (int k= 0; k < c.length; k++) {
452                             if (c[k].getData() != null)
453                                 disassociate(c[k]);
454                             c[k].dispose();
455                         }
456                     }
457
458                     updateItem(item, element);
459                     updatePlus(item, element);
460                     internalExpandToLevel(item, ALL_LEVELS);
461
462                     fReusedExpandedItem= null;
463                     fForceFireSelectionChanged= true;
464                 }
465
466                 protected boolean mustUpdateParent(IJavaElementDelta delta, IJavaElement element) {
467                     if (element instanceof IMethod) {
468                         if ((delta.getKind() & IJavaElementDelta.ADDED) != 0) {
469                             try {
470                                 return ((IMethod)element).isMainMethod();
471                             } catch (JavaModelException e) {
472                                 JavaPlugin.log(e.getStatus());
473                             }
474                         }
475                         return "main".equals(element.getElementName()); //$NON-NLS-1$
476
}
477                     return false;
478                 }
479
480                 /*
481                  * @see org.eclipse.jface.viewers.AbstractTreeViewer#isExpandable(java.lang.Object)
482                  */

483                 public boolean isExpandable(Object JavaDoc element) {
484                     if (hasFilters()) {
485                         return getFilteredChildren(element).length > 0;
486                     }
487                     return super.isExpandable(element);
488                 }
489
490                 protected ISourceRange getSourceRange(IJavaElement element) throws JavaModelException {
491                     if (element instanceof ISourceReference)
492                         return ((ISourceReference) element).getSourceRange();
493                     if (element instanceof IMember && !(element instanceof IInitializer))
494                         return ((IMember) element).getNameRange();
495                     return null;
496                 }
497
498                 protected boolean overlaps(ISourceRange range, int start, int end) {
499                     return start <= (range.getOffset() + range.getLength() - 1) && range.getOffset() <= end;
500                 }
501
502                 protected boolean filtered(IJavaElement parent, IJavaElement child) {
503
504                     Object JavaDoc[] result= new Object JavaDoc[] { child };
505                     ViewerFilter[] filters= getFilters();
506                     for (int i= 0; i < filters.length; i++) {
507                         result= filters[i].filter(this, parent, result);
508                         if (result.length == 0)
509                             return true;
510                     }
511
512                     return false;
513                 }
514
515                 protected void update(Widget w, IJavaElementDelta delta) {
516
517                     Item item;
518
519                     IJavaElement parent= delta.getElement();
520                     IJavaElementDelta[] affected= delta.getAffectedChildren();
521                     Item[] children= getChildren(w);
522
523                     boolean doUpdateParent= false;
524                     boolean doUpdateParentsPlus= false;
525
526                     Vector JavaDoc deletions= new Vector JavaDoc();
527                     Vector JavaDoc additions= new Vector JavaDoc();
528
529                     for (int i= 0; i < affected.length; i++) {
530                         IJavaElementDelta affectedDelta= affected[i];
531                         IJavaElement affectedElement= affectedDelta.getElement();
532                         int status= affected[i].getKind();
533
534                         // find tree item with affected element
535
int j;
536                         for (j= 0; j < children.length; j++)
537                             if (affectedElement.equals(children[j].getData()))
538                                 break;
539
540                         if (j == children.length) {
541                             // remove from collapsed parent
542
if ((status & IJavaElementDelta.REMOVED) != 0) {
543                                 doUpdateParentsPlus= true;
544                                 continue;
545                             }
546                             // addition
547
if ((status & IJavaElementDelta.CHANGED) != 0 &&
548                                 (affectedDelta.getFlags() & IJavaElementDelta.F_MODIFIERS) != 0 &&
549                                 !filtered(parent, affectedElement))
550                             {
551                                 additions.addElement(affectedDelta);
552                             }
553                             continue;
554                         }
555
556                         item= children[j];
557
558                         // removed
559
if ((status & IJavaElementDelta.REMOVED) != 0) {
560                             deletions.addElement(item);
561                             doUpdateParent= doUpdateParent || mustUpdateParent(affectedDelta, affectedElement);
562
563                         // changed
564
} else if ((status & IJavaElementDelta.CHANGED) != 0) {
565                             int change= affectedDelta.getFlags();
566                             doUpdateParent= doUpdateParent || mustUpdateParent(affectedDelta, affectedElement);
567
568                             if ((change & IJavaElementDelta.F_MODIFIERS) != 0) {
569                                 if (filtered(parent, affectedElement))
570                                     deletions.addElement(item);
571                                 else
572                                     updateItem(item, affectedElement);
573                             }
574
575                             if ((change & IJavaElementDelta.F_CONTENT) != 0)
576                                 updateItem(item, affectedElement);
577
578                             if ((change & IJavaElementDelta.F_CATEGORIES) != 0)
579                                 updateItem(item, affectedElement);
580
581                             if ((change & IJavaElementDelta.F_CHILDREN) != 0)
582                                 update(item, affectedDelta);
583
584                             if ((change & IJavaElementDelta.F_REORDER) != 0)
585                                 fReorderedMembers= true;
586                         }
587                     }
588
589                     // find all elements to add
590
IJavaElementDelta[] add= delta.getAddedChildren();
591                     if (additions.size() > 0) {
592                         IJavaElementDelta[] tmp= new IJavaElementDelta[add.length + additions.size()];
593                         System.arraycopy(add, 0, tmp, 0, add.length);
594                         for (int i= 0; i < additions.size(); i++)
595                             tmp[i + add.length]= (IJavaElementDelta) additions.elementAt(i);
596                         add= tmp;
597                     }
598
599                     // add at the right position
600
go2: for (int i= 0; i < add.length; i++) {
601
602                         try {
603
604                             IJavaElement e= add[i].getElement();
605                             if (filtered(parent, e))
606                                 continue go2;
607
608                             doUpdateParent= doUpdateParent || mustUpdateParent(add[i], e);
609                             ISourceRange rng= getSourceRange(e);
610                             int start= rng.getOffset();
611                             int end= start + rng.getLength() - 1;
612                             int nameOffset= Integer.MAX_VALUE;
613                             if (e instanceof IField) {
614                                 ISourceRange nameRange= ((IField) e).getNameRange();
615                                 if (nameRange != null)
616                                     nameOffset= nameRange.getOffset();
617                             }
618
619                             Item last= null;
620                             item= null;
621                             children= getChildren(w);
622
623                             for (int j= 0; j < children.length; j++) {
624                                 item= children[j];
625                                 IJavaElement r= (IJavaElement) item.getData();
626
627                                 if (r == null) {
628                                     // parent node collapsed and not be opened before -> do nothing
629
continue go2;
630                                 }
631
632
633                                 try {
634                                     rng= getSourceRange(r);
635
636                                     // multi-field declarations always start at
637
// the same offset. They also have the same
638
// end offset if the field sequence is terminated
639
// with a semicolon. If not, the source range
640
// ends behind the identifier / initializer
641
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=51851
642
boolean multiFieldDeclaration=
643                                         r.getElementType() == IJavaElement.FIELD
644                                             && e.getElementType() == IJavaElement.FIELD
645                                             && rng.getOffset() == start;
646
647                                     // elements are inserted by occurrence
648
// however, multi-field declarations have
649
// equal source ranges offsets, therefore we
650
// compare name-range offsets.
651
boolean multiFieldOrderBefore= false;
652                                     if (multiFieldDeclaration) {
653                                         if (r instanceof IField) {
654                                             ISourceRange nameRange= ((IField) r).getNameRange();
655                                             if (nameRange != null) {
656                                                 if (nameRange.getOffset() > nameOffset)
657                                                     multiFieldOrderBefore= true;
658                                             }
659                                         }
660                                     }
661
662                                     if (!multiFieldDeclaration && overlaps(rng, start, end)) {
663
664                                         // be tolerant if the delta is not correct, or if
665
// the tree has been updated other than by a delta
666
reuseTreeItem(item, e);
667                                         continue go2;
668
669                                     } else if (multiFieldOrderBefore || rng.getOffset() > start) {
670
671                                         if (last != null && deletions.contains(last)) {
672                                             // reuse item
673
deletions.removeElement(last);
674                                             reuseTreeItem(last, e);
675                                         } else {
676                                             // nothing to reuse
677
createTreeItem(w, e, j);
678                                         }
679                                         continue go2;
680                                     }
681
682                                 } catch (JavaModelException x) {
683                                     // stumbled over deleted element
684
}
685
686                                 last= item;
687                             }
688
689                             // add at the end of the list
690
if (last != null && deletions.contains(last)) {
691                                 // reuse item
692
deletions.removeElement(last);
693                                 reuseTreeItem(last, e);
694                             } else {
695                                 // nothing to reuse
696
createTreeItem(w, e, -1);
697                             }
698
699                         } catch (JavaModelException x) {
700                             // the element to be added is not present -> don't add it
701
}
702                     }
703
704
705                     // remove items which haven't been reused
706
Enumeration JavaDoc e= deletions.elements();
707                     while (e.hasMoreElements()) {
708                         item= (Item) e.nextElement();
709                         disassociate(item);
710                         item.dispose();
711                     }
712
713                     if (doUpdateParent)
714                         updateItem(w, delta.getElement());
715                     if (!doUpdateParent && doUpdateParentsPlus && w instanceof Item)
716                         updatePlus((Item)w, delta.getElement());
717                 }
718
719
720
721                 /*
722                  * @see ContentViewer#handleLabelProviderChanged(LabelProviderChangedEvent)
723                  */

724                 protected void handleLabelProviderChanged(LabelProviderChangedEvent event) {
725                     Object JavaDoc input= getInput();
726                     if (event instanceof ProblemsLabelChangedEvent) {
727                         ProblemsLabelChangedEvent e= (ProblemsLabelChangedEvent) event;
728                         if (e.isMarkerChange() && input instanceof ICompilationUnit) {
729                             return; // marker changes can be ignored
730
}
731                     }
732                     // look if the underlying resource changed
733
Object JavaDoc[] changed= event.getElements();
734                     if (changed != null) {
735                         IResource resource= getUnderlyingResource();
736                         if (resource != null) {
737                             for (int i= 0; i < changed.length; i++) {
738                                 if (changed[i] != null && changed[i].equals(resource)) {
739                                     // change event to a full refresh
740
event= new LabelProviderChangedEvent((IBaseLabelProvider) event.getSource());
741                                     break;
742                                 }
743                             }
744                         }
745                     }
746                     super.handleLabelProviderChanged(event);
747                 }
748
749                 private IResource getUnderlyingResource() {
750                     Object JavaDoc input= getInput();
751                     if (input instanceof ICompilationUnit) {
752                         ICompilationUnit cu= (ICompilationUnit) input;
753                         cu= cu.getPrimary();
754                         return cu.getResource();
755                     } else if (input instanceof IClassFile) {
756                         return ((IClassFile) input).getResource();
757                     }
758                     return null;
759                 }
760
761
762             }
763
764             class LexicalSortingAction extends Action {
765
766                 private JavaElementComparator fComparator= new JavaElementComparator();
767                 private SourcePositionComparator fSourcePositonComparator= new SourcePositionComparator();
768
769                 public LexicalSortingAction() {
770                     super();
771                     PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.LEXICAL_SORTING_OUTLINE_ACTION);
772                     setText(JavaEditorMessages.JavaOutlinePage_Sort_label);
773                     JavaPluginImages.setLocalImageDescriptors(this, "alphab_sort_co.gif"); //$NON-NLS-1$
774
setToolTipText(JavaEditorMessages.JavaOutlinePage_Sort_tooltip);
775                     setDescription(JavaEditorMessages.JavaOutlinePage_Sort_description);
776
777                     boolean checked= JavaPlugin.getDefault().getPreferenceStore().getBoolean("LexicalSortingAction.isChecked"); //$NON-NLS-1$
778
valueChanged(checked, false);
779                 }
780
781                 public void run() {
782                     valueChanged(isChecked(), true);
783                 }
784
785                 private void valueChanged(final boolean on, boolean store) {
786                     setChecked(on);
787                     BusyIndicator.showWhile(fOutlineViewer.getControl().getDisplay(), new Runnable JavaDoc() {
788                         public void run() {
789                             if (on)
790                                 fOutlineViewer.setComparator(fComparator);
791                             else
792                                 fOutlineViewer.setComparator(fSourcePositonComparator);
793                         }
794                     });
795
796                     if (store)
797                         JavaPlugin.getDefault().getPreferenceStore().setValue("LexicalSortingAction.isChecked", on); //$NON-NLS-1$
798
}
799             }
800
801         class ClassOnlyAction extends Action {
802
803             public ClassOnlyAction() {
804                 super();
805                 PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.GO_INTO_TOP_LEVEL_TYPE_ACTION);
806                 setText(JavaEditorMessages.JavaOutlinePage_GoIntoTopLevelType_label);
807                 setToolTipText(JavaEditorMessages.JavaOutlinePage_GoIntoTopLevelType_tooltip);
808                 setDescription(JavaEditorMessages.JavaOutlinePage_GoIntoTopLevelType_description);
809                 JavaPluginImages.setLocalImageDescriptors(this, "gointo_toplevel_type.gif"); //$NON-NLS-1$
810

811                 IPreferenceStore preferenceStore= JavaPlugin.getDefault().getPreferenceStore();
812                 boolean showclass= preferenceStore.getBoolean("GoIntoTopLevelTypeAction.isChecked"); //$NON-NLS-1$
813
setTopLevelTypeOnly(showclass);
814             }
815
816             /*
817              * @see org.eclipse.jface.action.Action#run()
818              */

819             public void run() {
820                 setTopLevelTypeOnly(!fTopLevelTypeOnly);
821             }
822
823             private void setTopLevelTypeOnly(boolean show) {
824                 fTopLevelTypeOnly= show;
825                 setChecked(show);
826                 fOutlineViewer.refresh(false);
827
828                 IPreferenceStore preferenceStore= JavaPlugin.getDefault().getPreferenceStore();
829                 preferenceStore.setValue("GoIntoTopLevelTypeAction.isChecked", show); //$NON-NLS-1$
830
}
831         }
832
833         /**
834          * This action toggles whether this Java Outline page links
835          * its selection to the active editor.
836          *
837          * @since 3.0
838          */

839         public class ToggleLinkingAction extends AbstractToggleLinkingAction {
840
841             JavaOutlinePage fJavaOutlinePage;
842
843             /**
844              * Constructs a new action.
845              *
846              * @param outlinePage the Java outline page
847              */

848             public ToggleLinkingAction(JavaOutlinePage outlinePage) {
849                 boolean isLinkingEnabled= PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE);
850                 setChecked(isLinkingEnabled);
851                 fJavaOutlinePage= outlinePage;
852             }
853
854             /**
855              * Runs the action.
856              */

857             public void run() {
858                 PreferenceConstants.getPreferenceStore().setValue(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE, isChecked());
859                 if (isChecked() && fEditor != null)
860                     fEditor.synchronizeOutlinePage(fEditor.computeHighlightRangeSourceReference(), false);
861             }
862
863         }
864
865         /**
866          * Empty selection provider.
867          *
868          * @since 3.2
869          */

870         private static final class EmptySelectionProvider implements ISelectionProvider {
871             public void addSelectionChangedListener(ISelectionChangedListener listener) {
872             }
873             public ISelection getSelection() {
874                 return StructuredSelection.EMPTY;
875             }
876             public void removeSelectionChangedListener(ISelectionChangedListener listener) {
877             }
878             public void setSelection(ISelection selection) {
879             }
880         }
881
882
883     /** A flag to show contents of top level type only */
884     private boolean fTopLevelTypeOnly;
885
886     private IJavaElement fInput;
887     private String JavaDoc fContextMenuID;
888     private Menu fMenu;
889     private JavaOutlineViewer fOutlineViewer;
890     private JavaEditor fEditor;
891
892     private MemberFilterActionGroup fMemberFilterActionGroup;
893
894     private ListenerList fSelectionChangedListeners= new ListenerList(ListenerList.IDENTITY);
895     private ListenerList fPostSelectionChangedListeners= new ListenerList(ListenerList.IDENTITY);
896     private Hashtable JavaDoc fActions= new Hashtable JavaDoc();
897
898     private TogglePresentationAction fTogglePresentation;
899
900     private ToggleLinkingAction fToggleLinkingAction;
901
902     private CompositeActionGroup fActionGroups;
903
904     private IPropertyChangeListener fPropertyChangeListener;
905     /**
906      * Custom filter action group.
907      * @since 3.0
908      */

909     private CustomFiltersActionGroup fCustomFiltersActionGroup;
910     /**
911      * Category filter action group.
912      * @since 3.2
913      */

914     private CategoryFilterActionGroup fCategoryFilterActionGroup;
915
916     public JavaOutlinePage(String JavaDoc contextMenuID, JavaEditor editor) {
917         super();
918
919         Assert.isNotNull(editor);
920
921         fContextMenuID= contextMenuID;
922         fEditor= editor;
923
924         fTogglePresentation= new TogglePresentationAction();
925         fTogglePresentation.setEditor(editor);
926
927         fPropertyChangeListener= new IPropertyChangeListener() {
928             public void propertyChange(PropertyChangeEvent event) {
929                 doPropertyChange(event);
930             }
931         };
932         JavaPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(fPropertyChangeListener);
933     }
934
935     /* (non-Javadoc)
936      * Method declared on Page
937      */

938     public void init(IPageSite pageSite) {
939         super.init(pageSite);
940     }
941
942     private void doPropertyChange(PropertyChangeEvent event) {
943         if (fOutlineViewer != null) {
944             if (MembersOrderPreferenceCache.isMemberOrderProperty(event.getProperty())) {
945                 fOutlineViewer.refresh(false);
946             }
947         }
948     }
949
950     /*
951      * @see ISelectionProvider#addSelectionChangedListener(ISelectionChangedListener)
952      */

953     public void addSelectionChangedListener(ISelectionChangedListener listener) {
954         if (fOutlineViewer != null)
955             fOutlineViewer.addSelectionChangedListener(listener);
956         else
957             fSelectionChangedListeners.add(listener);
958     }
959
960     /*
961      * @see ISelectionProvider#removeSelectionChangedListener(ISelectionChangedListener)
962      */

963     public void removeSelectionChangedListener(ISelectionChangedListener listener) {
964         if (fOutlineViewer != null)
965             fOutlineViewer.removeSelectionChangedListener(listener);
966         else
967             fSelectionChangedListeners.remove(listener);
968     }
969
970     /*
971      * @see ISelectionProvider#setSelection(ISelection)
972      */

973     public void setSelection(ISelection selection) {
974         if (fOutlineViewer != null)
975             fOutlineViewer.setSelection(selection);
976     }
977
978     /*
979      * @see ISelectionProvider#getSelection()
980      */

981     public ISelection getSelection() {
982         if (fOutlineViewer == null)
983             return StructuredSelection.EMPTY;
984         return fOutlineViewer.getSelection();
985     }
986
987     /*
988      * @see org.eclipse.jface.text.IPostSelectionProvider#addPostSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
989      */

990     public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
991         if (fOutlineViewer != null)
992             fOutlineViewer.addPostSelectionChangedListener(listener);
993         else
994             fPostSelectionChangedListeners.add(listener);
995     }
996
997     /*
998      * @see org.eclipse.jface.text.IPostSelectionProvider#removePostSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
999      */

1000    public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
1001        if (fOutlineViewer != null)
1002            fOutlineViewer.removePostSelectionChangedListener(listener);
1003        else
1004            fPostSelectionChangedListeners.remove(listener);
1005    }
1006
1007    private void registerToolbarActions(IActionBars actionBars) {
1008        IToolBarManager toolBarManager= actionBars.getToolBarManager();
1009        toolBarManager.add(new LexicalSortingAction());
1010
1011        fMemberFilterActionGroup= new MemberFilterActionGroup(fOutlineViewer, "org.eclipse.jdt.ui.JavaOutlinePage"); //$NON-NLS-1$
1012
fMemberFilterActionGroup.contributeToToolBar(toolBarManager);
1013
1014        fCustomFiltersActionGroup.fillActionBars(actionBars);
1015
1016        IMenuManager viewMenuManager= actionBars.getMenuManager();
1017        viewMenuManager.add(new Separator("EndFilterGroup")); //$NON-NLS-1$
1018

1019        fToggleLinkingAction= new ToggleLinkingAction(this);
1020        viewMenuManager.add(new ClassOnlyAction());
1021        viewMenuManager.add(fToggleLinkingAction);
1022
1023        fCategoryFilterActionGroup= new CategoryFilterActionGroup(fOutlineViewer, "org.eclipse.jdt.ui.JavaOutlinePage", new IJavaElement[] {fInput}); //$NON-NLS-1$
1024
fCategoryFilterActionGroup.contributeToViewMenu(viewMenuManager);
1025    }
1026
1027    /*
1028     * @see IPage#createControl
1029     */

1030    public void createControl(Composite parent) {
1031
1032        Tree tree= new Tree(parent, SWT.MULTI);
1033
1034        AppearanceAwareLabelProvider lprovider= new AppearanceAwareLabelProvider(
1035            AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS | JavaElementLabels.F_APP_TYPE_SIGNATURE | JavaElementLabels.ALL_CATEGORY,
1036            AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS
1037        );
1038
1039        fOutlineViewer= new JavaOutlineViewer(tree);
1040        ColoredViewersManager.install(fOutlineViewer);
1041        initDragAndDrop();
1042        fOutlineViewer.setContentProvider(new ChildrenProvider());
1043        fOutlineViewer.setLabelProvider(new DecoratingJavaLabelProvider(lprovider));
1044
1045        Object JavaDoc[] listeners= fSelectionChangedListeners.getListeners();
1046        for (int i= 0; i < listeners.length; i++) {
1047            fSelectionChangedListeners.remove(listeners[i]);
1048            fOutlineViewer.addSelectionChangedListener((ISelectionChangedListener) listeners[i]);
1049        }
1050
1051        listeners= fPostSelectionChangedListeners.getListeners();
1052        for (int i= 0; i < listeners.length; i++) {
1053            fPostSelectionChangedListeners.remove(listeners[i]);
1054            fOutlineViewer.addPostSelectionChangedListener((ISelectionChangedListener) listeners[i]);
1055        }
1056
1057        MenuManager manager= new MenuManager(fContextMenuID, fContextMenuID);
1058        manager.setRemoveAllWhenShown(true);
1059        manager.addMenuListener(new IMenuListener() {
1060            public void menuAboutToShow(IMenuManager m) {
1061                contextMenuAboutToShow(m);
1062            }
1063        });
1064        fMenu= manager.createContextMenu(tree);
1065        tree.setMenu(fMenu);
1066
1067        IPageSite site= getSite();
1068        site.registerContextMenu(JavaPlugin.getPluginId() + ".outline", manager, fOutlineViewer); //$NON-NLS-1$
1069

1070        updateSelectionProvider(site);
1071        
1072        // we must create the groups after we have set the selection provider to the site
1073
fActionGroups= new CompositeActionGroup(new ActionGroup[] {
1074                new OpenViewActionGroup(this),
1075                new CCPActionGroup(this),
1076                new GenerateActionGroup(this),
1077                new RefactorActionGroup(this),
1078                new JavaSearchActionGroup(this)});
1079
1080        // register global actions
1081
IActionBars actionBars= site.getActionBars();
1082        actionBars.setGlobalActionHandler(ITextEditorActionConstants.UNDO, fEditor.getAction(ITextEditorActionConstants.UNDO));
1083        actionBars.setGlobalActionHandler(ITextEditorActionConstants.REDO, fEditor.getAction(ITextEditorActionConstants.REDO));
1084
1085        IAction action= fEditor.getAction(ITextEditorActionConstants.NEXT);
1086        actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.GOTO_NEXT_ANNOTATION, action);
1087        actionBars.setGlobalActionHandler(ITextEditorActionConstants.NEXT, action);
1088        action= fEditor.getAction(ITextEditorActionConstants.PREVIOUS);
1089        actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.GOTO_PREVIOUS_ANNOTATION, action);
1090        actionBars.setGlobalActionHandler(ITextEditorActionConstants.PREVIOUS, action);
1091        
1092        actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.TOGGLE_SHOW_SELECTED_ELEMENT_ONLY, fTogglePresentation);
1093
1094        fActionGroups.fillActionBars(actionBars);
1095
1096        IStatusLineManager statusLineManager= actionBars.getStatusLineManager();
1097        if (statusLineManager != null) {
1098            StatusBarUpdater updater= new StatusBarUpdater(statusLineManager);
1099            fOutlineViewer.addPostSelectionChangedListener(updater);
1100        }
1101        // Custom filter group
1102
fCustomFiltersActionGroup= new CustomFiltersActionGroup("org.eclipse.jdt.ui.JavaOutlinePage", fOutlineViewer); //$NON-NLS-1$
1103

1104        registerToolbarActions(actionBars);
1105
1106        fOutlineViewer.setInput(fInput);
1107    }
1108
1109    /*
1110     * @since 3.2
1111     */

1112    private void updateSelectionProvider(IPageSite site) {
1113        ISelectionProvider provider= fOutlineViewer;
1114        if (fInput != null) {
1115            ICompilationUnit cu= (ICompilationUnit)fInput.getAncestor(IJavaElement.COMPILATION_UNIT);
1116            if (cu != null && !JavaModelUtil.isPrimary(cu))
1117                provider= new EmptySelectionProvider();
1118        }
1119        site.setSelectionProvider(provider);
1120    }
1121
1122    public void dispose() {
1123
1124        if (fEditor == null)
1125            return;
1126
1127        if (fMemberFilterActionGroup != null) {
1128            fMemberFilterActionGroup.dispose();
1129            fMemberFilterActionGroup= null;
1130        }
1131        
1132        if (fCategoryFilterActionGroup != null) {
1133            fCategoryFilterActionGroup.dispose();
1134            fCategoryFilterActionGroup= null;
1135        }
1136
1137        if (fCustomFiltersActionGroup != null) {
1138            fCustomFiltersActionGroup.dispose();
1139            fCustomFiltersActionGroup= null;
1140        }
1141
1142
1143        fEditor.outlinePageClosed();
1144        fEditor= null;
1145
1146        fSelectionChangedListeners.clear();
1147        fSelectionChangedListeners= null;
1148
1149        fPostSelectionChangedListeners.clear();
1150        fPostSelectionChangedListeners= null;
1151
1152        if (fPropertyChangeListener != null) {
1153            JavaPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(fPropertyChangeListener);
1154            fPropertyChangeListener= null;
1155        }
1156
1157        if (fMenu != null && !fMenu.isDisposed()) {
1158            fMenu.dispose();
1159            fMenu= null;
1160        }
1161
1162        if (fActionGroups != null)
1163            fActionGroups.dispose();
1164
1165        fTogglePresentation.setEditor(null);
1166
1167        fOutlineViewer= null;
1168
1169        super.dispose();
1170    }
1171
1172    public Control getControl() {
1173        if (fOutlineViewer != null)
1174            return fOutlineViewer.getControl();
1175        return null;
1176    }
1177
1178    public void setInput(IJavaElement inputElement) {
1179        fInput= inputElement;
1180        if (fOutlineViewer != null) {
1181            fOutlineViewer.setInput(fInput);
1182            updateSelectionProvider(getSite());
1183        }
1184        if (fCategoryFilterActionGroup != null)
1185            fCategoryFilterActionGroup.setInput(new IJavaElement[] {fInput});
1186    }
1187
1188    public void select(ISourceReference reference) {
1189        if (fOutlineViewer != null) {
1190
1191            ISelection s= fOutlineViewer.getSelection();
1192            if (s instanceof IStructuredSelection) {
1193                IStructuredSelection ss= (IStructuredSelection) s;
1194                List JavaDoc elements= ss.toList();
1195                if (!elements.contains(reference)) {
1196                    s= (reference == null ? StructuredSelection.EMPTY : new StructuredSelection(reference));
1197                    fOutlineViewer.setSelection(s, true);
1198                }
1199            }
1200        }
1201    }
1202
1203    public void setAction(String JavaDoc actionID, IAction action) {
1204        Assert.isNotNull(actionID);
1205        if (action == null)
1206            fActions.remove(actionID);
1207        else
1208            fActions.put(actionID, action);
1209    }
1210
1211    public IAction getAction(String JavaDoc actionID) {
1212        Assert.isNotNull(actionID);
1213        return (IAction) fActions.get(actionID);
1214    }
1215
1216    /*
1217     * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
1218     */

1219    public Object JavaDoc getAdapter(Class JavaDoc key) {
1220        if (key == IShowInSource.class) {
1221            return getShowInSource();
1222        }
1223        if (key == IShowInTargetList.class) {
1224            return new IShowInTargetList() {
1225                public String JavaDoc[] getShowInTargetIds() {
1226                    return new String JavaDoc[] { JavaUI.ID_PACKAGES };
1227                }
1228
1229            };
1230        }
1231        if (key == IShowInTarget.class) {
1232            return getShowInTarget();
1233        }
1234
1235        return null;
1236    }
1237
1238    /**
1239     * Convenience method to add the action installed under the given actionID to the
1240     * specified group of the menu.
1241     *
1242     * @param menu the menu manager
1243     * @param group the group to which to add the action
1244     * @param actionID the ID of the new action
1245     */

1246    protected void addAction(IMenuManager menu, String JavaDoc group, String JavaDoc actionID) {
1247        IAction action= getAction(actionID);
1248        if (action != null) {
1249            if (action instanceof IUpdate)
1250                ((IUpdate) action).update();
1251
1252            if (action.isEnabled()) {
1253                IMenuManager subMenu= menu.findMenuUsingPath(group);
1254                if (subMenu != null)
1255                    subMenu.add(action);
1256                else
1257                    menu.appendToGroup(group, action);
1258            }
1259        }
1260    }
1261
1262    protected void contextMenuAboutToShow(IMenuManager menu) {
1263
1264        JavaPlugin.createStandardGroups(menu);
1265
1266        IStructuredSelection selection= (IStructuredSelection)getSelection();
1267        fActionGroups.setContext(new ActionContext(selection));
1268        fActionGroups.fillContextMenu(menu);
1269    }
1270
1271    /*
1272     * @see Page#setFocus()
1273     */

1274    public void setFocus() {
1275        if (fOutlineViewer != null)
1276            fOutlineViewer.getControl().setFocus();
1277    }
1278
1279    /**
1280     * Checks whether a given Java element is an inner type.
1281     *
1282     * @param element the java element
1283     * @return <code>true</code> iff the given element is an inner type
1284     */

1285    private boolean isInnerType(IJavaElement element) {
1286
1287        if (element != null && element.getElementType() == IJavaElement.TYPE) {
1288            IType type= (IType)element;
1289            try {
1290                return type.isMember();
1291            } catch (JavaModelException e) {
1292                IJavaElement parent= type.getParent();
1293                if (parent != null) {
1294                    int parentElementType= parent.getElementType();
1295                    return (parentElementType != IJavaElement.COMPILATION_UNIT && parentElementType != IJavaElement.CLASS_FILE);
1296                }
1297            }
1298        }
1299
1300        return false;
1301    }
1302
1303    /**
1304     * Returns the <code>IShowInSource</code> for this view.
1305     *
1306     * @return the {@link IShowInSource}
1307     */

1308    protected IShowInSource getShowInSource() {
1309        return new IShowInSource() {
1310            public ShowInContext getShowInContext() {
1311                return new ShowInContext(
1312                    null,
1313                    getSite().getSelectionProvider().getSelection());
1314            }
1315        };
1316    }
1317
1318    /**
1319     * Returns the <code>IShowInTarget</code> for this view.
1320     *
1321     * @return the {@link IShowInTarget}
1322     */

1323    protected IShowInTarget getShowInTarget() {
1324        return new IShowInTarget() {
1325            public boolean show(ShowInContext context) {
1326                ISelection sel= context.getSelection();
1327                if (sel instanceof ITextSelection) {
1328                    ITextSelection tsel= (ITextSelection) sel;
1329                    int offset= tsel.getOffset();
1330                    IJavaElement element= fEditor.getElementAt(offset);
1331                    if (element != null) {
1332                        setSelection(new StructuredSelection(element));
1333                        return true;
1334                    }
1335                } else if (sel instanceof IStructuredSelection) {
1336                    setSelection(sel);
1337                    return true;
1338                }
1339                return false;
1340            }
1341        };
1342    }
1343
1344    private void initDragAndDrop() {
1345        int ops= DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
1346        Transfer[] transfers= new Transfer[] {
1347            LocalSelectionTransfer.getInstance()
1348            };
1349
1350        // Drop Adapter
1351
TransferDropTargetListener[] dropListeners= new TransferDropTargetListener[] {
1352            new SelectionTransferDropAdapter(fOutlineViewer)
1353        };
1354        fOutlineViewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, new DelegatingDropAdapter(dropListeners));
1355
1356        // Drag Adapter
1357
TransferDragSourceListener[] dragListeners= new TransferDragSourceListener[] {
1358            new SelectionTransferDragAdapter(fOutlineViewer)
1359        };
1360        fOutlineViewer.addDragSupport(ops, transfers, new JdtViewerDragAdapter(fOutlineViewer, dragListeners));
1361    }
1362    
1363    /**
1364     * Returns whether only the contents of the top level type is to be shown.
1365     *
1366     * @return <code>true</code> if only the contents of the top level type is to be shown.
1367     * @since 3.3
1368     */

1369    protected final boolean isTopLevelTypeOnly() {
1370        return fTopLevelTypeOnly;
1371    }
1372    
1373    /**
1374     * Returns the <code>JavaOutlineViewer</code> of this view.
1375     *
1376     * @return the {@link JavaOutlineViewer}
1377     * @since 3.3
1378     */

1379    protected final JavaOutlineViewer getOutlineViewer() {
1380        return fOutlineViewer;
1381    }
1382}
1383
Popular Tags