| /******************************************************************************* |
| * Copyright (c) 2000, 2005 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 |
| * Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog font should be |
| * activated and used by other components. |
| *******************************************************************************/ |
| package org.eclipse.ui.internal.ide.dialogs; |
| |
| import java.lang.reflect.InvocationTargetException; |
| |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.wizard.IWizard; |
| import org.eclipse.jface.wizard.IWizardContainer; |
| import org.eclipse.jface.wizard.IWizardPage; |
| import org.eclipse.jface.wizard.WizardPage; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.BusyIndicator; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.ide.IIDEHelpContextIds; |
| import org.eclipse.ui.internal.ide.misc.WizardStepGroup; |
| |
| /** |
| * This page allows the user to go thru a series of steps. Each |
| * step that has a wizard will have its pages embedded into this |
| * page. At the end, the step will be asked to complete its work. |
| * <p> |
| * Example usage: |
| * <pre> |
| * mainPage = new MultiStepConfigureWizardPage("multiStepWizardPage"); |
| * mainPage.setTitle("Project"); |
| * mainPage.setDescription("Configure project capability."); |
| * </pre> |
| * </p> |
| */ |
| public class MultiStepConfigureWizardPage extends WizardPage { |
| private MultiStepWizardDialog wizardDialog; |
| |
| private Composite pageSite; |
| |
| private WizardStepGroup stepGroup; |
| |
| private WizardStepContainer stepContainer = new WizardStepContainer(); |
| |
| /** |
| * Creates a new multi-step wizard page. |
| * |
| * @param pageName the name of this page |
| */ |
| public MultiStepConfigureWizardPage(String pageName) { |
| super(pageName); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWizardPage |
| */ |
| public boolean canFlipToNextPage() { |
| return stepContainer.canFlipToNextPage(); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IDialogPage. |
| */ |
| public void createControl(Composite parent) { |
| Composite composite = new Composite(parent, SWT.NULL); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| composite.setLayout(layout); |
| composite.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| composite.setFont(parent.getFont()); |
| |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, |
| IIDEHelpContextIds.NEW_PROJECT_CONFIGURE_WIZARD_PAGE); |
| |
| createStepGroup(composite); |
| createEmbeddedPageSite(composite); |
| |
| setControl(composite); |
| } |
| |
| /** |
| * Creates the control where the step's wizard will |
| * display its pages. |
| */ |
| private void createEmbeddedPageSite(Composite parent) { |
| pageSite = new Composite(parent, SWT.NONE); |
| pageSite.setLayout(new GridLayout()); |
| pageSite.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| } |
| |
| /** |
| * Creates the control for the step list |
| */ |
| private void createStepGroup(Composite parent) { |
| stepGroup = new WizardStepGroup(); |
| stepGroup.createContents(parent); |
| } |
| |
| /** |
| * Returns the container handler for the pages |
| * of the step's wizard. |
| */ |
| /* package */WizardStepContainer getStepContainer() { |
| return stepContainer; |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IDialogPage. |
| */ |
| public String getMessage() { |
| String msg = stepContainer.getMessage(); |
| if (msg == null || msg.length() == 0) |
| msg = super.getMessage(); |
| return msg; |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWizardPage. |
| */ |
| public IWizardPage getPreviousPage() { |
| return stepContainer.getPreviousPage(); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWizardPage. |
| */ |
| public void setPreviousPage(IWizardPage page) { |
| // Do not allow to go back |
| super.setPreviousPage(null); |
| } |
| |
| /** |
| * Sets the steps to be displayed. Ignored if the |
| * createControl has not been called yet. |
| * |
| * @param steps the collection of steps |
| */ |
| /* package */void setSteps(WizardStep[] steps) { |
| if (stepGroup != null) |
| stepGroup.setSteps(steps); |
| } |
| |
| /** |
| * Sets the multi-step wizard dialog processing this |
| * page. |
| */ |
| /* package */void setWizardDialog(MultiStepWizardDialog dialog) { |
| wizardDialog = dialog; |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IDialogPage. |
| */ |
| public void setVisible(boolean visible) { |
| super.setVisible(visible); |
| WizardStep[] steps = stepGroup.getSteps(); |
| MultiStepWizard stepWizard = wizardDialog.getMultiStepWizard(); |
| wizardDialog.setFinishLabel(stepWizard.getFinishStepLabel(steps)); |
| |
| getControl().getDisplay().asyncExec(new Runnable() { |
| public void run() { |
| stepContainer.processCurrentStep(); |
| } |
| }); |
| } |
| |
| /** |
| * Support for handling pages from the step's wizard |
| */ |
| /* package */class WizardStepContainer implements IWizardContainer { |
| private int stepIndex = 0; |
| |
| private IWizard wizard; |
| |
| private IWizardPage currentPage; |
| |
| /* (non-Javadoc) |
| * Method declared on IRunnableContext. |
| */ |
| public void run(boolean fork, boolean cancelable, |
| IRunnableWithProgress runnable) |
| throws InvocationTargetException, InterruptedException { |
| getContainer().run(fork, cancelable, runnable); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWizardContainer. |
| */ |
| public IWizardPage getCurrentPage() { |
| return currentPage; |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWizardContainer. |
| */ |
| public Shell getShell() { |
| return getContainer().getShell(); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWizardContainer. |
| */ |
| public void showPage(IWizardPage page) { |
| showPage(page, true); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWizardContainer. |
| */ |
| public void updateButtons() { |
| getContainer().updateButtons(); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWizardContainer. |
| */ |
| public void updateMessage() { |
| getContainer().updateMessage(); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWizardContainer. |
| */ |
| public void updateTitleBar() { |
| getContainer().updateTitleBar(); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWizardContainer. |
| */ |
| public void updateWindowTitle() { |
| getContainer().updateWindowTitle(); |
| } |
| |
| /** |
| * Handles the back button pressed |
| */ |
| public void backPressed() { |
| showPage(currentPage.getPreviousPage(), false); |
| } |
| |
| /** |
| * Handles the next button pressed |
| */ |
| public void nextPressed() { |
| showPage(currentPage.getNextPage(), true); |
| } |
| |
| /** |
| * Handles the help button pressed |
| */ |
| public void helpPressed() { |
| if (currentPage != null) |
| currentPage.performHelp(); |
| } |
| |
| /** |
| * Handles close request. |
| * |
| * @return the result |
| */ |
| public final boolean performCancel() { |
| if (wizard != null) |
| return wizard.performCancel(); |
| |
| return true; |
| } |
| |
| /** |
| * Handles finish request. |
| * |
| * @return the result |
| */ |
| public final boolean performFinish() { |
| if (wizard != null) { |
| if (wizard.performFinish()) { |
| wizard.dispose(); |
| wizard.setContainer(null); |
| stepGroup.markStepAsDone(); |
| stepIndex++; |
| return true; |
| } |
| return false; |
| } |
| return true; |
| |
| } |
| |
| /** |
| * Calculates the difference in size between the given |
| * page and the page site. A larger page results |
| * in a positive delta. |
| * |
| * @param page the page |
| * @return the size difference encoded |
| * as a <code>new Point(deltaWidth,deltaHeight)</code> |
| */ |
| private Point calculatePageSizeDelta(IWizardPage page) { |
| Control pageControl = page.getControl(); |
| |
| if (pageControl == null) |
| // control not created yet |
| return new Point(0, 0); |
| |
| Point contentSize = pageControl.computeSize(SWT.DEFAULT, |
| SWT.DEFAULT, true); |
| Rectangle rect = pageSite.getClientArea(); |
| Point containerSize = new Point(rect.width, rect.height); |
| |
| return new Point(Math.max(0, contentSize.x - containerSize.x), Math |
| .max(0, contentSize.y - containerSize.y)); |
| } |
| |
| /** |
| * Computes the correct page site size for the given page |
| * and resizes the dialog if nessessary. |
| * |
| * @param page the wizard page |
| */ |
| private void updateSizeForPage(IWizardPage page) { |
| // ensure the page container is large enough |
| Point delta = calculatePageSizeDelta(page); |
| |
| if (delta.x > 0 || delta.y > 0) { |
| Point siteSize = pageSite.getSize(); |
| GridData data = (GridData) pageSite.getLayoutData(); |
| data.heightHint = siteSize.y + delta.y; |
| data.widthHint = siteSize.x + delta.x; |
| } |
| } |
| |
| /** |
| * Computes the correct page site size for the given wizard |
| * and resizes the dialog if nessessary. |
| * |
| * @param wizard the wizard |
| */ |
| private void updateSizeForWizard(IWizard wizard) { |
| Point delta = new Point(0, 0); |
| IWizardPage[] pages = wizard.getPages(); |
| for (int i = 0; i < pages.length; i++) { |
| // ensure the page site is large enough |
| Point pageDelta = calculatePageSizeDelta(pages[i]); |
| |
| delta.x = Math.max(delta.x, pageDelta.x); |
| delta.y = Math.max(delta.y, pageDelta.y); |
| } |
| |
| if (delta.x > 0 || delta.y > 0) { |
| Point siteSize = pageSite.getSize(); |
| GridData data = (GridData) pageSite.getLayoutData(); |
| data.heightHint = siteSize.y + delta.y; |
| data.widthHint = siteSize.x + delta.x; |
| } |
| } |
| |
| /** |
| * Process the current step's wizard. |
| */ |
| public void processCurrentStep() { |
| WizardStep[] steps = stepGroup.getSteps(); |
| while (stepIndex < steps.length) { |
| // adjust the finish button label |
| if (stepIndex == (steps.length - 1)) |
| wizardDialog.setFinishLabel(null); |
| |
| final WizardStep step = steps[stepIndex]; |
| stepGroup.setCurrentStep(step); |
| |
| final IWizard[] stepWizard = new IWizard[1]; |
| BusyIndicator.showWhile(getShell().getDisplay(), |
| new Runnable() { |
| public void run() { |
| stepWizard[0] = step.getWizard(); |
| int tries = 0; |
| while (stepWizard[0] == null && tries++ < 3) { |
| boolean tryAgain = wizardDialog |
| .getMultiStepWizard() |
| .handleMissingStepWizard(step); |
| if (!tryAgain) |
| break; |
| |
| stepWizard[0] = step.getWizard(); |
| } |
| } |
| }); |
| |
| if (stepWizard[0] == null) |
| break; |
| setWizard(stepWizard[0]); |
| if (stepWizard[0].getPageCount() > 0) |
| return; |
| |
| performFinish(); |
| } |
| |
| wizardDialog.forceClose(); |
| } |
| |
| /** |
| * Sets the current wizard. |
| * |
| * @param newWizard the current wizard |
| */ |
| public void setWizard(IWizard newWizard) { |
| wizard = newWizard; |
| |
| // Allow the wizard pages to precreate their page controls |
| // This allows the wizard to open to the correct size |
| wizard.createPageControls(pageSite); |
| |
| // Ensure that all of the created pages are initially not visible |
| IWizardPage[] pages = wizard.getPages(); |
| for (int i = 0; i < pages.length; i++) { |
| IWizardPage page = pages[i]; |
| if (page.getControl() != null) |
| page.getControl().setVisible(false); |
| } |
| |
| // Ensure the dialog is large enough for the wizard |
| updateSizeForWizard(wizard); |
| wizardDialog.updateLayout(); |
| |
| wizard.setContainer(this); |
| showPage(wizard.getStartingPage(), false); |
| } |
| |
| /** |
| * Show the requested page. |
| * |
| * @param page the page |
| * @param rememberPrevious whether hte previous page should be remembered |
| */ |
| public void showPage(IWizardPage page, boolean rememberPrevious) { |
| if (page == null || page == currentPage) |
| return; |
| |
| if (rememberPrevious && currentPage != null) |
| page.setPreviousPage(currentPage); |
| |
| if (wizard != page.getWizard()) { |
| throw new IllegalStateException(); |
| } |
| |
| // ensure that page control has been created |
| // (this allows lazy page control creation) |
| if (page.getControl() == null) { |
| page.createControl(pageSite); |
| // the page is responsible for ensuring the created control is accessable |
| // via getControl. |
| if (page.getControl() == null) { |
| throw new IllegalArgumentException(); |
| } |
| // ensure the dialog is large enough for this page |
| updateSizeForPage(page); |
| wizardDialog.updateLayout(); |
| } |
| |
| // make the new page visible |
| IWizardPage oldPage = currentPage; |
| currentPage = page; |
| currentPage.setVisible(true); |
| if (oldPage != null) |
| oldPage.setVisible(false); |
| page.getControl().setBounds(pageSite.getClientArea()); |
| |
| // update the dialog controls |
| wizardDialog.updateAll(); |
| } |
| |
| /** |
| * Returns whether the current wizard can finish. |
| * |
| * @return whether the wizard can finish |
| */ |
| public boolean canWizardFinish() { |
| if (wizard != null) |
| return wizard.canFinish(); |
| |
| return false; |
| } |
| |
| /** |
| * Returns whether the current page can flip to |
| * the next page. |
| * |
| * @return can flip to next page |
| */ |
| public boolean canFlipToNextPage() { |
| if (currentPage != null) |
| return currentPage.canFlipToNextPage(); |
| return false; |
| } |
| |
| /** |
| * Returns the current page's message. |
| * |
| * @return the message |
| */ |
| public String getMessage() { |
| if (currentPage != null) |
| return currentPage.getMessage(); |
| |
| return null; |
| } |
| |
| /** |
| * Returns the current page's previous page. |
| * |
| * @return the page |
| */ |
| public IWizardPage getPreviousPage() { |
| if (currentPage != null) |
| return currentPage.getPreviousPage(); |
| |
| return null; |
| } |
| } |
| } |