1 11 package org.eclipse.ui.internal; 12 13 import java.util.BitSet ; 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 import java.util.Map ; 17 18 import org.eclipse.core.runtime.Assert; 19 import org.eclipse.core.runtime.IStatus; 20 import org.eclipse.core.runtime.ListenerList; 21 import org.eclipse.jface.resource.ImageDescriptor; 22 import org.eclipse.jface.resource.JFaceResources; 23 import org.eclipse.jface.util.IPropertyChangeListener; 24 import org.eclipse.jface.util.PropertyChangeEvent; 25 import org.eclipse.osgi.util.NLS; 26 import org.eclipse.swt.events.DisposeEvent; 27 import org.eclipse.swt.events.DisposeListener; 28 import org.eclipse.swt.graphics.Image; 29 import org.eclipse.swt.widgets.Control; 30 import org.eclipse.swt.widgets.Display; 31 import org.eclipse.ui.IPropertyListener; 32 import org.eclipse.ui.ISaveablePart; 33 import org.eclipse.ui.ISaveablesLifecycleListener; 34 import org.eclipse.ui.ISharedImages; 35 import org.eclipse.ui.IWorkbenchPart; 36 import org.eclipse.ui.IWorkbenchPart2; 37 import org.eclipse.ui.IWorkbenchPart3; 38 import org.eclipse.ui.IWorkbenchPartConstants; 39 import org.eclipse.ui.IWorkbenchPartReference; 40 import org.eclipse.ui.IWorkbenchPartSite; 41 import org.eclipse.ui.PartInitException; 42 import org.eclipse.ui.PlatformUI; 43 import org.eclipse.ui.internal.misc.UIListenerLogging; 44 import org.eclipse.ui.internal.util.Util; 45 46 49 public abstract class WorkbenchPartReference implements IWorkbenchPartReference { 50 51 54 public static final int INTERNAL_PROPERTY_OPENED = 0x211; 55 56 59 public static final int INTERNAL_PROPERTY_CLOSED = 0x212; 60 61 64 public static final int INTERNAL_PROPERTY_PINNED = 0x213; 65 66 69 public static final int INTERNAL_PROPERTY_VISIBLE = 0x214; 70 71 74 public static final int INTERNAL_PROPERTY_ZOOMED = 0x215; 75 76 80 public static final int INTERNAL_PROPERTY_ACTIVE_CHILD_CHANGED = 0x216; 81 82 86 public static final int INTERNAL_PROPERTY_MAXIMIZED = 0x217; 87 88 90 93 public static int STATE_LAZY = 0; 94 95 98 public static int STATE_CREATION_IN_PROGRESS = 1; 99 100 103 public static int STATE_CREATED = 2; 104 105 109 public static int STATE_DISPOSED = 3; 110 111 115 private int state = STATE_LAZY; 116 117 protected IWorkbenchPart part; 118 119 private String id; 120 121 protected PartPane pane; 122 123 private boolean pinned = false; 124 125 private String title; 126 127 private String tooltip; 128 129 132 private Image image = null; 133 134 private ImageDescriptor defaultImageDescriptor; 135 136 139 private ImageDescriptor imageDescriptor; 140 141 144 private ListenerList propChangeListeners = new ListenerList(); 145 146 150 private ListenerList internalPropChangeListeners = new ListenerList(); 151 152 private ListenerList partChangeListeners = new ListenerList(); 153 154 private String partName; 155 156 private String contentDescription; 157 158 protected Map propertyCache = new HashMap (); 159 160 163 private BitSet queuedEvents = new BitSet (); 164 165 private boolean queueEvents = false; 166 167 private static DisposeListener prematureDisposeListener = new DisposeListener() { 168 public void widgetDisposed(DisposeEvent e) { 169 WorkbenchPlugin.log(new RuntimeException ("Widget disposed too early!")); } 171 }; 172 173 private IPropertyListener propertyChangeListener = new IPropertyListener() { 174 177 public void propertyChanged(Object source, int propId) { 178 partPropertyChanged(source, propId); 179 } 180 }; 181 182 private IPropertyChangeListener partPropertyChangeListener = new IPropertyChangeListener() { 183 public void propertyChange(PropertyChangeEvent event) { 184 partPropertyChanged(event); 185 } 186 }; 187 188 public WorkbenchPartReference() { 189 } 191 192 public boolean isDisposed() { 193 return state == STATE_DISPOSED; 194 } 195 196 protected void checkReference() { 197 if (state == STATE_DISPOSED) { 198 throw new RuntimeException ("Error: IWorkbenchPartReference disposed"); } 200 } 201 202 209 private void deferEvents(boolean shouldQueue) { 210 queueEvents = shouldQueue; 211 212 if (queueEvents == false) { 213 for (int i = 0, n = queuedEvents.size(); i < n; ++i) { 215 if (queuedEvents.get(i)) { 216 firePropertyChange(i); 217 queuedEvents.clear(i); 218 } 219 } 220 } 221 } 222 223 protected void setTitle(String newTitle) { 224 if (Util.equals(title, newTitle)) { 225 return; 226 } 227 228 title = newTitle; 229 firePropertyChange(IWorkbenchPartConstants.PROP_TITLE); 230 } 231 232 protected void setPartName(String newPartName) { 233 if (Util.equals(partName, newPartName)) { 234 return; 235 } 236 237 partName = newPartName; 238 firePropertyChange(IWorkbenchPartConstants.PROP_PART_NAME); 239 } 240 241 protected void setContentDescription(String newContentDescription) { 242 if (Util.equals(contentDescription, newContentDescription)) { 243 return; 244 } 245 246 contentDescription = newContentDescription; 247 firePropertyChange(IWorkbenchPartConstants.PROP_CONTENT_DESCRIPTION); 248 } 249 250 protected void setImageDescriptor(ImageDescriptor descriptor) { 251 if (Util.equals(imageDescriptor, descriptor)) { 252 return; 253 } 254 255 Image oldImage = image; 256 ImageDescriptor oldDescriptor = imageDescriptor; 257 image = null; 258 imageDescriptor = descriptor; 259 260 immediateFirePropertyChange(IWorkbenchPartConstants.PROP_TITLE); 263 if (queueEvents) { 264 queuedEvents.clear(IWorkbenchPartConstants.PROP_TITLE); 267 } 268 269 if (oldImage != null) { 272 JFaceResources.getResources().destroy(oldDescriptor); 273 } 274 } 275 276 protected void setToolTip(String newToolTip) { 277 if (Util.equals(tooltip, newToolTip)) { 278 return; 279 } 280 281 tooltip = newToolTip; 282 firePropertyChange(IWorkbenchPartConstants.PROP_TITLE); 283 } 284 285 protected void partPropertyChanged(Object source, int propId) { 286 287 if (propId == IWorkbenchPartConstants.PROP_CONTENT_DESCRIPTION 290 || propId == IWorkbenchPartConstants.PROP_PART_NAME 291 || propId == IWorkbenchPartConstants.PROP_TITLE) { 292 293 refreshFromPart(); 294 } else { 295 firePropertyChange(propId); 297 } 298 299 if (propId == IWorkbenchPartConstants.PROP_DIRTY) { 301 IWorkbenchPart actualPart = getPart(false); 302 if (actualPart != null) { 303 SaveablesList modelManager = (SaveablesList) actualPart.getSite().getService(ISaveablesLifecycleListener.class); 304 modelManager.dirtyChanged(actualPart); 305 } 306 } 307 } 308 309 protected void partPropertyChanged(PropertyChangeEvent event) { 310 firePartPropertyChange(event); 311 } 312 313 316 protected void refreshFromPart() { 317 deferEvents(true); 318 319 setPartName(computePartName()); 320 setTitle(computeTitle()); 321 setContentDescription(computeContentDescription()); 322 setToolTip(getRawToolTip()); 323 setImageDescriptor(computeImageDescriptor()); 324 325 deferEvents(false); 326 } 327 328 protected ImageDescriptor computeImageDescriptor() { 329 if (part != null) { 330 return ImageDescriptor.createFromImage(part.getTitleImage(), Display.getCurrent()); 331 } 332 return defaultImageDescriptor; 333 } 334 335 public void init(String id, String title, String tooltip, 336 ImageDescriptor desc, String paneName, String contentDescription) { 337 Assert.isNotNull(id); 338 Assert.isNotNull(title); 339 Assert.isNotNull(tooltip); 340 Assert.isNotNull(desc); 341 Assert.isNotNull(paneName); 342 Assert.isNotNull(contentDescription); 343 344 this.id = id; 345 this.title = title; 346 this.tooltip = tooltip; 347 this.partName = paneName; 348 this.contentDescription = contentDescription; 349 this.defaultImageDescriptor = desc; 350 this.imageDescriptor = computeImageDescriptor(); 351 } 352 353 357 protected void releaseReferences() { 358 359 } 360 361 void addInternalPropertyListener(IPropertyListener listener) { 362 internalPropChangeListeners.add(listener); 363 } 364 365 void removeInternalPropertyListener(IPropertyListener listener) { 366 internalPropChangeListeners.remove(listener); 367 } 368 369 protected void fireInternalPropertyChange(int id) { 370 Object listeners[] = internalPropChangeListeners.getListeners(); 371 for (int i = 0; i < listeners.length; i++) { 372 ((IPropertyListener) listeners[i]).propertyChanged(this, id); 373 } 374 } 375 376 379 public void addPropertyListener(IPropertyListener listener) { 380 if (isDisposed()) { 383 return; 384 } 385 386 propChangeListeners.add(listener); 387 } 388 389 392 public void removePropertyListener(IPropertyListener listener) { 393 if (isDisposed()) { 396 return; 397 } 398 propChangeListeners.remove(listener); 399 } 400 401 public final String getId() { 402 if (part != null) { 403 IWorkbenchPartSite site = part.getSite(); 404 if (site != null) { 405 return site.getId(); 406 } 407 } 408 return Util.safeString(id); 409 } 410 411 public String getTitleToolTip() { 412 return Util.safeString(tooltip); 413 } 414 415 protected final String getRawToolTip() { 416 return Util.safeString(part.getTitleToolTip()); 417 } 418 419 424 public String getPartName() { 425 return Util.safeString(partName); 426 } 427 428 434 protected final String getRawPartName() { 435 String result = ""; 437 if (part instanceof IWorkbenchPart2) { 438 IWorkbenchPart2 part2 = (IWorkbenchPart2) part; 439 440 result = Util.safeString(part2.getPartName()); 441 } 442 443 return result; 444 } 445 446 protected String computePartName() { 447 return getRawPartName(); 448 } 449 450 455 public String getContentDescription() { 456 return Util.safeString(contentDescription); 457 } 458 459 465 protected String computeContentDescription() { 466 return getRawContentDescription(); 467 } 468 469 474 protected final String getRawContentDescription() { 475 if (part instanceof IWorkbenchPart2) { 476 IWorkbenchPart2 part2 = (IWorkbenchPart2) part; 477 478 return part2.getContentDescription(); 479 } 480 481 return ""; } 483 484 public boolean isDirty() { 485 if (!(part instanceof ISaveablePart)) { 486 return false; 487 } 488 return ((ISaveablePart) part).isDirty(); 489 } 490 491 public String getTitle() { 492 return Util.safeString(title); 493 } 494 495 500 protected String computeTitle() { 501 return getRawTitle(); 502 } 503 504 509 protected final String getRawTitle() { 510 return Util.safeString(part.getTitle()); 511 } 512 513 public final Image getTitleImage() { 514 if (isDisposed()) { 515 return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_DEF_VIEW); 516 } 517 518 if (image == null) { 519 image = JFaceResources.getResources().createImageWithDefault(imageDescriptor); 520 } 521 return image; 522 } 523 524 public ImageDescriptor getTitleImageDescriptor() { 525 if (isDisposed()) { 526 return PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_DEF_VIEW); 527 } 528 529 return imageDescriptor; 530 } 531 532 void fireVisibilityChange() { 533 fireInternalPropertyChange(INTERNAL_PROPERTY_VISIBLE); 534 } 535 536 void fireZoomChange() { 537 fireInternalPropertyChange(INTERNAL_PROPERTY_ZOOMED); 538 } 539 540 public boolean getVisible() { 541 if (isDisposed()) { 542 return false; 543 } 544 return getPane().getVisible(); 545 } 546 547 public void setVisible(boolean isVisible) { 548 if (isDisposed()) { 549 return; 550 } 551 getPane().setVisible(isVisible); 552 } 553 554 protected void firePropertyChange(int id) { 555 556 if (queueEvents) { 557 queuedEvents.set(id); 558 return; 559 } 560 561 immediateFirePropertyChange(id); 562 } 563 564 private void immediateFirePropertyChange(int id) { 565 UIListenerLogging.logPartReferencePropertyChange(this, id); 566 Object listeners[] = propChangeListeners.getListeners(); 567 for (int i = 0; i < listeners.length; i++) { 568 ((IPropertyListener) listeners[i]).propertyChanged(part, id); 569 } 570 571 fireInternalPropertyChange(id); 572 } 573 574 public final IWorkbenchPart getPart(boolean restore) { 575 if (isDisposed()) { 576 return null; 577 } 578 579 if (part == null && restore) { 580 581 if (state == STATE_CREATION_IN_PROGRESS) { 582 IStatus result = WorkbenchPlugin.getStatus( 583 new PartInitException(NLS.bind("Warning: Detected recursive attempt by part {0} to create itself (this is probably, but not necessarily, a bug)", getId()))); 585 WorkbenchPlugin.log(result); 586 return null; 587 } 588 589 try { 590 state = STATE_CREATION_IN_PROGRESS; 591 592 IWorkbenchPart newPart = createPart(); 593 if (newPart != null) { 594 part = newPart; 595 getPane().getControl().addDisposeListener(prematureDisposeListener); 599 part.addPropertyListener(propertyChangeListener); 600 if (part instanceof IWorkbenchPart3) { 601 ((IWorkbenchPart3)part).addPartPropertyListener(partPropertyChangeListener); 602 } 603 604 refreshFromPart(); 605 releaseReferences(); 606 607 fireInternalPropertyChange(INTERNAL_PROPERTY_OPENED); 608 } 609 } finally { 610 state = STATE_CREATED; 611 } 612 } 613 614 return part; 615 } 616 617 protected abstract IWorkbenchPart createPart(); 618 619 protected abstract PartPane createPane(); 620 621 630 public final PartPane getPane() { 631 632 if (pane == null) { 635 pane = createPane(); 636 } 637 return pane; 638 } 639 640 public final void dispose() { 641 642 if (isDisposed()) { 643 return; 644 } 645 646 partName = getPartName(); 649 contentDescription = getContentDescription(); 650 tooltip = getTitleToolTip(); 651 title = getTitle(); 652 653 if (state == STATE_CREATION_IN_PROGRESS) { 654 IStatus result = WorkbenchPlugin.getStatus( 655 new PartInitException(NLS.bind("Warning: Blocked recursive attempt by part {0} to dispose itself during creation", getId()))); 657 WorkbenchPlugin.log(result); 658 return; 659 } 660 661 if (pane != null) { 663 Control targetControl = getPane().getControl(); 665 if (targetControl != null) { 666 targetControl.removeDisposeListener(prematureDisposeListener); 667 } 668 pane.dispose(); 669 } 670 671 doDisposePart(); 672 673 if (pane != null) { 674 pane.removeContributions(); 675 } 676 677 clearListenerList(internalPropChangeListeners); 678 clearListenerList(partChangeListeners); 679 Image oldImage = image; 680 ImageDescriptor oldDescriptor = imageDescriptor; 681 image = null; 682 683 state = STATE_DISPOSED; 684 imageDescriptor = ImageDescriptor.getMissingImageDescriptor(); 685 defaultImageDescriptor = ImageDescriptor.getMissingImageDescriptor(); 686 immediateFirePropertyChange(IWorkbenchPartConstants.PROP_TITLE); 687 clearListenerList(propChangeListeners); 688 689 if (oldImage != null) { 690 JFaceResources.getResources().destroy(oldDescriptor); 691 } 692 } 693 694 701 private final void clearListenerList(final ListenerList list) { 702 final Object [] listeners = list.getListeners(); 703 for (int i = 0; i < listeners.length; i++) { 704 list.remove(listeners[i]); 705 } 706 } 707 708 711 protected void doDisposePart() { 712 if (part != null) { 713 fireInternalPropertyChange(INTERNAL_PROPERTY_CLOSED); 714 try { 716 part.removePropertyListener(propertyChangeListener); 717 if (part instanceof IWorkbenchPart3) { 718 ((IWorkbenchPart3)part).removePartPropertyListener(partPropertyChangeListener); 719 } 720 part.dispose(); 721 } catch (Exception e) { 722 WorkbenchPlugin.log(e); 723 } 724 part = null; 725 } 726 } 727 728 public void setPinned(boolean newPinned) { 729 if (isDisposed()) { 730 return; 731 } 732 733 if (newPinned == pinned) { 734 return; 735 } 736 737 pinned = newPinned; 738 739 setImageDescriptor(computeImageDescriptor()); 740 741 fireInternalPropertyChange(INTERNAL_PROPERTY_PINNED); 742 } 743 744 public boolean isPinned() { 745 return pinned; 746 } 747 748 751 public String getPartProperty(String key) { 752 if (part != null) { 753 if (part instanceof IWorkbenchPart3) { 754 return ((IWorkbenchPart3) part).getPartProperty(key); 755 } 756 } else { 757 return (String )propertyCache.get(key); 758 } 759 return null; 760 } 761 762 765 public void addPartPropertyListener(IPropertyChangeListener listener) { 766 if (isDisposed()) { 767 return; 768 } 769 partChangeListeners.add(listener); 770 } 771 772 775 public void removePartPropertyListener(IPropertyChangeListener listener) { 776 if (isDisposed()) { 777 return; 778 } 779 partChangeListeners.remove(listener); 780 } 781 782 protected void firePartPropertyChange(PropertyChangeEvent event) { 783 Object [] l = partChangeListeners.getListeners(); 784 for (int i = 0; i < l.length; i++) { 785 ((IPropertyChangeListener) l[i]).propertyChange(event); 786 } 787 } 788 789 protected void createPartProperties(IWorkbenchPart3 workbenchPart) { 790 Iterator i = propertyCache.entrySet().iterator(); 791 while (i.hasNext()) { 792 Map.Entry e = (Map.Entry ) i.next(); 793 workbenchPart.setPartProperty((String ) e.getKey(), (String ) e.getValue()); 794 } 795 } 796 } 797 | Popular Tags |