| /******************************************************************************* |
| * Copyright (c) 2000, 2007 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Stefan Xenos, IBM; Chris Torrence, ITT Visual Information Solutions - bug 51580 |
| *******************************************************************************/ |
| package org.eclipse.ui.internal; |
| |
| import java.util.BitSet; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.ListenerList; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.resource.JFaceResources; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.events.DisposeEvent; |
| import org.eclipse.swt.events.DisposeListener; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.ui.IPropertyListener; |
| import org.eclipse.ui.ISaveablePart; |
| import org.eclipse.ui.ISaveablesLifecycleListener; |
| import org.eclipse.ui.ISharedImages; |
| import org.eclipse.ui.ISizeProvider; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPart2; |
| import org.eclipse.ui.IWorkbenchPart3; |
| import org.eclipse.ui.IWorkbenchPartConstants; |
| import org.eclipse.ui.IWorkbenchPartReference; |
| import org.eclipse.ui.IWorkbenchPartSite; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.misc.UIListenerLogging; |
| import org.eclipse.ui.internal.util.Util; |
| |
| /** |
| * |
| */ |
| public abstract class WorkbenchPartReference implements IWorkbenchPartReference, ISizeProvider { |
| |
| /** |
| * Internal property ID: Indicates that the underlying part was created |
| */ |
| public static final int INTERNAL_PROPERTY_OPENED = 0x211; |
| |
| /** |
| * Internal property ID: Indicates that the underlying part was destroyed |
| */ |
| public static final int INTERNAL_PROPERTY_CLOSED = 0x212; |
| |
| /** |
| * Internal property ID: Indicates that the result of IEditorReference.isPinned() |
| */ |
| public static final int INTERNAL_PROPERTY_PINNED = 0x213; |
| |
| /** |
| * Internal property ID: Indicates that the result of getVisible() has changed |
| */ |
| public static final int INTERNAL_PROPERTY_VISIBLE = 0x214; |
| |
| /** |
| * Internal property ID: Indicates that the result of isZoomed() has changed |
| */ |
| public static final int INTERNAL_PROPERTY_ZOOMED = 0x215; |
| |
| /** |
| * Internal property ID: Indicates that the part has an active child and the |
| * active child has changed. (fired by PartStack) |
| */ |
| public static final int INTERNAL_PROPERTY_ACTIVE_CHILD_CHANGED = 0x216; |
| |
| /** |
| * Internal property ID: Indicates that changed in the min / max |
| * state has changed |
| */ |
| public static final int INTERNAL_PROPERTY_MAXIMIZED = 0x217; |
| |
| // State constants ////////////////////////////// |
| |
| /** |
| * State constant indicating that the part is not created yet |
| */ |
| public static int STATE_LAZY = 0; |
| |
| /** |
| * State constant indicating that the part is in the process of being created |
| */ |
| public static int STATE_CREATION_IN_PROGRESS = 1; |
| |
| /** |
| * State constant indicating that the part has been created |
| */ |
| public static int STATE_CREATED = 2; |
| |
| /** |
| * State constant indicating that the reference has been disposed (the reference shouldn't be |
| * used anymore) |
| */ |
| public static int STATE_DISPOSED = 3; |
| |
| /** |
| * Current state of the reference. Used to detect recursive creation errors, disposed |
| * references, etc. |
| */ |
| private int state = STATE_LAZY; |
| |
| protected IWorkbenchPart part; |
| |
| private String id; |
| |
| protected PartPane pane; |
| |
| private boolean pinned = false; |
| |
| private String title; |
| |
| private String tooltip; |
| |
| /** |
| * Stores the current Image for this part reference. Lazily created. Null if not allocated. |
| */ |
| private Image image = null; |
| |
| private ImageDescriptor defaultImageDescriptor; |
| |
| /** |
| * Stores the current image descriptor for the part. |
| */ |
| private ImageDescriptor imageDescriptor; |
| |
| /** |
| * API listener list |
| */ |
| private ListenerList propChangeListeners = new ListenerList(); |
| |
| /** |
| * Internal listener list. Listens to the INTERNAL_PROPERTY_* property change events that are not yet API. |
| * TODO: Make these properties API in 3.2 |
| */ |
| private ListenerList internalPropChangeListeners = new ListenerList(); |
| |
| private ListenerList partChangeListeners = new ListenerList(); |
| |
| private String partName; |
| |
| private String contentDescription; |
| |
| protected Map propertyCache = new HashMap(); |
| |
| /** |
| * Used to remember which events have been queued. |
| */ |
| private BitSet queuedEvents = new BitSet(); |
| |
| private boolean queueEvents = false; |
| |
| private static DisposeListener prematureDisposeListener = new DisposeListener() { |
| public void widgetDisposed(DisposeEvent e) { |
| WorkbenchPlugin.log(new RuntimeException("Widget disposed too early!")); //$NON-NLS-1$ |
| } |
| }; |
| |
| private IPropertyListener propertyChangeListener = new IPropertyListener() { |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IPropertyListener#propertyChanged(java.lang.Object, int) |
| */ |
| public void propertyChanged(Object source, int propId) { |
| partPropertyChanged(source, propId); |
| } |
| }; |
| |
| private IPropertyChangeListener partPropertyChangeListener = new IPropertyChangeListener() { |
| public void propertyChange(PropertyChangeEvent event) { |
| partPropertyChanged(event); |
| } |
| }; |
| |
| public WorkbenchPartReference() { |
| //no-op |
| } |
| |
| public boolean isDisposed() { |
| return state == STATE_DISPOSED; |
| } |
| |
| protected void checkReference() { |
| if (state == STATE_DISPOSED) { |
| throw new RuntimeException("Error: IWorkbenchPartReference disposed"); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Calling this with deferEvents(true) will queue all property change events until a subsequent |
| * call to deferEvents(false). This should be used at the beginning of a batch of related changes |
| * to prevent duplicate property change events from being sent. |
| * |
| * @param shouldQueue |
| */ |
| private void deferEvents(boolean shouldQueue) { |
| queueEvents = shouldQueue; |
| |
| if (queueEvents == false) { |
| // do not use nextSetBit, to allow compilation against JCL Foundation (bug 80053) |
| for (int i = 0, n = queuedEvents.size(); i < n; ++i) { |
| if (queuedEvents.get(i)) { |
| firePropertyChange(i); |
| queuedEvents.clear(i); |
| } |
| } |
| } |
| } |
| |
| protected void setTitle(String newTitle) { |
| if (Util.equals(title, newTitle)) { |
| return; |
| } |
| |
| title = newTitle; |
| firePropertyChange(IWorkbenchPartConstants.PROP_TITLE); |
| } |
| |
| protected void setPartName(String newPartName) { |
| if (Util.equals(partName, newPartName)) { |
| return; |
| } |
| |
| partName = newPartName; |
| firePropertyChange(IWorkbenchPartConstants.PROP_PART_NAME); |
| } |
| |
| protected void setContentDescription(String newContentDescription) { |
| if (Util.equals(contentDescription, newContentDescription)) { |
| return; |
| } |
| |
| contentDescription = newContentDescription; |
| firePropertyChange(IWorkbenchPartConstants.PROP_CONTENT_DESCRIPTION); |
| } |
| |
| protected void setImageDescriptor(ImageDescriptor descriptor) { |
| if (Util.equals(imageDescriptor, descriptor)) { |
| return; |
| } |
| |
| Image oldImage = image; |
| ImageDescriptor oldDescriptor = imageDescriptor; |
| image = null; |
| imageDescriptor = descriptor; |
| |
| // Don't queue events triggered by image changes. We'll dispose the image |
| // immediately after firing the event, so we need to fire it right away. |
| immediateFirePropertyChange(IWorkbenchPartConstants.PROP_TITLE); |
| if (queueEvents) { |
| // If there's a PROP_TITLE event queued, remove it from the queue because |
| // we've just fired it. |
| queuedEvents.clear(IWorkbenchPartConstants.PROP_TITLE); |
| } |
| |
| // If we had allocated the old image, deallocate it now (AFTER we fire the property change |
| // -- listeners may need to clean up references to the old image) |
| if (oldImage != null) { |
| JFaceResources.getResources().destroy(oldDescriptor); |
| } |
| } |
| |
| protected void setToolTip(String newToolTip) { |
| if (Util.equals(tooltip, newToolTip)) { |
| return; |
| } |
| |
| tooltip = newToolTip; |
| firePropertyChange(IWorkbenchPartConstants.PROP_TITLE); |
| } |
| |
| protected void partPropertyChanged(Object source, int propId) { |
| |
| // We handle these properties directly (some of them may be transformed |
| // before firing events to workbench listeners) |
| if (propId == IWorkbenchPartConstants.PROP_CONTENT_DESCRIPTION |
| || propId == IWorkbenchPartConstants.PROP_PART_NAME |
| || propId == IWorkbenchPartConstants.PROP_TITLE) { |
| |
| refreshFromPart(); |
| } else { |
| // Any other properties are just reported to listeners verbatim |
| firePropertyChange(propId); |
| } |
| |
| // Let the model manager know as well |
| if (propId == IWorkbenchPartConstants.PROP_DIRTY) { |
| IWorkbenchPart actualPart = getPart(false); |
| if (actualPart != null) { |
| SaveablesList modelManager = (SaveablesList) actualPart.getSite().getService(ISaveablesLifecycleListener.class); |
| modelManager.dirtyChanged(actualPart); |
| } |
| } |
| } |
| |
| protected void partPropertyChanged(PropertyChangeEvent event) { |
| firePartPropertyChange(event); |
| } |
| |
| /** |
| * Refreshes all cached values with the values from the real part |
| */ |
| protected void refreshFromPart() { |
| deferEvents(true); |
| |
| setPartName(computePartName()); |
| setTitle(computeTitle()); |
| setContentDescription(computeContentDescription()); |
| setToolTip(getRawToolTip()); |
| setImageDescriptor(computeImageDescriptor()); |
| |
| deferEvents(false); |
| } |
| |
| protected ImageDescriptor computeImageDescriptor() { |
| if (part != null) { |
| return ImageDescriptor.createFromImage(part.getTitleImage(), Display.getCurrent()); |
| } |
| return defaultImageDescriptor; |
| } |
| |
| public void init(String id, String title, String tooltip, |
| ImageDescriptor desc, String paneName, String contentDescription) { |
| Assert.isNotNull(id); |
| Assert.isNotNull(title); |
| Assert.isNotNull(tooltip); |
| Assert.isNotNull(desc); |
| Assert.isNotNull(paneName); |
| Assert.isNotNull(contentDescription); |
| |
| this.id = id; |
| this.title = title; |
| this.tooltip = tooltip; |
| this.partName = paneName; |
| this.contentDescription = contentDescription; |
| this.defaultImageDescriptor = desc; |
| this.imageDescriptor = computeImageDescriptor(); |
| } |
| |
| /** |
| * Releases any references maintained by this part reference |
| * when its actual part becomes known (not called when it is disposed). |
| */ |
| protected void releaseReferences() { |
| |
| } |
| |
| /* package */ void addInternalPropertyListener(IPropertyListener listener) { |
| internalPropChangeListeners.add(listener); |
| } |
| |
| /* package */ void removeInternalPropertyListener(IPropertyListener listener) { |
| internalPropChangeListeners.remove(listener); |
| } |
| |
| protected void fireInternalPropertyChange(int id) { |
| Object listeners[] = internalPropChangeListeners.getListeners(); |
| for (int i = 0; i < listeners.length; i++) { |
| ((IPropertyListener) listeners[i]).propertyChanged(this, id); |
| } |
| } |
| |
| /** |
| * @see IWorkbenchPart |
| */ |
| public void addPropertyListener(IPropertyListener listener) { |
| // The properties of a disposed reference will never change, so don't |
| // add listeners |
| if (isDisposed()) { |
| return; |
| } |
| |
| propChangeListeners.add(listener); |
| } |
| |
| /** |
| * @see IWorkbenchPart |
| */ |
| public void removePropertyListener(IPropertyListener listener) { |
| // Currently I'm not calling checkReference here for fear of breaking things late in 3.1, but it may |
| // make sense to do so later. For now we just turn it into a NOP if the reference is disposed. |
| if (isDisposed()) { |
| return; |
| } |
| propChangeListeners.remove(listener); |
| } |
| |
| public final String getId() { |
| if (part != null) { |
| IWorkbenchPartSite site = part.getSite(); |
| if (site != null) { |
| return site.getId(); |
| } |
| } |
| return Util.safeString(id); |
| } |
| |
| public String getTitleToolTip() { |
| return Util.safeString(tooltip); |
| } |
| |
| protected final String getRawToolTip() { |
| return Util.safeString(part.getTitleToolTip()); |
| } |
| |
| /** |
| * Returns the pane name for the part |
| * |
| * @return the pane name for the part |
| */ |
| public String getPartName() { |
| return Util.safeString(partName); |
| } |
| |
| /** |
| * Gets the part name directly from the associated workbench part, |
| * or the empty string if none. |
| * |
| * @return |
| */ |
| protected final String getRawPartName() { |
| String result = ""; //$NON-NLS-1$ |
| |
| if (part instanceof IWorkbenchPart2) { |
| IWorkbenchPart2 part2 = (IWorkbenchPart2) part; |
| |
| result = Util.safeString(part2.getPartName()); |
| } |
| |
| return result; |
| } |
| |
| protected String computePartName() { |
| return getRawPartName(); |
| } |
| |
| /** |
| * Returns the content description for this part. |
| * |
| * @return the pane name for the part |
| */ |
| public String getContentDescription() { |
| return Util.safeString(contentDescription); |
| } |
| |
| /** |
| * Computes a new content description for the part. Subclasses may override to change the |
| * default behavior |
| * |
| * @return the new content description for the part |
| */ |
| protected String computeContentDescription() { |
| return getRawContentDescription(); |
| } |
| |
| /** |
| * Returns the content description as set directly by the part, or the empty string if none |
| * |
| * @return the unmodified content description from the part (or the empty string if none) |
| */ |
| protected final String getRawContentDescription() { |
| if (part instanceof IWorkbenchPart2) { |
| IWorkbenchPart2 part2 = (IWorkbenchPart2) part; |
| |
| return part2.getContentDescription(); |
| } |
| |
| return ""; //$NON-NLS-1$ |
| } |
| |
| public boolean isDirty() { |
| if (!(part instanceof ISaveablePart)) { |
| return false; |
| } |
| return ((ISaveablePart) part).isDirty(); |
| } |
| |
| public String getTitle() { |
| return Util.safeString(title); |
| } |
| |
| /** |
| * Computes a new title for the part. Subclasses may override to change the default behavior. |
| * |
| * @return the title for the part |
| */ |
| protected String computeTitle() { |
| return getRawTitle(); |
| } |
| |
| /** |
| * Returns the unmodified title for the part, or the empty string if none |
| * |
| * @return the unmodified title, as set by the IWorkbenchPart. Returns the empty string if none. |
| */ |
| protected final String getRawTitle() { |
| return Util.safeString(part.getTitle()); |
| } |
| |
| public final Image getTitleImage() { |
| if (isDisposed()) { |
| return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_DEF_VIEW); |
| } |
| |
| if (image == null) { |
| image = JFaceResources.getResources().createImageWithDefault(imageDescriptor); |
| } |
| return image; |
| } |
| |
| public ImageDescriptor getTitleImageDescriptor() { |
| if (isDisposed()) { |
| return PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_DEF_VIEW); |
| } |
| |
| return imageDescriptor; |
| } |
| |
| /* package */ void fireVisibilityChange() { |
| fireInternalPropertyChange(INTERNAL_PROPERTY_VISIBLE); |
| } |
| |
| /* package */ void fireZoomChange() { |
| fireInternalPropertyChange(INTERNAL_PROPERTY_ZOOMED); |
| } |
| |
| public boolean getVisible() { |
| if (isDisposed()) { |
| return false; |
| } |
| return getPane().getVisible(); |
| } |
| |
| public void setVisible(boolean isVisible) { |
| if (isDisposed()) { |
| return; |
| } |
| getPane().setVisible(isVisible); |
| } |
| |
| protected void firePropertyChange(int id) { |
| |
| if (queueEvents) { |
| queuedEvents.set(id); |
| return; |
| } |
| |
| immediateFirePropertyChange(id); |
| } |
| |
| private void immediateFirePropertyChange(int id) { |
| UIListenerLogging.logPartReferencePropertyChange(this, id); |
| Object listeners[] = propChangeListeners.getListeners(); |
| for (int i = 0; i < listeners.length; i++) { |
| ((IPropertyListener) listeners[i]).propertyChanged(part, id); |
| } |
| |
| fireInternalPropertyChange(id); |
| } |
| |
| public final IWorkbenchPart getPart(boolean restore) { |
| if (isDisposed()) { |
| return null; |
| } |
| |
| if (part == null && restore) { |
| |
| if (state == STATE_CREATION_IN_PROGRESS) { |
| IStatus result = WorkbenchPlugin.getStatus( |
| new PartInitException(NLS.bind("Warning: Detected recursive attempt by part {0} to create itself (this is probably, but not necessarily, a bug)", //$NON-NLS-1$ |
| getId()))); |
| WorkbenchPlugin.log(result); |
| return null; |
| } |
| |
| try { |
| state = STATE_CREATION_IN_PROGRESS; |
| |
| IWorkbenchPart newPart = createPart(); |
| if (newPart != null) { |
| part = newPart; |
| // Add a dispose listener to the part. This dispose listener does nothing but log an exception |
| // if the part's widgets get disposed unexpectedly. The workbench part reference is the only |
| // object that should dispose this control, and it will remove the listener before it does so. |
| getPane().getControl().addDisposeListener(prematureDisposeListener); |
| part.addPropertyListener(propertyChangeListener); |
| if (part instanceof IWorkbenchPart3) { |
| ((IWorkbenchPart3)part).addPartPropertyListener(partPropertyChangeListener); |
| } |
| |
| refreshFromPart(); |
| releaseReferences(); |
| |
| fireInternalPropertyChange(INTERNAL_PROPERTY_OPENED); |
| |
| ISizeProvider sizeProvider = (ISizeProvider) Util.getAdapter(part, ISizeProvider.class); |
| if (sizeProvider != null) { |
| // If this part has a preferred size, indicate that the preferred size may have changed at this point |
| if (sizeProvider.getSizeFlags(true) != 0 || sizeProvider.getSizeFlags(false) != 0) { |
| fireInternalPropertyChange(IWorkbenchPartConstants.PROP_PREFERRED_SIZE); |
| } |
| } |
| } |
| } finally { |
| state = STATE_CREATED; |
| } |
| } |
| |
| return part; |
| } |
| |
| protected abstract IWorkbenchPart createPart(); |
| |
| protected abstract PartPane createPane(); |
| |
| /** |
| * Returns the part pane for this part reference. Does not return null. Should not be called |
| * if the reference has been disposed. |
| * |
| * TODO: clean up all code that has any possibility of calling this on a disposed reference |
| * and make this method throw an exception if anyone else attempts to do so. |
| * |
| * @return |
| */ |
| public final PartPane getPane() { |
| |
| // Note: we should never call this if the reference has already been disposed, since it |
| // may cause a PartPane to be created and leaked. |
| if (pane == null) { |
| pane = createPane(); |
| } |
| return pane; |
| } |
| |
| public final void dispose() { |
| |
| if (isDisposed()) { |
| return; |
| } |
| |
| // Store the current title, tooltip, etc. so that anyone that they can be returned to |
| // anyone that held on to the disposed reference. |
| partName = getPartName(); |
| contentDescription = getContentDescription(); |
| tooltip = getTitleToolTip(); |
| title = getTitle(); |
| |
| if (state == STATE_CREATION_IN_PROGRESS) { |
| IStatus result = WorkbenchPlugin.getStatus( |
| new PartInitException(NLS.bind("Warning: Blocked recursive attempt by part {0} to dispose itself during creation", //$NON-NLS-1$ |
| getId()))); |
| WorkbenchPlugin.log(result); |
| return; |
| } |
| |
| // Disposing the pane disposes the part's widgets. The part's widgets need to be disposed before the part itself. |
| if (pane != null) { |
| // Remove the dispose listener since this is the correct place for the widgets to get disposed |
| Control targetControl = getPane().getControl(); |
| if (targetControl != null) { |
| targetControl.removeDisposeListener(prematureDisposeListener); |
| } |
| pane.dispose(); |
| } |
| |
| doDisposePart(); |
| |
| if (pane != null) { |
| pane.removeContributions(); |
| } |
| |
| clearListenerList(internalPropChangeListeners); |
| clearListenerList(partChangeListeners); |
| Image oldImage = image; |
| ImageDescriptor oldDescriptor = imageDescriptor; |
| image = null; |
| |
| state = STATE_DISPOSED; |
| imageDescriptor = ImageDescriptor.getMissingImageDescriptor(); |
| defaultImageDescriptor = ImageDescriptor.getMissingImageDescriptor(); |
| immediateFirePropertyChange(IWorkbenchPartConstants.PROP_TITLE); |
| clearListenerList(propChangeListeners); |
| |
| if (oldImage != null) { |
| JFaceResources.getResources().destroy(oldDescriptor); |
| } |
| } |
| |
| /** |
| * Clears all of the listeners in a listener list. TODO Bug 117519 Remove |
| * this method when fixed. |
| * |
| * @param list |
| * The list to be clear; must not be <code>null</code>. |
| */ |
| private final void clearListenerList(final ListenerList list) { |
| final Object[] listeners = list.getListeners(); |
| for (int i = 0; i < listeners.length; i++) { |
| list.remove(listeners[i]); |
| } |
| } |
| |
| /** |
| * |
| */ |
| protected void doDisposePart() { |
| if (part != null) { |
| fireInternalPropertyChange(INTERNAL_PROPERTY_CLOSED); |
| // Don't let exceptions in client code bring us down. Log them and continue. |
| try { |
| part.removePropertyListener(propertyChangeListener); |
| if (part instanceof IWorkbenchPart3) { |
| ((IWorkbenchPart3)part).removePartPropertyListener(partPropertyChangeListener); |
| } |
| part.dispose(); |
| } catch (Exception e) { |
| WorkbenchPlugin.log(e); |
| } |
| part = null; |
| } |
| } |
| |
| public void setPinned(boolean newPinned) { |
| if (isDisposed()) { |
| return; |
| } |
| |
| if (newPinned == pinned) { |
| return; |
| } |
| |
| pinned = newPinned; |
| |
| setImageDescriptor(computeImageDescriptor()); |
| |
| fireInternalPropertyChange(INTERNAL_PROPERTY_PINNED); |
| } |
| |
| public boolean isPinned() { |
| return pinned; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IWorkbenchPartReference#getPartProperty(java.lang.String) |
| */ |
| public String getPartProperty(String key) { |
| if (part != null) { |
| if (part instanceof IWorkbenchPart3) { |
| return ((IWorkbenchPart3) part).getPartProperty(key); |
| } |
| } else { |
| return (String)propertyCache.get(key); |
| } |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IWorkbenchPartReference#addPartPropertyListener(org.eclipse.jface.util.IPropertyChangeListener) |
| */ |
| public void addPartPropertyListener(IPropertyChangeListener listener) { |
| if (isDisposed()) { |
| return; |
| } |
| partChangeListeners.add(listener); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IWorkbenchPartReference#removePartPropertyListener(org.eclipse.jface.util.IPropertyChangeListener) |
| */ |
| public void removePartPropertyListener(IPropertyChangeListener listener) { |
| if (isDisposed()) { |
| return; |
| } |
| partChangeListeners.remove(listener); |
| } |
| |
| protected void firePartPropertyChange(PropertyChangeEvent event) { |
| Object[] l = partChangeListeners.getListeners(); |
| for (int i = 0; i < l.length; i++) { |
| ((IPropertyChangeListener) l[i]).propertyChange(event); |
| } |
| } |
| |
| protected void createPartProperties(IWorkbenchPart3 workbenchPart) { |
| Iterator i = propertyCache.entrySet().iterator(); |
| while (i.hasNext()) { |
| Map.Entry e = (Map.Entry) i.next(); |
| workbenchPart.setPartProperty((String) e.getKey(), (String) e.getValue()); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.ISizeProvider#computePreferredSize(boolean, int, int, int) |
| */ |
| public int computePreferredSize(boolean width, int availableParallel, |
| int availablePerpendicular, int preferredResult) { |
| |
| ISizeProvider sizeProvider = (ISizeProvider) Util.getAdapter(part, ISizeProvider.class); |
| if (sizeProvider != null) { |
| return sizeProvider.computePreferredSize(width, availableParallel, availablePerpendicular, preferredResult); |
| } |
| |
| return preferredResult; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.ISizeProvider#getSizeFlags(boolean) |
| */ |
| public int getSizeFlags(boolean width) { |
| ISizeProvider sizeProvider = (ISizeProvider) Util.getAdapter(part, ISizeProvider.class); |
| if (sizeProvider != null) { |
| return sizeProvider.getSizeFlags(width); |
| } |
| return 0; |
| } |
| |
| } |