001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 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.jface.wizard;
011:
012: import java.util.ArrayList;
013: import java.util.List;
014:
015: import org.eclipse.core.runtime.Assert;
016: import org.eclipse.jface.dialogs.IDialogSettings;
017: import org.eclipse.jface.resource.ImageDescriptor;
018: import org.eclipse.jface.resource.JFaceResources;
019: import org.eclipse.swt.graphics.Image;
020: import org.eclipse.swt.graphics.RGB;
021: import org.eclipse.swt.widgets.Composite;
022: import org.eclipse.swt.widgets.Shell;
023:
024: /**
025: * An abstract base implementation of a wizard. A typical client subclasses
026: * <code>Wizard</code> to implement a particular wizard.
027: * <p>
028: * Subclasses may call the following methods to configure the wizard:
029: * <ul>
030: * <li><code>addPage</code></li>
031: * <li><code>setHelpAvailable</code></li>
032: * <li><code>setDefaultPageImageDescriptor</code></li>
033: * <li><code>setDialogSettings</code></li>
034: * <li><code>setNeedsProgressMonitor</code></li>
035: * <li><code>setTitleBarColor</code></li>
036: * <li><code>setWindowTitle</code></li>
037: * </ul>
038: * </p>
039: * <p>
040: * Subclasses may override these methods if required:
041: * <ul>
042: * <li>reimplement <code>createPageControls</code></li>
043: * <li>reimplement <code>performCancel</code></li>
044: * <li>extend <code>addPages</code></li>
045: * <li>reimplement <code>performFinish</code></li>
046: * <li>extend <code>dispose</code></li>
047: * </ul>
048: * </p>
049: * <p>
050: * Note that clients are free to implement <code>IWizard</code> from scratch
051: * instead of subclassing <code>Wizard</code>. Correct implementations of
052: * <code>IWizard</code> will work with any correct implementation of
053: * <code>IWizardPage</code>.
054: * </p>
055: */
056: public abstract class Wizard implements IWizard {
057: /**
058: * Image registry key of the default image for wizard pages (value
059: * <code>"org.eclipse.jface.wizard.Wizard.pageImage"</code>).
060: */
061: public static final String DEFAULT_IMAGE = "org.eclipse.jface.wizard.Wizard.pageImage";//$NON-NLS-1$
062:
063: /**
064: * The wizard container this wizard belongs to; <code>null</code> if none.
065: */
066: private IWizardContainer container = null;
067:
068: /**
069: * This wizard's list of pages (element type: <code>IWizardPage</code>).
070: */
071: private List pages = new ArrayList();
072:
073: /**
074: * Indicates whether this wizard needs a progress monitor.
075: */
076: private boolean needsProgressMonitor = false;
077:
078: /**
079: * Indicates whether this wizard needs previous and next buttons even if the
080: * wizard has only one page.
081: */
082: private boolean forcePreviousAndNextButtons = false;
083:
084: /**
085: * Indicates whether this wizard supports help.
086: */
087: private boolean isHelpAvailable = false;
088:
089: /**
090: * The default page image for pages without one of their one;
091: * <code>null</code> if none.
092: */
093: private Image defaultImage = null;
094:
095: /**
096: * The default page image descriptor, used for creating a default page image
097: * if required; <code>null</code> if none.
098: */
099: private ImageDescriptor defaultImageDescriptor = JFaceResources
100: .getImageRegistry().getDescriptor(DEFAULT_IMAGE);
101:
102: /**
103: * The color of the wizard title bar; <code>null</code> if none.
104: */
105: private RGB titleBarColor = null;
106:
107: /**
108: * The window title string for this wizard; <code>null</code> if none.
109: */
110: private String windowTitle = null;
111:
112: /**
113: * The dialog settings for this wizard; <code>null</code> if none.
114: */
115: private IDialogSettings dialogSettings = null;
116:
117: /**
118: * Creates a new empty wizard.
119: */
120: protected Wizard() {
121: super ();
122: }
123:
124: /**
125: * Adds a new page to this wizard. The page is inserted at the end of the
126: * page list.
127: *
128: * @param page
129: * the new page
130: */
131: public void addPage(IWizardPage page) {
132: pages.add(page);
133: page.setWizard(this );
134: }
135:
136: /**
137: * The <code>Wizard</code> implementation of this <code>IWizard</code>
138: * method does nothing. Subclasses should extend if extra pages need to be
139: * added before the wizard opens. New pages should be added by calling
140: * <code>addPage</code>.
141: */
142: public void addPages() {
143: }
144:
145: /*
146: * (non-Javadoc) Method declared on IWizard.
147: */
148: public boolean canFinish() {
149: // Default implementation is to check if all pages are complete.
150: for (int i = 0; i < pages.size(); i++) {
151: if (!((IWizardPage) pages.get(i)).isPageComplete()) {
152: return false;
153: }
154: }
155: return true;
156: }
157:
158: /**
159: * The <code>Wizard</code> implementation of this <code>IWizard</code>
160: * method creates all the pages controls using
161: * <code>IDialogPage.createControl</code>. Subclasses should reimplement
162: * this method if they want to delay creating one or more of the pages
163: * lazily. The framework ensures that the contents of a page will be created
164: * before attempting to show it.
165: */
166: public void createPageControls(Composite pageContainer) {
167: // the default behavior is to create all the pages controls
168: for (int i = 0; i < pages.size(); i++) {
169: IWizardPage page = (IWizardPage) pages.get(i);
170: page.createControl(pageContainer);
171: // page is responsible for ensuring the created control is
172: // accessable
173: // via getControl.
174: Assert.isNotNull(page.getControl());
175: }
176: }
177:
178: /**
179: * The <code>Wizard</code> implementation of this <code>IWizard</code>
180: * method disposes all the pages controls using
181: * <code>DialogPage.dispose</code>. Subclasses should extend this method
182: * if the wizard instance maintains addition SWT resource that need to be
183: * disposed.
184: */
185: public void dispose() {
186: // notify pages
187: for (int i = 0; i < pages.size(); i++) {
188: ((IWizardPage) pages.get(i)).dispose();
189: }
190: // dispose of image
191: if (defaultImage != null) {
192: JFaceResources.getResources().destroyImage(
193: defaultImageDescriptor);
194: defaultImage = null;
195: }
196: }
197:
198: /*
199: * (non-Javadoc) Method declared on IWizard.
200: */
201: public IWizardContainer getContainer() {
202: return container;
203: }
204:
205: /*
206: * (non-Javadoc) Method declared on IWizard.
207: */
208: public Image getDefaultPageImage() {
209: if (defaultImage == null) {
210: defaultImage = JFaceResources.getResources()
211: .createImageWithDefault(defaultImageDescriptor);
212: }
213: return defaultImage;
214: }
215:
216: /*
217: * (non-Javadoc) Method declared on IWizard.
218: */
219: public IDialogSettings getDialogSettings() {
220: return dialogSettings;
221: }
222:
223: /*
224: * (non-Javadoc) Method declared on IWizard. The default behavior is to
225: * return the page that was added to this wizard after the given page.
226: */
227: public IWizardPage getNextPage(IWizardPage page) {
228: int index = pages.indexOf(page);
229: if (index == pages.size() - 1 || index == -1) {
230: // last page or page not found
231: return null;
232: }
233: return (IWizardPage) pages.get(index + 1);
234: }
235:
236: /*
237: * (non-Javadoc) Method declared on IWizard.
238: */
239: public IWizardPage getPage(String name) {
240: for (int i = 0; i < pages.size(); i++) {
241: IWizardPage page = (IWizardPage) pages.get(i);
242: String pageName = page.getName();
243: if (pageName.equals(name)) {
244: return page;
245: }
246: }
247: return null;
248: }
249:
250: /*
251: * (non-Javadoc) Method declared on IWizard.
252: */
253: public int getPageCount() {
254: return pages.size();
255: }
256:
257: /*
258: * (non-Javadoc) Method declared on IWizard.
259: */
260: public IWizardPage[] getPages() {
261: return (IWizardPage[]) pages.toArray(new IWizardPage[pages
262: .size()]);
263: }
264:
265: /*
266: * (non-Javadoc) Method declared on IWizard. The default behavior is to
267: * return the page that was added to this wizard before the given page.
268: */
269: public IWizardPage getPreviousPage(IWizardPage page) {
270: int index = pages.indexOf(page);
271: if (index == 0 || index == -1) {
272: // first page or page not found
273: return null;
274: }
275: return (IWizardPage) pages.get(index - 1);
276: }
277:
278: /**
279: * Returns the wizard's shell if the wizard is visible. Otherwise
280: * <code>null</code> is returned.
281: *
282: * @return Shell
283: */
284: public Shell getShell() {
285: if (container == null) {
286: return null;
287: }
288: return container.getShell();
289: }
290:
291: /*
292: * (non-Javadoc) Method declared on IWizard. By default this is the first
293: * page inserted into the wizard.
294: */
295: public IWizardPage getStartingPage() {
296: if (pages.size() == 0) {
297: return null;
298: }
299: return (IWizardPage) pages.get(0);
300: }
301:
302: /*
303: * (non-Javadoc) Method declared on IWizard.
304: */
305: public RGB getTitleBarColor() {
306: return titleBarColor;
307: }
308:
309: /*
310: * (non-Javadoc) Method declared on IWizard.
311: */
312: public String getWindowTitle() {
313: return windowTitle;
314: }
315:
316: /*
317: * (non-Javadoc) Method declared on IWizard.
318: */
319: public boolean isHelpAvailable() {
320: return isHelpAvailable;
321: }
322:
323: /*
324: * (non-Javadoc) Method declared on IWizard.
325: */
326: public boolean needsPreviousAndNextButtons() {
327: return forcePreviousAndNextButtons || pages.size() > 1;
328: }
329:
330: /*
331: * (non-Javadoc) Method declared on IWizard.
332: */
333: public boolean needsProgressMonitor() {
334: return needsProgressMonitor;
335: }
336:
337: /**
338: * The <code>Wizard</code> implementation of this <code>IWizard</code>
339: * method does nothing and returns <code>true</code>. Subclasses should
340: * reimplement this method if they need to perform any special cancel
341: * processing for their wizard.
342: */
343: public boolean performCancel() {
344: return true;
345: }
346:
347: /**
348: * Subclasses must implement this <code>IWizard</code> method to perform
349: * any special finish processing for their wizard.
350: */
351: public abstract boolean performFinish();
352:
353: /*
354: * (non-Javadoc) Method declared on IWizard.
355: */
356: public void setContainer(IWizardContainer wizardContainer) {
357: container = wizardContainer;
358: }
359:
360: /**
361: * Sets the default page image descriptor for this wizard.
362: * <p>
363: * This image descriptor will be used to generate an image for a page with
364: * no image of its own; the image will be computed once and cached.
365: * </p>
366: *
367: * @param imageDescriptor
368: * the default page image descriptor
369: */
370: public void setDefaultPageImageDescriptor(
371: ImageDescriptor imageDescriptor) {
372: defaultImageDescriptor = imageDescriptor;
373: }
374:
375: /**
376: * Sets the dialog settings for this wizard.
377: * <p>
378: * The dialog settings is used to record state between wizard invocations
379: * (for example, radio button selection, last import directory, etc.)
380: * </p>
381: *
382: * @param settings
383: * the dialog settings, or <code>null</code> if none
384: * @see #getDialogSettings
385: *
386: */
387: public void setDialogSettings(IDialogSettings settings) {
388: dialogSettings = settings;
389: }
390:
391: /**
392: * Controls whether the wizard needs Previous and Next buttons even if it
393: * currently contains only one page.
394: * <p>
395: * This flag should be set on wizards where the first wizard page adds
396: * follow-on wizard pages based on user input.
397: * </p>
398: *
399: * @param b
400: * <code>true</code> to always show Next and Previous buttons,
401: * and <code>false</code> to suppress Next and Previous buttons
402: * for single page wizards
403: */
404: public void setForcePreviousAndNextButtons(boolean b) {
405: forcePreviousAndNextButtons = b;
406: }
407:
408: /**
409: * Sets whether help is available for this wizard.
410: * <p>
411: * The result of this method is typically used by the container to show or
412: * hide the Help button.
413: * </p>
414: *
415: * @param b
416: * <code>true</code> if help is available, and
417: * <code>false</code> if this wizard is helpless
418: * @see #isHelpAvailable()
419: */
420: public void setHelpAvailable(boolean b) {
421: isHelpAvailable = b;
422: }
423:
424: /**
425: * Sets whether this wizard needs a progress monitor.
426: *
427: * @param b
428: * <code>true</code> if a progress monitor is required, and
429: * <code>false</code> if none is needed
430: * @see #needsProgressMonitor()
431: */
432: public void setNeedsProgressMonitor(boolean b) {
433: needsProgressMonitor = b;
434: }
435:
436: /**
437: * Sets the title bar color for this wizard.
438: *
439: * @param color
440: * the title bar color
441: */
442: public void setTitleBarColor(RGB color) {
443: titleBarColor = color;
444: }
445:
446: /**
447: * Sets the window title for the container that hosts this page to the given
448: * string.
449: *
450: * @param newTitle
451: * the window title for the container
452: */
453: public void setWindowTitle(String newTitle) {
454: windowTitle = newTitle;
455: if (container != null) {
456: container.updateWindowTitle();
457: }
458: }
459: }
|