001: /*******************************************************************************
002: * Copyright (c) 2004, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.part;
011:
012: import org.eclipse.core.commands.common.EventManager;
013: import org.eclipse.core.runtime.Assert;
014: import org.eclipse.core.runtime.IConfigurationElement;
015: import org.eclipse.core.runtime.IExecutableExtension;
016: import org.eclipse.core.runtime.Platform;
017: import org.eclipse.jface.resource.ImageDescriptor;
018: import org.eclipse.jface.resource.JFaceResources;
019: import org.eclipse.jface.util.SafeRunnable;
020: import org.eclipse.swt.graphics.Image;
021: import org.eclipse.swt.widgets.Composite;
022: import org.eclipse.ui.IMemento;
023: import org.eclipse.ui.IPropertyListener;
024: import org.eclipse.ui.ISharedImages;
025: import org.eclipse.ui.PartInitException;
026: import org.eclipse.ui.PlatformUI;
027: import org.eclipse.ui.internal.intro.IntroMessages;
028: import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
029: import org.eclipse.ui.internal.util.Util;
030: import org.eclipse.ui.intro.IIntroPart;
031: import org.eclipse.ui.intro.IIntroSite;
032: import org.eclipse.ui.plugin.AbstractUIPlugin;
033:
034: /**
035: * Abstract base implementation of an intro part.
036: * <p>
037: * Subclasses must implement the following methods:
038: * <ul>
039: * <li><code>createPartControl</code>- to create the intro part's controls
040: * </li>
041: * <li><code>setFocus</code>- to accept focus</li>
042: * <li><code>standbyStateChanged</code>- to change the standby mode</li>
043: * </ul>
044: * </p>
045: * <p>
046: * Subclasses may extend or reimplement the following methods as required:
047: * <ul>
048: * <li><code>setInitializationData</code>- extend to provide additional
049: * initialization when the intro extension is instantiated</li>
050: * <li><code>init(IIntroSite, IMemento)</code>- extend to provide additional
051: * initialization when intro is assigned its site</li>
052: * <li><code>dispose</code>- extend to provide additional cleanup</li>
053: * <li><code>getAdapter</code>- reimplement to make their intro adaptable
054: * </li>
055: * </ul>
056: * </p>
057: * @since 3.0
058: */
059: public abstract class IntroPart extends EventManager implements
060: IIntroPart, IExecutableExtension {
061:
062: private IConfigurationElement configElement;
063:
064: private ImageDescriptor imageDescriptor;
065:
066: private IIntroSite partSite;
067:
068: private Image titleImage;
069:
070: private String titleLabel;
071:
072: /**
073: * Creates a new intro part.
074: */
075: protected IntroPart() {
076: super ();
077: }
078:
079: /* (non-Javadoc)
080: * @see org.eclipse.ui.intro.IIntroPart#addPropertyListener(org.eclipse.ui.IPropertyListener)
081: */
082: public void addPropertyListener(IPropertyListener l) {
083: addListenerObject(l);
084: }
085:
086: /*
087: * (non-Javadoc) Creates the SWT controls for this intro part. <p>
088: * Subclasses must implement this method. For a detailed description of the
089: * requirements see <code> IIntroPart </code></p>
090: *
091: * @param parent the parent control
092: *
093: * @see IIntroPart
094: */
095: public abstract void createPartControl(Composite parent);
096:
097: /**
098: * The <code>IntroPart</code> implementation of this
099: * <code>IIntroPart</code> method disposes the title image loaded by
100: * <code>setInitializationData</code>. Subclasses may extend.
101: */
102: public void dispose() {
103: if (titleImage != null) {
104: JFaceResources.getResources().destroyImage(imageDescriptor);
105: titleImage = null;
106: }
107:
108: // Clear out the property change listeners as we
109: // should not be notifying anyone after the part
110: // has been disposed.
111: clearListeners();
112: }
113:
114: /**
115: * Fires a property changed event.
116: *
117: * @param propertyId
118: * the id of the property that changed
119: */
120: protected void firePropertyChange(final int propertyId) {
121: Object[] array = getListeners();
122: for (int nX = 0; nX < array.length; nX++) {
123: final IPropertyListener l = (IPropertyListener) array[nX];
124: Platform.run(new SafeRunnable() {
125:
126: public void run() {
127: l.propertyChanged(this , propertyId);
128: }
129: });
130: }
131: }
132:
133: /**
134: * This implementation of the method declared by <code>IAdaptable</code>
135: * passes the request along to the platform's adapter manager; roughly
136: * <code>Platform.getAdapterManager().getAdapter(this, adapter)</code>.
137: * Subclasses may override this method (however, if they do so, they should
138: * invoke the method on their superclass to ensure that the Platform's
139: * adapter manager is consulted).
140: */
141: public Object getAdapter(Class adapter) {
142: return Platform.getAdapterManager().getAdapter(this , adapter);
143: }
144:
145: /**
146: * Returns the configuration element for this part. The configuration
147: * element comes from the plug-in registry entry for the extension defining
148: * this part.
149: *
150: * @return the configuration element for this part
151: */
152: protected IConfigurationElement getConfigurationElement() {
153: return configElement;
154: }
155:
156: /**
157: * Returns the default title image.
158: *
159: * @return the default image
160: */
161: protected Image getDefaultImage() {
162: return PlatformUI.getWorkbench().getSharedImages().getImage(
163: ISharedImages.IMG_DEF_VIEW);
164: }
165:
166: /*
167: * (non-Javadoc)
168: *
169: * @see org.eclipse.ui.intro.IIntroPart#getIntroSite()
170: */
171: public final IIntroSite getIntroSite() {
172: return partSite;
173: }
174:
175: /* (non-Javadoc)
176: * @see org.eclipse.ui.intro.IIntroPart#getTitleImage()
177: */
178: public Image getTitleImage() {
179: if (titleImage != null) {
180: return titleImage;
181: }
182: return getDefaultImage();
183: }
184:
185: /* (non-Javadoc)
186: * @see org.eclipse.ui.intro.IIntroPart#getTitle()
187: */
188: public String getTitle() {
189: if (titleLabel != null) {
190: return titleLabel;
191: }
192: return getDefaultTitle();
193: }
194:
195: /**
196: * Return the default title string.
197: *
198: * @return the default title string
199: */
200: private String getDefaultTitle() {
201: return IntroMessages.Intro_default_title;
202: }
203:
204: /**
205: * The base implementation of this {@link org.eclipse.ui.intro.IIntroPart}method ignores the
206: * memento and initializes the part in a fresh state. Subclasses may extend
207: * to perform any state restoration, but must call the super method.
208: *
209: * @param site
210: * the intro site
211: * @param memento
212: * the intro part state or <code>null</code> if there is no
213: * previous saved state
214: * @exception PartInitException
215: * if this part was not initialized successfully
216: */
217: public void init(IIntroSite site, IMemento memento)
218: throws PartInitException {
219: setSite(site);
220: }
221:
222: /**
223: * Sets the part site.
224: * <p>
225: * Subclasses must invoke this method from {@link org.eclipse.ui.intro.IIntroPart#init(IIntroSite, IMemento)}.
226: * </p>
227: *
228: * @param site the intro part site
229: */
230: protected void setSite(IIntroSite site) {
231: this .partSite = site;
232: }
233:
234: /* (non-Javadoc)
235: * @see org.eclipse.ui.intro.IIntroPart#removePropertyListener(org.eclipse.ui.IPropertyListener)
236: */
237: public void removePropertyListener(IPropertyListener l) {
238: removeListenerObject(l);
239: }
240:
241: /**
242: * The base implementation of this {@link org.eclipse.ui.intro.IIntroPart} method does nothing.
243: * Subclasses may override.
244: *
245: * @param memento
246: * a memento to receive the object state
247: */
248: public void saveState(IMemento memento) {
249: //no-op
250: }
251:
252: /*
253: * (non-Javadoc) Asks this part to take focus within the workbench.
254: * <p>
255: * Subclasses must implement this method. For a detailed description of the
256: * requirements see <code>IIntroPart</code>
257: * </p>
258: *
259: * @see IIntroPart
260: */
261: public abstract void setFocus();
262:
263: /**
264: * The <code>IntroPart</code> implementation of this
265: * <code>IExecutableExtension</code> records the configuration element in
266: * and internal state variable (accessible via <code>getConfigElement</code>).
267: * It also loads the title image, if one is specified in the configuration
268: * element. Subclasses may extend.
269: *
270: * Should not be called by clients. It is called by the core plugin when
271: * creating this executable extension.
272: */
273: public void setInitializationData(IConfigurationElement cfig,
274: String propertyName, Object data) {
275:
276: // Save config element.
277: configElement = cfig;
278:
279: titleLabel = cfig
280: .getAttribute(IWorkbenchRegistryConstants.ATT_LABEL);
281:
282: // Icon.
283: String strIcon = cfig
284: .getAttribute(IWorkbenchRegistryConstants.ATT_ICON);
285: if (strIcon == null) {
286: return;
287: }
288:
289: imageDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin(
290: configElement.getNamespace(), strIcon);
291:
292: if (imageDescriptor == null) {
293: return;
294: }
295:
296: Image image = JFaceResources.getResources()
297: .createImageWithDefault(imageDescriptor);
298: titleImage = image;
299: }
300:
301: /**
302: * Sets or clears the title image of this part.
303: *
304: * @param titleImage
305: * the title image, or <code>null</code> to clear
306: */
307: protected void setTitleImage(Image titleImage) {
308: Assert.isTrue(titleImage == null || !titleImage.isDisposed());
309: //Do not send changes if they are the same
310: if (this .titleImage == titleImage) {
311: return;
312: }
313: this .titleImage = titleImage;
314: firePropertyChange(IIntroPart.PROP_TITLE);
315: }
316:
317: /**
318: * Set the title string for this part.
319: *
320: * @param titleLabel the title string. Must not be <code>null</code>.
321: * @since 3.2
322: */
323: protected void setTitle(String titleLabel) {
324: Assert.isNotNull(titleLabel);
325: if (Util.equals(this.titleLabel, titleLabel))
326: return;
327: this.titleLabel = titleLabel;
328: firePropertyChange(IIntroPart.PROP_TITLE);
329: }
330: }
|