1 12 package org.eclipse.ui.internal; 13 14 import java.util.ArrayList ; 15 import java.util.Arrays ; 16 import java.util.HashMap ; 17 import java.util.HashSet ; 18 import java.util.Iterator ; 19 import java.util.List ; 20 import java.util.Map ; 21 import java.util.Set ; 22 23 import org.eclipse.core.runtime.Assert; 24 import org.eclipse.core.runtime.IStatus; 25 import org.eclipse.core.runtime.ListenerList; 26 import org.eclipse.core.runtime.Status; 27 import org.eclipse.jface.action.ContributionItem; 28 import org.eclipse.jface.action.IMenuManager; 29 import org.eclipse.jface.preference.IPreferenceStore; 30 import org.eclipse.jface.util.Geometry; 31 import org.eclipse.osgi.util.NLS; 32 import org.eclipse.swt.graphics.Cursor; 33 import org.eclipse.swt.graphics.Point; 34 import org.eclipse.swt.graphics.Rectangle; 35 import org.eclipse.swt.widgets.Composite; 36 import org.eclipse.swt.widgets.Control; 37 import org.eclipse.swt.widgets.Display; 38 import org.eclipse.ui.IEditorInput; 39 import org.eclipse.ui.IMemento; 40 import org.eclipse.ui.IPersistable; 41 import org.eclipse.ui.IPropertyListener; 42 import org.eclipse.ui.IWorkbenchPartReference; 43 import org.eclipse.ui.IWorkbenchPreferenceConstants; 44 import org.eclipse.ui.PartInitException; 45 import org.eclipse.ui.PlatformUI; 46 import org.eclipse.ui.XMLMemento; 47 import org.eclipse.ui.internal.StartupThreading.StartupRunnable; 48 import org.eclipse.ui.internal.dnd.AbstractDropTarget; 49 import org.eclipse.ui.internal.dnd.DragUtil; 50 import org.eclipse.ui.internal.dnd.IDropTarget; 51 import org.eclipse.ui.internal.dnd.SwtUtil; 52 import org.eclipse.ui.internal.intro.IIntroConstants; 53 import org.eclipse.ui.internal.layout.ITrimManager; 54 import org.eclipse.ui.internal.layout.IWindowTrim; 55 import org.eclipse.ui.internal.presentations.PresentablePart; 56 import org.eclipse.ui.internal.presentations.PresentationFactoryUtil; 57 import org.eclipse.ui.internal.presentations.PresentationSerializer; 58 import org.eclipse.ui.internal.util.PrefUtil; 59 import org.eclipse.ui.internal.util.Util; 60 import org.eclipse.ui.presentations.AbstractPresentationFactory; 61 import org.eclipse.ui.presentations.IPresentablePart; 62 import org.eclipse.ui.presentations.IStackPresentationSite; 63 import org.eclipse.ui.presentations.StackDropResult; 64 import org.eclipse.ui.presentations.StackPresentation; 65 66 72 public abstract class PartStack extends LayoutPart implements ILayoutContainer { 73 74 public static final int PROP_SELECTION = 0x42; 75 76 private List children = new ArrayList (3); 77 private boolean isActive = true; 78 private ArrayList presentableParts = new ArrayList (); 79 80 private Map properties = new HashMap (); 81 82 protected int appearance = PresentationFactoryUtil.ROLE_VIEW; 83 84 90 private LayoutPart requestedCurrent; 91 92 99 private LayoutPart current; 100 101 109 private PresentablePart presentationCurrent; 110 111 private boolean ignoreSelectionChanges = false; 112 113 protected IMemento savedPresentationState = null; 114 115 protected DefaultStackPresentationSite presentationSite = new DefaultStackPresentationSite() { 116 117 public void close(IPresentablePart part) { 118 PartStack.this.close(part); 119 } 120 121 public void close(IPresentablePart[] parts) { 122 PartStack.this.close(parts); 123 } 124 125 public void dragStart(IPresentablePart beingDragged, 126 Point initialLocation, boolean keyboard) { 127 PartStack.this.dragStart(beingDragged, initialLocation, keyboard); 128 } 129 130 public void dragStart(Point initialLocation, boolean keyboard) { 131 PartStack.this.dragStart(null, initialLocation, keyboard); 132 } 133 134 public boolean isPartMoveable(IPresentablePart part) { 135 return PartStack.this.isMoveable(part); 136 } 137 138 public void selectPart(IPresentablePart toSelect) { 139 PartStack.this.presentationSelectionChanged(toSelect); 140 } 141 142 public boolean supportsState(int state) { 143 return PartStack.this.supportsState(state); 144 } 145 146 public void setState(int newState) { 147 PartStack.this.setState(newState); 148 } 149 150 public IPresentablePart getSelectedPart() { 151 return PartStack.this.getSelectedPart(); 152 } 153 154 public void addSystemActions(IMenuManager menuManager) { 155 PartStack.this.addSystemActions(menuManager); 156 } 157 158 public boolean isStackMoveable() { 159 return canMoveFolder(); 160 } 161 162 public void flushLayout() { 163 PartStack.this.flushLayout(); 164 } 165 166 public IPresentablePart[] getPartList() { 167 List parts = getPresentableParts(); 168 169 return (IPresentablePart[]) parts.toArray(new IPresentablePart[parts.size()]); 170 } 171 172 public String getProperty(String id) { 173 return PartStack.this.getProperty(id); 174 } 175 }; 176 177 private static final class PartStackDropResult extends AbstractDropTarget { 178 private PartPane pane; 179 180 private StackDropResult dropResult; 183 private PartStack stack; 184 185 195 public void setTarget(PartStack stack, PartPane pane, StackDropResult result) { 196 this.pane = pane; 197 this.dropResult = result; 198 this.stack = stack; 199 } 200 201 public void drop() { 202 205 Object cookie = null; 206 if (dropResult != null) { 207 cookie = dropResult.getCookie(); 208 } 209 210 if (pane instanceof EditorPane) { 212 if (pane.getWorkbenchWindow() != stack.getWorkbenchWindow()) { 213 EditorPane editor = (EditorPane) pane; 214 try { 215 IEditorInput input = editor.getEditorReference().getEditorInput(); 216 217 boolean editorClosed = editor.getPage().closeEditor(editor.getEditorReference(), true); 219 220 if (editorClosed) 222 stack.getPage().openEditor(input, editor.getEditorReference().getId()); 223 return; 224 } catch (PartInitException e) { 225 e.printStackTrace(); 226 } 227 228 } 229 } 230 231 if (pane.getContainer() != stack) { 232 stack.derefPart(pane); 234 pane.reparent(stack.getParent()); 235 stack.add(pane, cookie); 236 stack.setSelection(pane); 237 pane.setFocus(); 238 } else if (cookie != null) { 239 stack.getPresentation().movePart(stack.getPresentablePart(pane), cookie); 241 } 242 } 243 244 public Cursor getCursor() { 245 return DragCursors.getCursor(DragCursors.CENTER); 246 } 247 248 public Rectangle getSnapRectangle() { 249 if (dropResult == null) { 250 return DragUtil.getDisplayBounds(stack.getControl()); 251 } 252 return dropResult.getSnapRectangle(); 253 } 254 } 255 256 private static final PartStackDropResult dropResult = new PartStackDropResult(); 257 258 protected boolean isMinimized; 259 260 private ListenerList listeners = new ListenerList(); 261 262 266 private AbstractPresentationFactory factory; 267 268 private boolean smartZoomed = false; 269 private boolean doingUnzoom = false; 270 271 protected abstract boolean isMoveable(IPresentablePart part); 272 273 protected abstract void addSystemActions(IMenuManager menuManager); 274 275 protected abstract boolean supportsState(int newState); 276 277 protected abstract boolean canMoveFolder(); 278 279 protected abstract void derefPart(LayoutPart toDeref); 280 281 protected abstract boolean allowsDrop(PartPane part); 282 283 protected static void appendToGroupIfPossible(IMenuManager m, 284 String groupId, ContributionItem item) { 285 try { 286 m.appendToGroup(groupId, item); 287 } catch (IllegalArgumentException e) { 288 m.add(item); 289 } 290 } 291 292 297 public PartStack(int appearance) { 298 this(appearance, null); 299 } 300 301 306 public PartStack(int appearance, AbstractPresentationFactory factory) { 307 super("PartStack"); 309 this.appearance = appearance; 310 this.factory = factory; 311 } 312 313 319 public void addListener(IPropertyListener listener) { 320 listeners.add(listener); 321 } 322 323 public void removeListener(IPropertyListener listener) { 324 listeners.remove(listener); 325 } 326 327 protected final boolean isStandalone() { 328 return (appearance == PresentationFactoryUtil.ROLE_STANDALONE 329 || appearance == PresentationFactoryUtil.ROLE_STANDALONE_NOTITLE); 330 } 331 332 337 protected IPresentablePart getSelectedPart() { 338 return presentationCurrent; 339 } 340 341 protected IStackPresentationSite getPresentationSite() { 342 return presentationSite; 343 } 344 345 349 public void testInvariants() { 350 Control focusControl = Display.getCurrent().getFocusControl(); 351 352 boolean currentFound = false; 353 354 LayoutPart[] children = getChildren(); 355 356 for (int idx = 0; idx < children.length; idx++) { 357 LayoutPart child = children[idx]; 358 359 Assert.isNotNull(child, 361 "null children are not allowed in PartStack"); 363 Assert.isTrue(child instanceof PartPlaceholder 365 || child instanceof PartPane, 366 "PartStack can only contain PartPlaceholders or PartPanes"); 368 IPresentablePart part = getPresentablePart(child); 370 if (child instanceof PartPane) { 371 Assert.isNotNull(part, 372 "All PartPanes must have a non-null IPresentablePart"); } 374 375 ILayoutContainer childContainer = child.getContainer(); 377 378 if (!(child instanceof PartPlaceholder)) { 382 383 if (isDisposed()) { 384 385 if (childContainer != null) { 389 Assert 390 .isTrue(childContainer == this, 391 "PartStack has a child that thinks it has a different parent"); } 393 } else { 394 Assert 396 .isTrue(childContainer == this, 397 "PartStack has a child that thinks it has a different parent"); 399 402 if (SwtUtil.isChild(child.getControl(), focusControl)) { 403 Assert.isTrue(child == current, 404 "The part with focus is not the selected part"); } 408 } 409 } 410 411 if (child == current) { 413 currentFound = true; 414 } 415 416 child.testInvariants(); 418 } 419 420 if (!isDisposed() && getPresentableParts().size() > 0) { 422 Assert.isTrue(currentFound); 423 424 if (!isDisposed()) { 425 StackPresentation presentation = getPresentation(); 426 427 if (SwtUtil.isChild(presentation.getControl(), focusControl)) { 429 Assert 430 .isTrue( 431 getActive() == StackPresentation.AS_ACTIVE_FOCUS, 432 "The presentation has focus but does not have the active appearance"); } 434 } 435 } 436 437 Assert.isTrue((getState() == IStackPresentationSite.STATE_MAXIMIZED) 439 == (getContainer() != null && getContainer().childIsZoomed(this))); 440 441 } 442 443 446 public void describeLayout(StringBuffer buf) { 447 int activeState = getActive(); 448 if (activeState == StackPresentation.AS_ACTIVE_FOCUS) { 449 buf.append("active "); } else if (activeState == StackPresentation.AS_ACTIVE_NOFOCUS) { 451 buf.append("active_nofocus "); } 453 454 buf.append("("); 456 LayoutPart[] children = ((ILayoutContainer) this).getChildren(); 457 458 int visibleChildren = 0; 459 460 for (int idx = 0; idx < children.length; idx++) { 461 462 LayoutPart next = children[idx]; 463 if (!(next instanceof PartPlaceholder)) { 464 if (idx > 0) { 465 buf.append(", "); } 467 468 if (next == requestedCurrent) { 469 buf.append("*"); } 471 472 next.describeLayout(buf); 473 474 visibleChildren++; 475 } 476 } 477 478 buf.append(")"); } 480 481 484 public void add(LayoutPart child) { 485 add(child, null); 486 } 487 488 491 protected void add(LayoutPart newChild, Object cookie) { 492 children.add(newChild); 493 494 if(!(newChild.getContainer() instanceof ContainerPlaceholder)) { 496 newChild.setContainer(this); 497 } 498 499 showPart(newChild, cookie); 500 } 501 502 public boolean allowsAdd(LayoutPart toAdd) { 503 return !isStandalone(); 504 } 505 506 511 public boolean allowsAutoFocus() { 512 if (presentationSite.getState() == IStackPresentationSite.STATE_MINIMIZED) { 513 return false; 514 } 515 516 return super.allowsAutoFocus(); 517 } 518 519 522 protected void close(IPresentablePart[] parts) { 523 for (int idx = 0; idx < parts.length; idx++) { 524 IPresentablePart part = parts[idx]; 525 526 close(part); 527 } 528 } 529 530 533 protected void close(IPresentablePart part) { 534 if (!presentationSite.isCloseable(part)) { 535 return; 536 } 537 538 LayoutPart layoutPart = getPaneFor(part); 539 540 if (layoutPart != null && layoutPart instanceof PartPane) { 541 PartPane viewPane = (PartPane) layoutPart; 542 543 viewPane.doHide(); 544 } 545 } 546 547 public boolean isDisposed() { 548 return getPresentation() == null; 549 } 550 551 protected AbstractPresentationFactory getFactory() { 552 553 if (factory != null) { 554 return factory; 555 } 556 557 return ((WorkbenchWindow) getPage() 558 .getWorkbenchWindow()).getWindowConfigurer() 559 .getPresentationFactory(); 560 } 561 562 public void createControl(Composite parent) { 563 if (!isDisposed()) { 564 return; 565 } 566 567 AbstractPresentationFactory factory = getFactory(); 568 569 PresentationSerializer serializer = new PresentationSerializer( 570 getPresentableParts()); 571 572 StackPresentation presentation = PresentationFactoryUtil 573 .createPresentation(factory, appearance, parent, 574 presentationSite, serializer, savedPresentationState); 575 576 createControl(parent, presentation); 577 getControl().moveBelow(null); 578 } 579 580 583 public IDropTarget getDropTarget(Object draggedObject, Point position) { 584 585 if (!(draggedObject instanceof PartPane)) { 586 return null; 587 } 588 589 final PartPane pane = (PartPane) draggedObject; 590 if (isStandalone() 591 || !allowsDrop(pane)) { 592 return null; 593 } 594 595 boolean differentWindows = pane.getWorkbenchWindow() != getWorkbenchWindow(); 597 boolean editorDropOK = ((pane instanceof EditorPane) && 598 pane.getWorkbenchWindow().getWorkbench() == 599 getWorkbenchWindow().getWorkbench()); 600 if (differentWindows && !editorDropOK) { 601 return null; 602 } 603 604 StackDropResult dropResult = getPresentation().dragOver( 605 getControl(), position); 606 607 if (dropResult == null) { 608 return null; 609 } 610 611 return createDropTarget(pane, dropResult); 612 } 613 614 public void setActive(boolean isActive) { 615 616 this.isActive = isActive; 617 Iterator iter = children.iterator(); 619 while (iter.hasNext()) { 620 LayoutPart part = (LayoutPart) iter.next(); 621 622 part.setContainer(isActive ? this : null); 623 } 624 625 for (Iterator iterator = presentableParts.iterator(); iterator.hasNext();) { 626 PresentablePart next = (PresentablePart) iterator.next(); 627 628 next.enableInputs(isActive); 629 next.enableOutputs(isActive); 630 } 631 } 632 633 public void createControl(Composite parent, StackPresentation presentation) { 634 635 Assert.isTrue(isDisposed()); 636 637 if (presentationSite.getPresentation() != null) { 638 return; 639 } 640 641 presentationSite.setPresentation(presentation); 642 643 LayoutPart[] childParts = (LayoutPart[]) children.toArray(new LayoutPart[children.size()]); 647 for (int i = 0; i < childParts.length; i++) { 648 LayoutPart part = childParts[i]; 649 showPart(part, null); 650 } 651 652 if (savedPresentationState!=null) { 653 PresentationSerializer serializer = new PresentationSerializer( 654 getPresentableParts()); 655 presentation.restoreState(serializer, savedPresentationState); 656 } 657 658 Control ctrl = getPresentation().getControl(); 659 660 ctrl.setData(this); 661 662 if (requestedCurrent instanceof PartPlaceholder) { 664 requestedCurrent = null; 665 updateContainerVisibleTab(); 666 } 667 668 refreshPresentationSelection(); 669 } 670 671 public IDropTarget createDropTarget(PartPane pane, StackDropResult result) { 672 dropResult.setTarget(this, pane, result); 673 return dropResult; 674 } 675 676 680 protected void savePresentationState() { 681 if (isDisposed()) { 682 return; 683 } 684 685 { XMLMemento memento = XMLMemento 687 .createWriteRoot(IWorkbenchConstants.TAG_PRESENTATION); 688 memento.putString(IWorkbenchConstants.TAG_ID, getFactory().getId()); 689 690 PresentationSerializer serializer = new PresentationSerializer( 691 getPresentableParts()); 692 693 getPresentation().saveState(serializer, memento); 694 695 savedPresentationState = memento; 697 } 698 } 699 700 703 public void dispose() { 704 705 if (isDisposed()) { 706 return; 707 } 708 709 savePresentationState(); 710 711 presentationSite.dispose(); 712 713 for (Iterator iter = presentableParts.iterator(); iter.hasNext();) { 714 PresentablePart part = (PresentablePart) iter.next(); 715 716 part.dispose(); 717 } 718 presentableParts.clear(); 719 720 presentationCurrent = null; 721 current = null; 722 fireInternalPropertyChange(PROP_SELECTION); 723 } 724 725 public void findSashes(LayoutPart part, PartPane.Sashes sashes) { 726 ILayoutContainer container = getContainer(); 727 728 if (container != null) { 729 container.findSashes(this, sashes); 730 } 731 } 732 733 736 public Rectangle getBounds() { 737 if (getPresentation() == null) { 738 return new Rectangle(0, 0, 0, 0); 739 } 740 741 return getPresentation().getControl().getBounds(); 742 } 743 744 747 public LayoutPart[] getChildren() { 748 return (LayoutPart[]) children.toArray(new LayoutPart[children.size()]); 749 } 750 751 public Control getControl() { 752 StackPresentation presentation = getPresentation(); 753 754 if (presentation == null) { 755 return null; 756 } 757 758 return presentation.getControl(); 759 } 760 761 764 public int getItemCount() { 765 if (isDisposed()) { 766 return children.size(); 767 } 768 return getPresentableParts().size(); 769 } 770 771 778 protected LayoutPart getPaneFor(IPresentablePart part) { 779 if (part == null || !(part instanceof PresentablePart)) { 780 return null; 781 } 782 783 return ((PresentablePart)part).getPane(); 784 } 785 786 789 public Composite getParent() { 790 return getControl().getParent(); 791 } 792 793 798 public List getPresentableParts() { 799 return presentableParts; 800 } 801 802 private PresentablePart getPresentablePart(LayoutPart pane) { 803 for (Iterator iter = presentableParts.iterator(); iter.hasNext();) { 804 PresentablePart part = (PresentablePart) iter.next(); 805 806 if (part.getPane() == pane) { 807 return part; 808 } 809 } 810 811 return null; 812 } 813 814 protected StackPresentation getPresentation() { 815 return presentationSite.getPresentation(); 816 } 817 818 822 public PartPane getSelection() { 823 if (current instanceof PartPane) { 824 return (PartPane) current; 825 } 826 return null; 827 } 828 829 private void presentationSelectionChanged(IPresentablePart newSelection) { 830 if (ignoreSelectionChanges) { 832 return; 833 } 834 LayoutPart newPart = getPaneFor(newSelection); 835 836 Assert.isNotNull(newPart); 838 839 if (newPart == requestedCurrent) { 840 return; 841 } 842 843 setSelection(newPart); 844 845 if (newPart != null) { 846 newPart.setFocus(); 847 } 848 849 } 850 851 854 public void remove(LayoutPart child) { 855 PresentablePart presentablePart = getPresentablePart(child); 856 857 children.remove(child); 861 862 StackPresentation presentation = getPresentation(); 863 864 if (presentablePart != null && presentation != null) { 865 ignoreSelectionChanges = true; 866 presentableParts .remove(presentablePart); 867 presentation.removePart(presentablePart); 868 presentablePart.dispose(); 869 ignoreSelectionChanges = false; 870 } 871 872 if (!isDisposed()) { 873 child.setContainer(null); 874 } 875 876 if (child == requestedCurrent) { 877 updateContainerVisibleTab(); 878 } 879 } 880 881 884 public void reparent(Composite newParent) { 885 886 Control control = getControl(); 887 if ((control == null) || (control.getParent() == newParent) || !control.isReparentable()) { 888 return; 889 } 890 891 super.reparent(newParent); 892 893 Iterator iter = children.iterator(); 894 while (iter.hasNext()) { 895 LayoutPart next = (LayoutPart) iter.next(); 896 next.reparent(newParent); 897 } 898 } 899 900 903 public void replace(LayoutPart oldChild, LayoutPart newChild) { 904 int idx = children.indexOf(oldChild); 905 int numPlaceholders = 0; 906 for (int i = 0; i < idx; i++) { 909 if (children.get(i) instanceof PartPlaceholder) { 910 numPlaceholders++; 911 } 912 } 913 Integer cookie = new Integer (idx - numPlaceholders); 914 children.add(idx, newChild); 915 916 showPart(newChild, cookie); 917 918 if (oldChild == requestedCurrent && !(newChild instanceof PartPlaceholder)) { 919 setSelection(newChild); 920 } 921 922 remove(oldChild); 923 } 924 925 928 public int computePreferredSize(boolean width, int availableParallel, 929 int availablePerpendicular, int preferredParallel) { 930 931 return getPresentation().computePreferredSize(width, availableParallel, 932 availablePerpendicular, preferredParallel); 933 } 934 935 938 public int getSizeFlags(boolean horizontal) { 939 StackPresentation presentation = getPresentation(); 940 941 if (presentation != null) { 942 return presentation.getSizeFlags(horizontal); 943 } 944 945 return 0; 946 } 947 948 951 public IStatus restoreState(IMemento memento) { 952 String activeTabID = memento 954 .getString(IWorkbenchConstants.TAG_ACTIVE_PAGE_ID); 955 956 IMemento[] children = memento.getChildren(IWorkbenchConstants.TAG_PAGE); 958 if (children != null) { 959 for (int i = 0; i < children.length; i++) { 961 IMemento childMem = children[i]; 963 String partID = childMem 964 .getString(IWorkbenchConstants.TAG_CONTENT); 965 966 LayoutPart part = new PartPlaceholder(partID); 968 part.setContainer(this); 969 add(part); 970 if (partID.equals(activeTabID)) { 973 setSelection(part); 974 } 977 } 978 } 979 980 IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore(); 981 boolean useNewMinMax = preferenceStore.getBoolean(IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX); 982 final Integer expanded = memento.getInteger(IWorkbenchConstants.TAG_EXPANDED); 983 if (useNewMinMax && expanded != null) { 984 StartupThreading.runWithoutExceptions(new StartupRunnable() { 985 public void runWithException() throws Throwable { 986 setState((expanded == null || expanded.intValue() != IStackPresentationSite.STATE_MINIMIZED) ? IStackPresentationSite.STATE_RESTORED 987 : IStackPresentationSite.STATE_MINIMIZED); 988 } 989 }); 990 } 991 else { 992 setState((expanded == null || expanded.intValue() != IStackPresentationSite.STATE_MINIMIZED) ? IStackPresentationSite.STATE_RESTORED 993 : IStackPresentationSite.STATE_MINIMIZED); 994 } 995 996 Integer appearance = memento 997 .getInteger(IWorkbenchConstants.TAG_APPEARANCE); 998 if (appearance != null) { 999 this.appearance = appearance.intValue(); 1000 } 1001 1002 savedPresentationState = null; 1004 IMemento[] presentationMementos = memento 1005 .getChildren(IWorkbenchConstants.TAG_PRESENTATION); 1006 1007 for (int idx = 0; idx < presentationMementos.length; idx++) { 1008 IMemento child = presentationMementos[idx]; 1009 1010 String id = child.getString(IWorkbenchConstants.TAG_ID); 1011 1012 if (Util.equals(id, getFactory().getId())) { 1013 savedPresentationState = child; 1014 break; 1015 } 1016 } 1017 1018 IMemento propertiesState = memento.getChild(IWorkbenchConstants.TAG_PROPERTIES); 1019 if (propertiesState != null) { 1020 IMemento[] props = propertiesState.getChildren(IWorkbenchConstants.TAG_PROPERTY); 1021 for (int i = 0; i < props.length; i++) { 1022 properties.put(props[i].getID(), props[i].getTextData()); 1023 } 1024 } 1025 1026 1027 return new Status(IStatus.OK, PlatformUI.PLUGIN_ID, 0, "", null); } 1029 1030 1033 public void setVisible(boolean makeVisible) { 1034 Control ctrl = getControl(); 1035 1036 boolean useShortcut = makeVisible || !isActive; 1037 1038 if (!SwtUtil.isDisposed(ctrl) && useShortcut) { 1039 if (makeVisible == ctrl.getVisible()) { 1040 return; 1041 } 1042 } 1043 1044 if (makeVisible) { 1045 for (Iterator iterator = presentableParts.iterator(); iterator.hasNext();) { 1046 PresentablePart next = (PresentablePart) iterator.next(); 1047 1048 next.enableInputs(isActive); 1049 next.enableOutputs(isActive); 1050 } 1051 } 1052 1053 super.setVisible(makeVisible); 1054 1055 StackPresentation presentation = getPresentation(); 1056 1057 if (presentation != null) { 1058 presentation.setVisible(makeVisible); 1059 } 1060 1061 if (!makeVisible) { 1062 for (Iterator iterator = presentableParts.iterator(); iterator.hasNext();) { 1063 PresentablePart next = (PresentablePart) iterator.next(); 1064 1065 next.enableInputs(false); 1066 } 1067 } 1068 } 1069 1070 1073 public IStatus saveState(IMemento memento) { 1074 1075 if (requestedCurrent != null) { 1077 memento.putString(IWorkbenchConstants.TAG_ACTIVE_PAGE_ID, requestedCurrent 1078 .getCompoundId()); 1079 } 1080 1081 Set cachedIds = new HashSet (); 1083 Iterator ppIter = getPresentableParts().iterator(); 1084 while (ppIter.hasNext()) { 1085 PresentablePart presPart = (PresentablePart) ppIter.next(); 1086 1087 IMemento childMem = memento 1088 .createChild(IWorkbenchConstants.TAG_PAGE); 1089 PartPane part = presPart.getPane(); 1090 String tabText = part.getPartReference().getPartName(); 1091 1092 childMem.putString(IWorkbenchConstants.TAG_LABEL, tabText); 1093 childMem.putString(IWorkbenchConstants.TAG_CONTENT, presPart.getPane().getPlaceHolderId()); 1094 1095 cachedIds.add(presPart.getPane().getPlaceHolderId()); 1097 } 1098 1099 Iterator iter = children.iterator(); 1100 while (iter.hasNext()) { 1101 LayoutPart next = (LayoutPart) iter.next(); 1102 1103 PartPane part = null; 1104 if (next instanceof PartPane) { 1105 if (cachedIds.contains(((PartPane)next).getPlaceHolderId())) 1107 continue; 1108 1109 part = (PartPane)next; 1110 } 1111 1112 IMemento childMem = memento 1113 .createChild(IWorkbenchConstants.TAG_PAGE); 1114 1115 String tabText = "LabelNotFound"; if (part != null) { 1117 tabText = part.getPartReference().getPartName(); 1118 } 1119 childMem.putString(IWorkbenchConstants.TAG_LABEL, tabText); 1120 childMem.putString(IWorkbenchConstants.TAG_CONTENT, next 1121 .getCompoundId()); 1122 } 1123 1124 IPreferenceStore preferenceStore = PrefUtil.getAPIPreferenceStore(); 1125 boolean useNewMinMax = preferenceStore.getBoolean(IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX); 1126 if (useNewMinMax) { 1127 memento.putInteger(IWorkbenchConstants.TAG_EXPANDED, presentationSite.getState()); 1128 } 1129 else { 1130 memento 1131 .putInteger( 1132 IWorkbenchConstants.TAG_EXPANDED, 1133 (presentationSite.getState() == IStackPresentationSite.STATE_MINIMIZED) ? IStackPresentationSite.STATE_MINIMIZED 1134 : IStackPresentationSite.STATE_RESTORED); 1135 } 1136 1137 memento.putInteger(IWorkbenchConstants.TAG_APPEARANCE, appearance); 1138 1139 savePresentationState(); 1140 1141 if (savedPresentationState != null) { 1142 IMemento presentationState = memento 1143 .createChild(IWorkbenchConstants.TAG_PRESENTATION); 1144 presentationState.putMemento(savedPresentationState); 1145 } 1146 1147 if (!properties.isEmpty()) { 1148 IMemento propertiesState = memento.createChild(IWorkbenchConstants.TAG_PROPERTIES); 1149 Set ids = properties.keySet(); 1150 for (Iterator iterator = ids.iterator(); iterator.hasNext();) { 1151 String id = (String )iterator.next(); 1152 1153 if (properties.get(id) == null) continue; 1154 1155 IMemento prop = propertiesState.createChild(IWorkbenchConstants.TAG_PROPERTY, id); 1156 prop.putTextData((String )properties.get(id)); 1157 } 1158 } 1159 1160 1161 return new Status(IStatus.OK, PlatformUI.PLUGIN_ID, 0, "", null); } 1163 1164 protected WorkbenchPage getPage() { 1165 WorkbenchWindow window = (WorkbenchWindow) getWorkbenchWindow(); 1166 1167 if (window == null) { 1168 return null; 1169 } 1170 1171 return (WorkbenchPage) window.getActivePage(); 1172 } 1173 1174 1179 public void setActive(int activeState) { 1180 1181 if (activeState == StackPresentation.AS_ACTIVE_FOCUS && isMinimized) { 1182 setMinimized(false); 1183 } 1184 1185 presentationSite.setActive(activeState); 1186 } 1187 1188 public int getActive() { 1189 return presentationSite.getActive(); 1190 } 1191 1192 1195 public void setBounds(Rectangle r) { 1196 1197 if (getPresentation() != null) { 1198 getPresentation().setBounds(r); 1199 } 1200 } 1201 1202 public void setSelection(LayoutPart part) { 1203 if (part == requestedCurrent) { 1204 return; 1205 } 1206 1207 requestedCurrent = part; 1208 1209 refreshPresentationSelection(); 1210 } 1211 1212 1216 protected abstract void updateActions(PresentablePart current); 1217 1218 1221 protected void handleDeferredEvents() { 1222 super.handleDeferredEvents(); 1223 1224 refreshPresentationSelection(); 1225 } 1226 1227 private void refreshPresentationSelection() { 1228 if (isDeferred()) { 1230 return; 1231 } 1232 1233 if (current == requestedCurrent) { 1236 return; 1237 } 1238 1239 StackPresentation presentation = getPresentation(); 1240 if (presentation != null) { 1241 1242 presentationCurrent = getPresentablePart(requestedCurrent); 1243 1244 if (!isDisposed()) { 1245 updateActions(presentationCurrent); 1246 } 1247 1248 if (presentationCurrent != null && presentation != null) { 1249 requestedCurrent.createControl(getParent()); 1250 if (requestedCurrent.getControl().getParent() != getControl() 1251 .getParent()) { 1252 requestedCurrent.reparent(getControl().getParent()); 1253 } 1254 1255 1256 presentation.selectPart(presentationCurrent); 1257 1258 } 1259 1260 current = requestedCurrent; 1262 fireInternalPropertyChange(PROP_SELECTION); 1263 } 1264 } 1265 1266 public int getState() { 1267 return presentationSite.getState(); 1268 } 1269 1270 1276 public void setMinimized(boolean minimized) { 1277 if (minimized != isMinimized) { 1278 isMinimized = minimized; 1279 1280 refreshPresentationState(); 1281 } 1282 } 1283 1284 1287 public boolean childObscuredByZoom(LayoutPart toTest) { 1288 return isObscuredByZoom(); 1289 } 1290 1291 1294 public void childRequestZoomIn(LayoutPart toZoom) { 1295 super.childRequestZoomIn(toZoom); 1296 1297 requestZoomIn(); 1298 } 1299 1302 public void childRequestZoomOut() { 1303 super.childRequestZoomOut(); 1304 1305 requestZoomOut(); 1306 } 1307 1308 1311 public boolean childIsZoomed(LayoutPart toTest) { 1312 return isZoomed(); 1313 } 1314 1315 1326 private boolean isIntroInStack() { 1327 LayoutPart[] kids = getChildren(); 1328 for (int i = 0; i < kids.length; i++) { 1329 if (kids[i] instanceof ViewPane) { 1330 ViewPane vp = (ViewPane) kids[i]; 1331 if (vp.getID().equals(IIntroConstants.INTRO_VIEW_ID)) 1332 return true; 1333 } 1334 } 1335 return false; 1336 } 1337 1338 private void smartZoom() { 1339 WorkbenchWindow wbw = (WorkbenchWindow) getPage().getWorkbenchWindow(); 1340 if (wbw == null || wbw.getShell() == null) 1341 return; 1342 1343 Perspective perspective = getPage().getActivePerspective(); 1344 FastViewManager fvm = perspective.getFastViewManager(); 1345 1346 fvm.deferUpdates(true); 1347 1348 perspective.getPresentation().updateBoundsMap(); 1350 1351 LayoutPart[] children = perspective.getPresentation().getLayout().getChildren(); 1352 for (int i = 0; i < children.length; i++) { 1353 if (children[i] != this) { 1354 if (children[i] instanceof ViewStack) { 1355 ((ViewStack) children[i]).setMinimized(true); 1356 ViewStackTrimToolBar vstb = fvm 1357 .getViewStackTrimToolbar(children[i] 1358 .getID()); 1359 vstb.setRestoreOnUnzoom(true); 1360 } 1361 else if (children[i] instanceof EditorSashContainer && !(this instanceof EditorStack)) { 1362 perspective.setEditorAreaState(IStackPresentationSite.STATE_MINIMIZED); 1363 perspective.setEditorAreaRestoreOnUnzoom(true); 1364 } 1365 } 1366 } 1367 1368 if (this instanceof EditorStack) 1370 perspective.setEditorAreaState(IStackPresentationSite.STATE_MAXIMIZED); 1371 1372 perspective.getPresentation().resetBoundsMap(); 1374 1375 fvm.deferUpdates(false); 1377 1378 perspective.getPresentation().setMaximizedStack(this); 1379 smartZoomed = true; 1380 } 1381 1382 protected void smartUnzoom() { 1383 if (doingUnzoom) 1385 return; 1386 doingUnzoom = true; 1387 1388 WorkbenchWindow wbw = (WorkbenchWindow) getPage().getWorkbenchWindow(); 1389 if (wbw == null || wbw.getShell() == null) 1390 return; 1391 1392 ITrimManager tbm = wbw.getTrimManager(); 1393 Perspective perspective = getPage().getActivePerspective(); 1394 FastViewManager fvm = perspective.getFastViewManager(); 1395 1396 ILayoutContainer root = getContainer(); 1397 1398 boolean restoringEditorArea = false; 1401 if (root instanceof EditorSashContainer) { 1402 root = ((EditorSashContainer) root).getContainer(); 1403 restoringEditorArea = true; 1404 } 1405 1406 fvm.deferUpdates(true); 1408 1409 LayoutPart[] children = root.getChildren(); 1410 for (int i = 0; i < children.length; i++) { 1411 if (children[i] != this) { 1412 IWindowTrim trim = tbm.getTrim(children[i].getID()); 1413 if (trim == null) 1414 continue; 1415 1416 if (trim instanceof ViewStackTrimToolBar) { 1417 ViewStackTrimToolBar vstb = (ViewStackTrimToolBar) trim; 1418 if (vstb.restoreOnUnzoom() 1419 && children[i] instanceof ContainerPlaceholder) { 1420 ViewStack realStack = (ViewStack) ((ContainerPlaceholder) children[i]) 1423 .getRealContainer(); 1424 realStack.setMinimized(false); 1425 1426 vstb.setRestoreOnUnzoom(false); 1427 } 1428 } else if (trim instanceof EditorAreaTrimToolBar) { 1429 if (perspective.getEditorAreaRestoreOnUnzoom()) 1430 perspective.setEditorAreaState(IStackPresentationSite.STATE_RESTORED); 1431 } 1432 } 1433 } 1434 1435 if (restoringEditorArea) 1437 perspective.setEditorAreaState(IStackPresentationSite.STATE_RESTORED); 1438 1439 perspective.getPresentation().setMaximizedStack(null); 1440 1441 fvm.deferUpdates(false); 1442 smartZoomed = false; 1443 1444 doingUnzoom = false; 1445 } 1446 1447 protected void setState(final int newState) { 1448 final int oldState = presentationSite.getState(); 1449 if (!supportsState(newState) || newState == oldState) { 1450 return; 1451 } 1452 1453 final WorkbenchWindow wbw = (WorkbenchWindow) getPage().getWorkbenchWindow(); 1454 if (wbw == null || wbw.getShell() == null || wbw.getActiveWorkbenchPage() == null) 1455 return; 1456 1457 WorkbenchPage page = wbw.getActiveWorkbenchPage(); 1458 if (page == null) 1459 return; 1460 1461 boolean useNewMinMax = Perspective.useNewMinMax(page.getActivePerspective()); 1462 1463 if (newState == IStackPresentationSite.STATE_MAXIMIZED) 1466 useNewMinMax = useNewMinMax && !isIntroInStack(); 1467 else if (newState == IStackPresentationSite.STATE_RESTORED) { 1468 PartStack maxStack = page.getActivePerspective().getPresentation().getMaximizedStack(); 1469 useNewMinMax = useNewMinMax && maxStack == this; 1470 } 1471 1472 if (useNewMinMax) { 1473 StartupThreading.runWithoutExceptions(new StartupRunnable() { 1474 public void runWithException() throws Throwable { 1475 wbw.getPageComposite().setRedraw(false); 1476 try { 1477 if (newState == IStackPresentationSite.STATE_MAXIMIZED) { 1478 smartZoom(); 1479 } else if (oldState == IStackPresentationSite.STATE_MAXIMIZED) { 1480 smartUnzoom(); 1481 } 1482 1483 if (newState == IStackPresentationSite.STATE_MINIMIZED) { 1484 setMinimized(true); 1485 } 1486 } finally { 1487 wbw.getPageComposite().setRedraw(true); 1488 1489 wbw.getShell().redraw(); 1491 } 1492 1493 setPresentationState(newState); 1494 } 1495 }); 1496 } else { 1497 boolean minimized = (newState == IStackPresentationSite.STATE_MINIMIZED); 1498 setMinimized(minimized); 1499 1500 if (newState == IStackPresentationSite.STATE_MAXIMIZED) { 1501 requestZoomIn(); 1502 } else if (oldState == IStackPresentationSite.STATE_MAXIMIZED) { 1503 requestZoomOut(); 1504 1505 if (newState == IStackPresentationSite.STATE_MINIMIZED) 1506 setMinimized(true); 1507 } 1508 } 1509 } 1510 1511 1512 1517 public void setZoomed(boolean isZoomed) { 1518 1519 super.setZoomed(isZoomed); 1520 1521 LayoutPart[] children = getChildren(); 1522 1523 for (int i = 0; i < children.length; i++) { 1524 LayoutPart next = children[i]; 1525 1526 next.setZoomed(isZoomed); 1527 } 1528 1529 refreshPresentationState(); 1530 } 1531 1532 public boolean isZoomed() { 1533 ILayoutContainer container = getContainer(); 1534 1535 if (container != null) { 1536 return container.childIsZoomed(this); 1537 } 1538 1539 return false; 1540 } 1541 1542 protected void refreshPresentationState() { 1543 if (isZoomed() || smartZoomed) { 1544 presentationSite.setPresentationState(IStackPresentationSite.STATE_MAXIMIZED); 1545 } else { 1546 1547 boolean wasMinimized = (presentationSite.getState() == IStackPresentationSite.STATE_MINIMIZED); 1548 1549 if (isMinimized) { 1550 presentationSite.setPresentationState(IStackPresentationSite.STATE_MINIMIZED); 1551 } else { 1552 presentationSite.setPresentationState(IStackPresentationSite.STATE_RESTORED); 1553 } 1554 1555 if (isMinimized != wasMinimized) { 1556 flushLayout(); 1557 1558 if (isMinimized) { 1559 WorkbenchPage page = getPage(); 1560 1561 if (page != null) { 1562 page.refreshActiveView(); 1563 } 1564 } 1565 } 1566 } 1567 } 1568 1569 1574 private void showPart(LayoutPart part, Object cookie) { 1575 1576 if (isDisposed()) { 1577 return; 1578 } 1579 1580 if ((part instanceof PartPlaceholder)) { 1581 part.setContainer(this); 1582 return; 1583 } 1584 1585 if (!(part instanceof PartPane)) { 1586 WorkbenchPlugin.log(NLS.bind( 1587 WorkbenchMessages.PartStack_incorrectPartInFolder, part 1588 .getID())); 1589 return; 1590 } 1591 1592 PartPane pane = (PartPane)part; 1593 1594 PresentablePart presentablePart = new PresentablePart(pane, getControl().getParent()); 1595 presentableParts.add(presentablePart); 1596 1597 if (isActive) { 1598 part.setContainer(this); 1599 } 1600 1601 presentationSite.getPresentation().addPart(presentablePart, cookie); 1602 1603 if (requestedCurrent == null) { 1604 setSelection(part); 1605 } 1606 1607 if (childObscuredByZoom(part)) { 1608 presentablePart.enableInputs(false); 1609 } 1610 } 1611 1612 1616 private void updateContainerVisibleTab() { 1617 LayoutPart[] parts = getChildren(); 1618 1619 if (parts.length < 1) { 1620 setSelection(null); 1621 return; 1622 } 1623 1624 PartPane selPart = null; 1625 int topIndex = 0; 1626 WorkbenchPage page = getPage(); 1627 1628 if (page != null) { 1629 IWorkbenchPartReference sortedPartsArray[] = page.getSortedParts(); 1630 List sortedParts = Arrays.asList(sortedPartsArray); 1631 for (int i = 0; i < parts.length; i++) { 1632 if (parts[i] instanceof PartPane) { 1633 IWorkbenchPartReference part = ((PartPane) parts[i]) 1634 .getPartReference(); 1635 int index = sortedParts.indexOf(part); 1636 if (index >= topIndex) { 1637 topIndex = index; 1638 selPart = (PartPane) parts[i]; 1639 } 1640 } 1641 } 1642 1643 } 1644 1645 if (selPart == null) { 1646 List presentableParts = getPresentableParts(); 1647 if (presentableParts.size() != 0) { 1648 IPresentablePart part = (IPresentablePart) getPresentableParts() 1649 .get(0); 1650 1651 selPart = (PartPane) getPaneFor(part); 1652 } 1653 } 1654 1655 setSelection(selPart); 1656 } 1657 1658 1661 public void showSystemMenu() { 1662 getPresentation().showSystemMenu(); 1663 } 1664 1665 public void showPaneMenu() { 1666 getPresentation().showPaneMenu(); 1667 } 1668 1669 public void showPartList() { 1670 getPresentation().showPartList(); 1671 } 1672 1673 public Control[] getTabList(LayoutPart part) { 1674 if (part != null) { 1675 IPresentablePart presentablePart = getPresentablePart(part); 1676 StackPresentation presentation = getPresentation(); 1677 1678 if (presentablePart != null && presentation != null) { 1679 return presentation.getTabList(presentablePart); 1680 } 1681 } 1682 1683 return new Control[0]; 1684 } 1685 1686 1692 private void dragStart(IPresentablePart beingDragged, Point initialLocation, 1693 boolean keyboard) { 1694 if (beingDragged == null) { 1695 paneDragStart((LayoutPart)null, initialLocation, keyboard); 1696 } else { 1697 if (presentationSite.isPartMoveable(beingDragged)) { 1698 LayoutPart pane = getPaneFor(beingDragged); 1699 1700 if (pane != null) { 1701 paneDragStart(pane, initialLocation, keyboard); 1702 } 1703 } 1704 } 1705 } 1706 1707 public void paneDragStart(LayoutPart pane, Point initialLocation, 1708 boolean keyboard) { 1709 if (pane == null) { 1710 if (canMoveFolder()) { 1711 1712 if (presentationSite.getState() == IStackPresentationSite.STATE_MAXIMIZED) { 1713 Rectangle bounds = Geometry.toDisplay(getParent(), getPresentation().getControl().getBounds()); 1715 float xpct = (initialLocation.x - bounds.x) / (float)(bounds.width); 1716 float ypct = (initialLocation.y - bounds.y) / (float)(bounds.height); 1717 1718 setState(IStackPresentationSite.STATE_RESTORED); 1719 1720 bounds = Geometry.toDisplay(getParent(), getPresentation().getControl().getBounds()); 1722 initialLocation.x = (int) (bounds.x + (xpct * bounds.width)); 1723 initialLocation.y = (int) (bounds.y + (ypct * bounds.height)); 1724 } 1725 1726 DragUtil.performDrag(PartStack.this, Geometry 1727 .toDisplay(getParent(), getPresentation().getControl() 1728 .getBounds()), initialLocation, !keyboard); 1729 } 1730 } else { 1731 1732 if (presentationSite.getState() == IStackPresentationSite.STATE_MAXIMIZED) { 1733 Rectangle bounds = Geometry.toDisplay(getParent(), getPresentation().getControl().getBounds()); 1735 float xpct = (initialLocation.x - bounds.x) / (float)(bounds.width); 1736 float ypct = (initialLocation.y - bounds.y) / (float)(bounds.height); 1737 1738 presentationSite.setState(IStackPresentationSite.STATE_RESTORED); 1739 1740 bounds = Geometry.toDisplay(getParent(), getPresentation().getControl().getBounds()); 1743 initialLocation.x = (int) (bounds.x + (xpct * bounds.width)); 1744 initialLocation.y = (int) (bounds.y + (ypct * bounds.height)); 1745 } 1746 1747 DragUtil.performDrag(pane, Geometry.toDisplay(getParent(), 1748 getPresentation().getControl().getBounds()), 1749 initialLocation, !keyboard); 1750 } 1751 } 1752 1753 1756 public IMemento getSavedPresentationState() { 1757 return savedPresentationState; 1758 } 1759 1760 private void fireInternalPropertyChange(int id) { 1761 Object listeners[] = this.listeners.getListeners(); 1762 for (int i = 0; i < listeners.length; i++) { 1763 ((IPropertyListener) listeners[i]).propertyChanged(this, id); 1764 } 1765 } 1766 1767 1769 1776 public void setPresentationState(int newState) { 1777 presentationSite.setPresentationState(newState); 1778 } 1779 1780 1783 1784 public String getProperty(String id) { 1785 return (String )properties.get(id); 1786 } 1787 1788 public void setProperty(String id, String value) { 1789 if (value==null) { 1790 properties.remove(id); 1791 } else { 1792 properties.put(id, value); 1793 } 1794 } 1795 1796 1799 public void copyAppearanceProperties(PartStack copyTo) { 1800 copyTo.appearance = this.appearance; 1801 if (!properties.isEmpty()) { 1802 Set ids = properties.keySet(); 1803 for (Iterator iterator = ids.iterator(); iterator.hasNext();) { 1804 String id = (String )iterator.next(); 1805 copyTo.setProperty(id, (String )properties.get(id)); 1806 } 1807 } 1808 } 1809} 1810 | Popular Tags |