1 11 package org.eclipse.jdt.internal.ui.javaeditor; 12 13 14 import java.util.Enumeration ; 15 import java.util.Hashtable ; 16 import java.util.List ; 17 import java.util.Vector ; 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 142 public class JavaOutlinePage extends Page implements IContentOutlinePage, IAdaptable , IPostSelectionProvider { 143 144 static Object [] NO_CHILDREN= new Object [0]; 145 146 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 () { 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; } 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 227 public String toString() { 228 return JavaEditorMessages.JavaOutlinePage_error_NoTopLevelType; 229 } 230 231 234 public Object getAdapter(Class clas) { 235 if (clas == IWorkbenchAdapter.class) 236 return this; 237 return null; 238 } 239 } 240 241 246 protected class ChildrenProvider implements ITreeContentProvider { 247 248 private Object [] NO_CLASS= new Object [] {new NoClassElement()}; 249 private ElementChangedListener fListener; 250 251 protected boolean matches(IJavaElement element) { 252 if (element.getElementType() == IJavaElement.METHOD) { 253 String 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 v= new Vector (); 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 [] getChildren(Object parent) { 284 if (parent instanceof IParent) { 285 IParent c= (IParent) parent; 286 try { 287 return filter(c.getChildren()); 288 } catch (JavaModelException x) { 289 if (JavaPlugin.isDebug() || !x.isDoesNotExist()) 294 JavaPlugin.log(x); 295 } 296 } 297 return NO_CHILDREN; 298 } 299 300 public Object [] getElements(Object 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 getParent(Object 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 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 if (JavaPlugin.isDebug() || !x.isDoesNotExist()) 334 JavaPlugin.log(x); 335 } 336 } 337 return false; 338 } 339 340 public boolean isDeleted(Object 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 354 public void inputChanged(Viewer viewer, Object oldInput, Object 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 372 protected class JavaOutlineViewer extends TreeViewer { 373 374 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 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 refresh(true); 420 } 421 } 422 423 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 element) { 443 444 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()); } 477 return false; 478 } 479 480 483 public boolean isExpandable(Object 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 [] result= new Object [] { 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 deletions= new Vector (); 527 Vector additions= new Vector (); 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 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 if ((status & IJavaElementDelta.REMOVED) != 0) { 543 doUpdateParentsPlus= true; 544 continue; 545 } 546 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 if ((status & IJavaElementDelta.REMOVED) != 0) { 560 deletions.addElement(item); 561 doUpdateParent= doUpdateParent || mustUpdateParent(affectedDelta, affectedElement); 562 563 } 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 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 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 continue go2; 630 } 631 632 633 try { 634 rng= getSourceRange(r); 635 636 boolean multiFieldDeclaration= 643 r.getElementType() == IJavaElement.FIELD 644 && e.getElementType() == IJavaElement.FIELD 645 && rng.getOffset() == start; 646 647 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 reuseTreeItem(item, e); 667 continue go2; 668 669 } else if (multiFieldOrderBefore || rng.getOffset() > start) { 670 671 if (last != null && deletions.contains(last)) { 672 deletions.removeElement(last); 674 reuseTreeItem(last, e); 675 } else { 676 createTreeItem(w, e, j); 678 } 679 continue go2; 680 } 681 682 } catch (JavaModelException x) { 683 } 685 686 last= item; 687 } 688 689 if (last != null && deletions.contains(last)) { 691 deletions.removeElement(last); 693 reuseTreeItem(last, e); 694 } else { 695 createTreeItem(w, e, -1); 697 } 698 699 } catch (JavaModelException x) { 700 } 702 } 703 704 705 Enumeration 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 724 protected void handleLabelProviderChanged(LabelProviderChangedEvent event) { 725 Object input= getInput(); 726 if (event instanceof ProblemsLabelChangedEvent) { 727 ProblemsLabelChangedEvent e= (ProblemsLabelChangedEvent) event; 728 if (e.isMarkerChange() && input instanceof ICompilationUnit) { 729 return; } 731 } 732 Object [] 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 event= new LabelProviderChangedEvent((IBaseLabelProvider) event.getSource()); 741 break; 742 } 743 } 744 } 745 } 746 super.handleLabelProviderChanged(event); 747 } 748 749 private IResource getUnderlyingResource() { 750 Object 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"); setToolTipText(JavaEditorMessages.JavaOutlinePage_Sort_tooltip); 775 setDescription(JavaEditorMessages.JavaOutlinePage_Sort_description); 776 777 boolean checked= JavaPlugin.getDefault().getPreferenceStore().getBoolean("LexicalSortingAction.isChecked"); 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 () { 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); } 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"); 811 IPreferenceStore preferenceStore= JavaPlugin.getDefault().getPreferenceStore(); 812 boolean showclass= preferenceStore.getBoolean("GoIntoTopLevelTypeAction.isChecked"); setTopLevelTypeOnly(showclass); 814 } 815 816 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); } 831 } 832 833 839 public class ToggleLinkingAction extends AbstractToggleLinkingAction { 840 841 JavaOutlinePage fJavaOutlinePage; 842 843 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 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 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 884 private boolean fTopLevelTypeOnly; 885 886 private IJavaElement fInput; 887 private String 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 fActions= new Hashtable (); 897 898 private TogglePresentationAction fTogglePresentation; 899 900 private ToggleLinkingAction fToggleLinkingAction; 901 902 private CompositeActionGroup fActionGroups; 903 904 private IPropertyChangeListener fPropertyChangeListener; 905 909 private CustomFiltersActionGroup fCustomFiltersActionGroup; 910 914 private CategoryFilterActionGroup fCategoryFilterActionGroup; 915 916 public JavaOutlinePage(String 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 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 953 public void addSelectionChangedListener(ISelectionChangedListener listener) { 954 if (fOutlineViewer != null) 955 fOutlineViewer.addSelectionChangedListener(listener); 956 else 957 fSelectionChangedListeners.add(listener); 958 } 959 960 963 public void removeSelectionChangedListener(ISelectionChangedListener listener) { 964 if (fOutlineViewer != null) 965 fOutlineViewer.removeSelectionChangedListener(listener); 966 else 967 fSelectionChangedListeners.remove(listener); 968 } 969 970 973 public void setSelection(ISelection selection) { 974 if (fOutlineViewer != null) 975 fOutlineViewer.setSelection(selection); 976 } 977 978 981 public ISelection getSelection() { 982 if (fOutlineViewer == null) 983 return StructuredSelection.EMPTY; 984 return fOutlineViewer.getSelection(); 985 } 986 987 990 public void addPostSelectionChangedListener(ISelectionChangedListener listener) { 991 if (fOutlineViewer != null) 992 fOutlineViewer.addPostSelectionChangedListener(listener); 993 else 994 fPostSelectionChangedListeners.add(listener); 995 } 996 997 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"); fMemberFilterActionGroup.contributeToToolBar(toolBarManager); 1013 1014 fCustomFiltersActionGroup.fillActionBars(actionBars); 1015 1016 IMenuManager viewMenuManager= actionBars.getMenuManager(); 1017 viewMenuManager.add(new Separator("EndFilterGroup")); 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}); fCategoryFilterActionGroup.contributeToViewMenu(viewMenuManager); 1025 } 1026 1027 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 [] 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); 1070 updateSelectionProvider(site); 1071 1072 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 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 fCustomFiltersActionGroup= new CustomFiltersActionGroup("org.eclipse.jdt.ui.JavaOutlinePage", fOutlineViewer); 1104 registerToolbarActions(actionBars); 1105 1106 fOutlineViewer.setInput(fInput); 1107 } 1108 1109 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 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 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 actionID) { 1212 Assert.isNotNull(actionID); 1213 return (IAction) fActions.get(actionID); 1214 } 1215 1216 1219 public Object getAdapter(Class key) { 1220 if (key == IShowInSource.class) { 1221 return getShowInSource(); 1222 } 1223 if (key == IShowInTargetList.class) { 1224 return new IShowInTargetList() { 1225 public String [] getShowInTargetIds() { 1226 return new String [] { JavaUI.ID_PACKAGES }; 1227 } 1228 1229 }; 1230 } 1231 if (key == IShowInTarget.class) { 1232 return getShowInTarget(); 1233 } 1234 1235 return null; 1236 } 1237 1238 1246 protected void addAction(IMenuManager menu, String group, String 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 1274 public void setFocus() { 1275 if (fOutlineViewer != null) 1276 fOutlineViewer.getControl().setFocus(); 1277 } 1278 1279 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 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 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 TransferDropTargetListener[] dropListeners= new TransferDropTargetListener[] { 1352 new SelectionTransferDropAdapter(fOutlineViewer) 1353 }; 1354 fOutlineViewer.addDropSupport(ops | DND.DROP_DEFAULT, transfers, new DelegatingDropAdapter(dropListeners)); 1355 1356 TransferDragSourceListener[] dragListeners= new TransferDragSourceListener[] { 1358 new SelectionTransferDragAdapter(fOutlineViewer) 1359 }; 1360 fOutlineViewer.addDragSupport(ops, transfers, new JdtViewerDragAdapter(fOutlineViewer, dragListeners)); 1361 } 1362 1363 1369 protected final boolean isTopLevelTypeOnly() { 1370 return fTopLevelTypeOnly; 1371 } 1372 1373 1379 protected final JavaOutlineViewer getOutlineViewer() { 1380 return fOutlineViewer; 1381 } 1382} 1383 | Popular Tags |