| /******************************************************************************* |
| * Copyright (c) 2000, 2019 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 |
| *******************************************************************************/ |
| package org.eclipse.ui.part; |
| |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.core.commands.common.EventManager; |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExecutableExtension; |
| import org.eclipse.core.runtime.ListenerList; |
| import org.eclipse.core.runtime.Platform; |
| 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.jface.window.Window; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.ui.IPropertyListener; |
| import org.eclipse.ui.ISharedImages; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchPart3; |
| import org.eclipse.ui.IWorkbenchPartConstants; |
| import org.eclipse.ui.IWorkbenchPartSite; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.WorkbenchMessages; |
| import org.eclipse.ui.internal.WorkbenchPlugin; |
| import org.eclipse.ui.internal.util.Util; |
| import org.eclipse.ui.plugin.AbstractUIPlugin; |
| |
| import com.ibm.icu.text.MessageFormat; |
| |
| /** |
| * Abstract base implementation of all workbench parts. |
| * <p> |
| * This class is not intended to be subclassed by clients outside this |
| * package; clients should instead subclass <code>ViewPart</code> or |
| * <code>EditorPart</code>. |
| * </p> |
| * |
| * @see org.eclipse.ui.part.ViewPart |
| * @see org.eclipse.ui.part.EditorPart |
| * @since 1.0 |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public abstract class WorkbenchPart extends EventManager implements |
| IWorkbenchPart3, IExecutableExtension, IWorkbenchPartOrientation { |
| private String title = ""; //$NON-NLS-1$ |
| |
| private ImageDescriptor imageDescriptor; |
| |
| private Image titleImage; |
| |
| private String toolTip = ""; //$NON-NLS-1$ |
| |
| private IConfigurationElement configElement; |
| |
| private IWorkbenchPartSite partSite; |
| |
| private String partName = ""; //$NON-NLS-1$ |
| |
| private String contentDescription = ""; //$NON-NLS-1$ |
| |
| private ListenerList partChangeListeners = new ListenerList(); |
| |
| /** |
| * Creates a new workbench part. |
| */ |
| protected WorkbenchPart() { |
| super(); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWorkbenchPart. |
| */ |
| public void addPropertyListener(IPropertyListener l) { |
| addListenerObject(l); |
| } |
| |
| /* (non-Javadoc) |
| * Creates the SWT controls for this workbench part. |
| * <p> |
| * Subclasses must implement this method. For a detailed description of the |
| * requirements see <code>IWorkbenchPart</code> |
| * </p> |
| * |
| * @param parent the parent control |
| * @see IWorkbenchPart |
| */ |
| public abstract void createPartControl(Composite parent); |
| |
| /** |
| * The <code>WorkbenchPart</code> implementation of this |
| * <code>IWorkbenchPart</code> method disposes the title image |
| * loaded by <code>setInitializationData</code>. Subclasses may extend. |
| */ |
| public void dispose() { |
| if (imageDescriptor != null) { |
| JFaceResources.getResources().destroyImage(imageDescriptor); |
| } |
| |
| // Clear out the property change listeners as we |
| // should not be notifying anyone after the part |
| // has been disposed. |
| clearListeners(); |
| partChangeListeners.clear(); |
| } |
| |
| /** |
| * Fires a property changed event. |
| * |
| * @param propertyId the id of the property that changed |
| */ |
| protected void firePropertyChange(final int propertyId) { |
| Object[] array = getListeners(); |
| for (int nX = 0; nX < array.length; nX++) { |
| final IPropertyListener l = (IPropertyListener) array[nX]; |
| try { |
| l.propertyChanged(WorkbenchPart.this, propertyId); |
| } catch (RuntimeException e) { |
| WorkbenchPlugin.log(e); |
| } |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * Subclasses may override this method (however, if they do so, they |
| * should invoke the method on their superclass to ensure that the |
| * Platform's adapter manager is consulted). |
| */ |
| public <T> T getAdapter(Class<T> adapter) { |
| |
| /** |
| * This implementation of the method declared by <code>IAdaptable</code> |
| * passes the request along to the platform's adapter manager; roughly |
| * <code>Platform.getAdapterManager().getAdapter(this, adapter)</code>. |
| */ |
| |
| return Platform.getAdapterManager().getAdapter(this, adapter); |
| } |
| |
| /** |
| * Returns the configuration element for this part. The configuration element |
| * comes from the plug-in registry entry for the extension defining this part. |
| * |
| * @return the configuration element for this part |
| */ |
| protected IConfigurationElement getConfigurationElement() { |
| return configElement; |
| } |
| |
| /** |
| * Returns the default title image. |
| * |
| * @return the default image |
| */ |
| protected Image getDefaultImage() { |
| return PlatformUI.getWorkbench().getSharedImages().getImage( |
| ISharedImages.IMG_DEF_VIEW); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWorkbenchPart. |
| */ |
| public IWorkbenchPartSite getSite() { |
| return partSite; |
| } |
| |
| /** |
| * {@inheritDoc} |
| * <p> |
| * It is considered bad practise to overload or extend this method. |
| * Parts should set their title by calling setPartName and/or setContentDescription. |
| * </p> |
| */ |
| public String getTitle() { |
| return title; |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWorkbenchPart. |
| */ |
| public Image getTitleImage() { |
| if (titleImage != null) { |
| return titleImage; |
| } |
| return getDefaultImage(); |
| } |
| |
| /* (non-Javadoc) |
| * Gets the title tool tip text of this part. |
| * |
| * @return the tool tip text |
| */ |
| public String getTitleToolTip() { |
| return toolTip; |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWorkbenchPart. |
| */ |
| public void removePropertyListener(IPropertyListener l) { |
| removeListenerObject(l); |
| } |
| |
| /* (non-Javadoc) |
| * Asks this part to take focus within the workbench. Parts must |
| * assign focus to one of the controls contained in the part's |
| * parent composite. |
| * <p> |
| * Subclasses must implement this method. For a detailed description of the |
| * requirements see <code>IWorkbenchPart</code> |
| * </p> |
| * |
| * @see IWorkbenchPart |
| */ |
| public abstract void setFocus(); |
| |
| /** |
| * {@inheritDoc} |
| * The <code>WorkbenchPart</code> implementation of this |
| * <code>IExecutableExtension</code> records the configuration element in |
| * and internal state variable (accessible via <code>getConfigElement</code>). |
| * It also loads the title image, if one is specified in the configuration element. |
| * Subclasses may extend. |
| * |
| * Should not be called by clients. It is called by the core plugin when creating |
| * this executable extension. |
| */ |
| public void setInitializationData(IConfigurationElement cfig, |
| String propertyName, Object data) { |
| |
| // Save config element. |
| configElement = cfig; |
| |
| // Part name and title. |
| partName = Util.safeString(cfig.getAttribute("name"));//$NON-NLS-1$; |
| title = partName; |
| |
| // Icon. |
| String strIcon = cfig.getAttribute("icon");//$NON-NLS-1$ |
| if (strIcon == null) { |
| return; |
| } |
| |
| imageDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin( |
| configElement.getNamespace(), strIcon); |
| |
| if (imageDescriptor == null) { |
| return; |
| } |
| |
| titleImage = JFaceResources.getResources().createImageWithDefault(imageDescriptor); |
| } |
| |
| /** |
| * Sets the part site. |
| * <p> |
| * Subclasses must invoke this method from <code>IEditorPart.init</code> |
| * and <code>IViewPart.init</code>. |
| * |
| * @param site the workbench part site |
| */ |
| protected void setSite(IWorkbenchPartSite site) { |
| checkSite(site); |
| this.partSite = site; |
| } |
| |
| /** |
| * Checks that the given site is valid for this type of part. |
| * The default implementation does nothing. |
| * |
| * @param site the site to check |
| */ |
| protected void checkSite(IWorkbenchPartSite site) { |
| // do nothing |
| } |
| |
| /** |
| * Sets or clears the title of this part. Clients should call this method instead |
| * of overriding getTitle. |
| * <p> |
| * This may change a title that was previously set using setPartName or setContentDescription. |
| * </p> |
| * |
| * @deprecated new code should use setPartName and setContentDescription |
| * |
| * @param title the title, or <code>null</code> to clear |
| */ |
| protected void setTitle(String title) { |
| title = Util.safeString(title); |
| |
| //Do not send changes if they are the same |
| if (Util.equals(this.title, title)) { |
| return; |
| } |
| this.title = title; |
| firePropertyChange(IWorkbenchPart.PROP_TITLE); |
| } |
| |
| /** |
| * Sets or clears the title image of this part. |
| * |
| * @param titleImage the title image, or <code>null</code> to clear |
| */ |
| protected void setTitleImage(Image titleImage) { |
| Assert.isTrue(titleImage == null || !titleImage.isDisposed()); |
| //Do not send changes if they are the same |
| if (this.titleImage == titleImage) { |
| return; |
| } |
| this.titleImage = titleImage; |
| firePropertyChange(IWorkbenchPart.PROP_TITLE); |
| if (imageDescriptor != null) { |
| JFaceResources.getResources().destroyImage(imageDescriptor); |
| imageDescriptor = null; |
| } |
| } |
| |
| /** |
| * Sets or clears the title tool tip text of this part. Clients should |
| * call this method instead of overriding <code>getTitleToolTip</code> |
| * |
| * @param toolTip the new tool tip text, or <code>null</code> to clear |
| */ |
| protected void setTitleToolTip(String toolTip) { |
| toolTip = Util.safeString(toolTip); |
| //Do not send changes if they are the same |
| if (Util.equals(this.toolTip, toolTip)) { |
| return; |
| } |
| this.toolTip = toolTip; |
| firePropertyChange(IWorkbenchPart.PROP_TITLE); |
| } |
| |
| /** |
| * Show that this part is busy due to a Job running that it |
| * is listening to. |
| * @param busy boolean to indicate that the busy state has started |
| * or ended. |
| * @see org.eclipse.ui.progress.IWorkbenchSiteProgressService#showBusyForFamily(Object) |
| */ |
| public void showBusy(boolean busy) { |
| //By default do nothing |
| } |
| |
| /** |
| * {@inheritDoc} |
| * <p> |
| * It is considered bad practise to overload or extend this method. |
| * Parts should call setPartName to change their part name. |
| * </p> |
| */ |
| public String getPartName() { |
| return partName; |
| } |
| |
| /** |
| * Sets the name of this part. The name will be shown in the tab area for |
| * the part. Clients should call this method instead of overriding getPartName. |
| * Setting this to the empty string will cause a default part name to be used. |
| * |
| * <p> |
| * setPartName and setContentDescription are intended to replace setTitle. |
| * This may change a value that was previously set using setTitle. |
| * </p> |
| * |
| * @param partName the part name, as it should be displayed in tabs. |
| * |
| */ |
| protected void setPartName(String partName) { |
| |
| internalSetPartName(partName); |
| |
| setDefaultTitle(); |
| } |
| |
| void setDefaultTitle() { |
| String description = getContentDescription(); |
| String name = getPartName(); |
| String newTitle = name; |
| |
| if (!Util.equals(description, "")) { //$NON-NLS-1$ |
| newTitle = MessageFormat |
| .format( |
| WorkbenchMessages.get().WorkbenchPart_AutoTitleFormat, new String[] { name, description }); |
| } |
| |
| setTitle(newTitle); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * <p> |
| * It is considered bad practise to overload or extend this method. |
| * Parts should call setContentDescription to change their content description. |
| * </p> |
| */ |
| public String getContentDescription() { |
| return contentDescription; |
| } |
| |
| /** |
| * Sets the content description for this part. The content description is typically |
| * a short string describing the current contents of the part. Setting this to the |
| * empty string will cause a default content description to be used. Clients should |
| * call this method instead of overriding getContentDescription(). For views, the |
| * content description is shown (by default) in a line near the top of the view. For |
| * editors, the content description is shown beside the part name when showing a |
| * list of editors. If the editor is open on a file, this typically contains the path |
| * to the input file, without the filename or trailing slash. |
| * |
| * <p> |
| * This may overwrite a value that was previously set in setTitle |
| * </p> |
| * |
| * @param description the content description |
| * |
| */ |
| protected void setContentDescription(String description) { |
| internalSetContentDescription(description); |
| |
| setDefaultTitle(); |
| } |
| |
| void internalSetContentDescription(String description) { |
| Assert.isNotNull(description); |
| |
| //Do not send changes if they are the same |
| if (Util.equals(contentDescription, description)) { |
| return; |
| } |
| this.contentDescription = description; |
| |
| firePropertyChange(IWorkbenchPartConstants.PROP_CONTENT_DESCRIPTION); |
| } |
| |
| void internalSetPartName(String partName) { |
| partName = Util.safeString(partName); |
| |
| Assert.isNotNull(partName); |
| |
| //Do not send changes if they are the same |
| if (Util.equals(this.partName, partName)) { |
| return; |
| } |
| this.partName = partName; |
| |
| firePropertyChange(IWorkbenchPartConstants.PROP_PART_NAME); |
| |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.part.IWorkbenchPartOrientation#getOrientation() |
| */ |
| public int getOrientation(){ |
| //By default use the orientation in Window |
| return Window.getDefaultOrientation(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IWorkbenchPart3#addPartPropertyListener(org.eclipse.jface.util.IPropertyChangeListener) |
| */ |
| public void addPartPropertyListener(IPropertyChangeListener listener) { |
| partChangeListeners.add(listener); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IWorkbenchPart3#removePartPropertyListener(org.eclipse.jface.util.IPropertyChangeListener) |
| */ |
| public void removePartPropertyListener(IPropertyChangeListener listener) { |
| partChangeListeners.remove(listener); |
| } |
| |
| /** |
| */ |
| protected void firePartPropertyChanged(String key, String oldValue, String newValue) { |
| final PropertyChangeEvent event = new PropertyChangeEvent(this, key, oldValue, newValue); |
| Object[] l = partChangeListeners.getListeners(); |
| for (int i = 0; i < l.length; i++) { |
| try { |
| ((IPropertyChangeListener)l[i]).propertyChange(event); |
| } catch (RuntimeException e) { |
| WorkbenchPlugin.log(e); |
| } |
| } |
| } |
| |
| private Map partProperties = new HashMap(); |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IWorkbenchPart3#setPartProperty(java.lang.String, java.lang.String) |
| */ |
| public void setPartProperty(String key, String value) { |
| String oldValue = (String) partProperties.get(key); |
| if (value==null) { |
| partProperties.remove(key); |
| } else { |
| partProperties.put(key, value); |
| } |
| firePartPropertyChanged(key, oldValue, value); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IWorkbenchPart3#getPartProperty(java.lang.String) |
| */ |
| public String getPartProperty(String key) { |
| return (String)partProperties.get(key); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IWorkbenchPart3#getPartProperties() |
| */ |
| public Map getPartProperties() { |
| return Collections.unmodifiableMap(partProperties); |
| } |
| } |