/******************************************************************************* * Copyright (c) 2004, 2006 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 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.Platform; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.util.SafeRunnable; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IMemento; import org.eclipse.ui.IPropertyListener; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.intro.IntroMessages; import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; import org.eclipse.ui.internal.util.Util; import org.eclipse.ui.intro.IIntroPart; import org.eclipse.ui.intro.IIntroSite; import org.eclipse.ui.plugin.AbstractUIPlugin; /** * Abstract base implementation of an intro part. * <p> * Subclasses must implement the following methods: * <ul> * <li><code>createPartControl</code>- to create the intro part's controls * </li> * <li><code>setFocus</code>- to accept focus</li> * <li><code>standbyStateChanged</code>- to change the standby mode</li> * </ul> * </p> * <p> * Subclasses may extend or reimplement the following methods as required: * <ul> * <li><code>setInitializationData</code>- extend to provide additional * initialization when the intro extension is instantiated</li> * <li><code>init(IIntroSite, IMemento)</code>- extend to provide additional * initialization when intro is assigned its site</li> * <li><code>dispose</code>- extend to provide additional cleanup</li> * <li><code>getAdapter</code>- reimplement to make their intro adaptable * </li> * </ul> * </p> * @since 3.0 */ public abstract class IntroPart extends EventManager implements IIntroPart, IExecutableExtension { private IConfigurationElement configElement; private ImageDescriptor imageDescriptor; private IIntroSite partSite; private Image titleImage; private String titleLabel; /** * Creates a new intro part. */ protected IntroPart() { super(); } /* (non-Javadoc) * @see org.eclipse.ui.intro.IIntroPart#addPropertyListener(org.eclipse.ui.IPropertyListener) */ public void addPropertyListener(IPropertyListener l) { addListenerObject(l); } /* * (non-Javadoc) Creates the SWT controls for this intro part. <p> * Subclasses must implement this method. For a detailed description of the * requirements see <code> IIntroPart </code></p> * * @param parent the parent control * * @see IIntroPart */ public abstract void createPartControl(Composite parent); /** * The <code>IntroPart</code> implementation of this * <code>IIntroPart</code> method disposes the title image loaded by * <code>setInitializationData</code>. Subclasses may extend. */ public void dispose() { if (titleImage != null) { JFaceResources.getResources().destroyImage(imageDescriptor); titleImage = null; } // Clear out the property change listeners as we // should not be notifying anyone after the part // has been disposed. clearListeners(); } /** * 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]; Platform.run(new SafeRunnable() { public void run() { l.propertyChanged(this, propertyId); } }); } } /** * 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>. * 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 Object getAdapter(Class adapter) { 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) * * @see org.eclipse.ui.intro.IIntroPart#getIntroSite() */ public final IIntroSite getIntroSite() { return partSite; } /* (non-Javadoc) * @see org.eclipse.ui.intro.IIntroPart#getTitleImage() */ public Image getTitleImage() { if (titleImage != null) { return titleImage; } return getDefaultImage(); } /* (non-Javadoc) * @see org.eclipse.ui.intro.IIntroPart#getTitle() */ public String getTitle() { if (titleLabel != null) { return titleLabel; } return getDefaultTitle(); } /** * Return the default title string. * * @return the default title string */ private String getDefaultTitle() { return IntroMessages.Intro_default_title; } /** * The base implementation of this {@link org.eclipse.ui.intro.IIntroPart}method ignores the * memento and initializes the part in a fresh state. Subclasses may extend * to perform any state restoration, but must call the super method. * * @param site * the intro site * @param memento * the intro part state or <code>null</code> if there is no * previous saved state * @exception PartInitException * if this part was not initialized successfully */ public void init(IIntroSite site, IMemento memento) throws PartInitException { setSite(site); } /** * Sets the part site. * <p> * Subclasses must invoke this method from {@link org.eclipse.ui.intro.IIntroPart#init(IIntroSite, IMemento)}. * </p> * * @param site the intro part site */ protected void setSite(IIntroSite site) { this.partSite = site; } /* (non-Javadoc) * @see org.eclipse.ui.intro.IIntroPart#removePropertyListener(org.eclipse.ui.IPropertyListener) */ public void removePropertyListener(IPropertyListener l) { removeListenerObject(l); } /** * The base implementation of this {@link org.eclipse.ui.intro.IIntroPart} method does nothing. * Subclasses may override. * * @param memento * a memento to receive the object state */ public void saveState(IMemento memento) { //no-op } /* * (non-Javadoc) Asks this part to take focus within the workbench. * <p> * Subclasses must implement this method. For a detailed description of the * requirements see <code>IIntroPart</code> * </p> * * @see IIntroPart */ public abstract void setFocus(); /** * The <code>IntroPart</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; titleLabel = cfig.getAttribute(IWorkbenchRegistryConstants.ATT_LABEL); // Icon. String strIcon = cfig.getAttribute(IWorkbenchRegistryConstants.ATT_ICON); if (strIcon == null) { return; } imageDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin( configElement.getNamespace(), strIcon); if (imageDescriptor == null) { return; } Image image = JFaceResources.getResources().createImageWithDefault(imageDescriptor); titleImage = image; } /** * 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(IIntroPart.PROP_TITLE); } /** * Set the title string for this part. * * @param titleLabel the title string. Must not be <code>null</code>. * @since 3.2 */ protected void setTitle(String titleLabel) { Assert.isNotNull(titleLabel); if (Util.equals(this.titleLabel, titleLabel)) return; this.titleLabel = titleLabel; firePropertyChange(IIntroPart.PROP_TITLE); } }