All Downloads are FREE. Search and download functionalities are using the official Maven repository.

at.spardat.xma.page.WizardPageClient Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2003, 2009 s IT Solutions AT Spardat GmbH .
 * 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:
 *     s IT Solutions AT Spardat GmbH - initial API and implementation
 *******************************************************************************/
package at.spardat.xma.page;

import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import at.spardat.xma.boot.component.IXMAControl;
import at.spardat.xma.component.ComponentClient;

/**
 * Client half base class for the wizard frame.
 * To use this class/functionality create a new WizardPage with the XMA GUI designer,
 * create the subpages you need as embedded pages and either call setPageInfos() or
 * override getNextPageInfo().
 * @author laslovd
 * @since 2.1.0
 */
public abstract class WizardPageClient extends DialogPage {

    private static final Color COLOR_WHITE = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);

    protected Composite compositeExplanationW;
    protected Label labelExplanationTitle;
    protected Label labelExplanationText;
    protected Label labelExplanationImage;
    protected Label sep1W;
    protected Composite compositeButtonsW;
    protected Button buttonBackW;
    protected Button buttonNextW;
    protected Button buttonFinishW;
    protected Button buttonCancelW;
    protected Label sep2W;
    protected Composite compositeContentW;

    private WizardSubPageInfo actPageInfo = null;
    private String stepOfText;
    private ResourceBundle messages;
    private List pageInfoList = null;

    /**
     * Initializes a WizardPageClient inside the same Component as the parent PageClient.
     *
     * @param parent the PageClient calling this DialogPage.
     * @param stateless indicating if this page is stateless on the server.
     * @param style The SWT-Style for the Shell of the DialogPage.
     */
    public WizardPageClient(PageClient parent, boolean stateless, int style) {
        super(parent,stateless,style);
    }

    /**
     * Initializes a WizardPageClient inside inside a given Component.
     *
     * @param component the Component containing the DialogPage.
     * @param style The SWT-Style for the Shell of the DialogPage.
     * @param stateless indicating if this page is stateless on the server.
     * @throws IllegalArgumentException if component is null.
     */
    public WizardPageClient(ComponentClient component, boolean stateless, int style) {
        super(component,stateless,style);
    }

    /**
     * Initializes a WizardPageClient inside the same Component as the parent PageClient.
     *
     * @param parent the PageClient calling this DialogPage.
     * @param stateless indicating if this page is stateless on the server.
     * @param style The SWT-Style for the Shell of the DialogPage.
     */
    public WizardPageClient(ComponentClient component, Shell parentShell, boolean stateless, int style) {
        super(component,parentShell,stateless,style);
    }

    /**
     * Creates Widgets and layout
     * @see at.spardat.xma.page.DialogPage#initGUI()
     */
    public void initGUI() {
        super.initGUI();
        FormData data;
        Control[] tabOrder;
        EventAdapter adapter = new EventAdapter(this);
        Locale locale = getComponent().getContext().getLocale();
        messages = ResourceBundle.getBundle("at.spardat.xma.page.PageTexts",locale);
        stepOfText = messages.getString("WizardPage.stepOf");

        final Scaler scaler = Scaler.getInstance(getComposite());
        Composite wizardPageCompW = getComposite();

        compositeExplanationW = new Composite(wizardPageCompW,SWT.NONE);
        FormLayout layout = new FormLayout();
        layout.marginHeight = scaler.convertYToCurrent(0);
        layout.marginWidth = scaler.convertXToCurrent(0);
        compositeExplanationW.setLayout(layout);
        compositeExplanationW.setBackground(COLOR_WHITE);

        labelExplanationTitle = new Label(compositeExplanationW,SWT.LEFT);
        labelExplanationTitle.setText("");
        labelExplanationTitle.setBackground(COLOR_WHITE);
        labelExplanationTitle.setFont(getComponent().getFontByStyle(labelExplanationTitle.getFont(),SWT.BOLD));

        labelExplanationText = new Label(compositeExplanationW,SWT.LEFT);
        labelExplanationText.setText("");
        labelExplanationText.setBackground(COLOR_WHITE);

        labelExplanationImage = new Label(compositeExplanationW,SWT.LEFT);
        labelExplanationImage.setBackground(COLOR_WHITE);

        sep1W = new Label (compositeExplanationW,SWT.SEPARATOR|SWT.HORIZONTAL);

        compositeButtonsW = new Composite(wizardPageCompW,SWT.NONE);
        layout = new FormLayout();
        layout.marginHeight = scaler.convertYToCurrent(0);
        layout.marginWidth = scaler.convertXToCurrent(0);
        compositeButtonsW.setLayout(layout);

        buttonBackW = new Button (compositeButtonsW, SWT.PUSH|SWT.CENTER);
        buttonBackW.setText(messages.getString("WizardPage.buttonBackW"));
        buttonBackW.setEnabled(false);
        buttonBackW.addSelectionListener(adapter);

        buttonNextW = new Button (compositeButtonsW, SWT.PUSH|SWT.CENTER);
        buttonNextW.setText(messages.getString("WizardPage.buttonNextW"));
        buttonNextW.addSelectionListener(adapter);

        buttonFinishW = new Button (compositeButtonsW, SWT.PUSH|SWT.CENTER);
        buttonFinishW.setText(messages.getString("WizardPage.buttonFinishW"));
        buttonFinishW.setEnabled(false);
        buttonFinishW.addSelectionListener(adapter);

        buttonCancelW = new Button (compositeButtonsW, SWT.PUSH|SWT.CENTER);
        buttonCancelW.setText(messages.getString("WizardPage.buttonCancelW"));
        buttonCancelW.addSelectionListener(adapter);

        sep2W = new Label (compositeButtonsW,SWT.SEPARATOR|SWT.HORIZONTAL);

        compositeContentW = new Composite(wizardPageCompW,SWT.NONE);
        layout = new FormLayout();
        layout.marginHeight = scaler.convertYToCurrent(0);
        layout.marginWidth = scaler.convertXToCurrent(0);
        compositeContentW.setLayout(layout);

        mkLayout4ExplanationAndContentComposite(true);

        data = new FormData();
        data.left = new FormAttachment(0,100,scaler.convertXToCurrent(10));
        data.top = new FormAttachment(0,100,scaler.convertYToCurrent(10));
        labelExplanationTitle.setLayoutData(data);

        data = new FormData();
        data.left = new FormAttachment(0,100,scaler.convertXToCurrent(20));
        data.right = new FormAttachment(labelExplanationImage,scaler.convertXToCurrent(-3),SWT.LEFT);
        data.top = new FormAttachment(labelExplanationTitle,scaler.convertYToCurrent(3),SWT.BOTTOM);
        data.bottom = new FormAttachment(sep1W,scaler.convertYToCurrent(-3),SWT.TOP);
        labelExplanationText.setLayoutData(data);

        data = new FormData();
        data.width = scaler.convertXToCurrent(60);
        data.height = scaler.convertYToCurrent(60);
        data.right = new FormAttachment(100,100,scaler.convertXToCurrent(-6));
        data.top = new FormAttachment(0,100,scaler.convertYToCurrent(3));
        labelExplanationImage.setLayoutData(data);

        data = new FormData();
        data.left = new FormAttachment(0,100,scaler.convertXToCurrent(0));
        data.right = new FormAttachment(100,100,scaler.convertXToCurrent(0));
        data.top = new FormAttachment(labelExplanationImage,scaler.convertYToCurrent(6),SWT.BOTTOM);
        sep1W.setLayoutData(data);

        data = new FormData();
        data.left = new FormAttachment(0,100,scaler.convertXToCurrent(0));
        data.right = new FormAttachment(100,100,scaler.convertXToCurrent(0));
        data.bottom = new FormAttachment(100,100,scaler.convertYToCurrent(0));
        compositeButtonsW.setLayoutData(data);

        data = new FormData();
        data.width = scaler.convertXToCurrent(100);
        data.right = new FormAttachment(buttonNextW,scaler.convertXToCurrent(-6),SWT.LEFT);
        data.bottom = new FormAttachment(buttonCancelW,scaler.convertYToCurrent(0),SWT.BOTTOM);
        buttonBackW.setLayoutData(data);

        data = new FormData();
        data.width = scaler.convertXToCurrent(100);
        data.right = new FormAttachment(buttonFinishW,scaler.convertXToCurrent(-6),SWT.LEFT);
        data.bottom = new FormAttachment(buttonCancelW,scaler.convertYToCurrent(0),SWT.BOTTOM);
        buttonNextW.setLayoutData(data);

        data = new FormData();
        data.width = scaler.convertXToCurrent(100);
        data.right = new FormAttachment(buttonCancelW,scaler.convertXToCurrent(-6),SWT.LEFT);
        data.bottom = new FormAttachment(buttonCancelW,scaler.convertYToCurrent(0),SWT.BOTTOM);
        buttonFinishW.setLayoutData(data);

        data = new FormData();
        data.width = scaler.convertXToCurrent(100);
        data.right = new FormAttachment(100,100,scaler.convertXToCurrent(-3));
        data.bottom = new FormAttachment(100,100,scaler.convertYToCurrent(-3));
        buttonCancelW.setLayoutData(data);

        data = new FormData();
        data.left = new FormAttachment(0,100,scaler.convertXToCurrent(0));
        data.right = new FormAttachment(100,100,scaler.convertXToCurrent(0));
        data.bottom = new FormAttachment(buttonBackW,scaler.convertYToCurrent(-6),SWT.TOP);
        sep2W.setLayoutData(data);

        tabOrder = new Control[3];
        tabOrder[0] = compositeExplanationW;
        tabOrder[1] = compositeButtonsW;
        tabOrder[2] = compositeContentW;
        wizardPageCompW.setTabList(tabOrder);
        tabOrder = new Control[0];
        compositeExplanationW.setTabList(tabOrder);
        tabOrder = new Control[4];
        tabOrder[0] = buttonBackW;
        tabOrder[1] = buttonNextW;
        tabOrder[2] = buttonFinishW;
        tabOrder[3] = buttonCancelW;
        compositeButtonsW.setTabList(tabOrder);
        tabOrder = new Control[0];
        compositeContentW.setTabList(tabOrder);

        wizardPageCompW.layout();
    }

    /**
     * Remove all Widgets of the page after they have been disposed.
     */
    public void removeWidgets() {
        super.removeWidgetsBase();
        compositeExplanationW = null;
        labelExplanationTitle = null;
        labelExplanationText = null;
        labelExplanationImage = null;
        sep1W = null;
        compositeButtonsW = null;
        buttonBackW = null;
        buttonNextW = null;
        buttonFinishW = null;
        buttonCancelW = null;
        sep2W = null;
        compositeContentW = null;
    }

    /**
     * Calls the client event configured for the widget of the event.
     *
     * @param event the SWT-Event that happened.
     * @param type the type of the Event, as defined by the event type constants in class SWT.
     */
    protected void clientEventBase(SelectionEvent event,int type) {
        if (event.widget == buttonBackW) {
            buttonBackWEvent();
        } else if (event.widget == buttonNextW) {
            buttonNextWEvent();
        } else if (event.widget == buttonFinishW) {
            buttonFinishWEvent();
        } else if (event.widget == buttonCancelW) {
            buttonCancelWEvent();
        } else {
            super.clientEventBase(event,type);
        }
    }

    /**
     * Startup action. In this case especially changePage()
     * (and implicitly getNextPageInfo()) will be called the first time.
     * @see at.spardat.xma.page.PageClient#enterBase()
     */
    public void enterBase () {
        buttonFinishW.setEnabled(false);
        changePage(true);

        super.enterBase();
    }

    /**
     * Enables or disables Widgets according to the current state of the page.
     * This method is called every time the content of any WizardModel of the
     * Page may have been changed. 
* This method is called immediately after {@link #determineState()}. */ final public void stateChangedBaseImpl() { // if we have errors, the [next] button has to be disabled buttonNextW.setEnabled ( getDialog().getErrorCount() < 1 && actPageInfo != null && ! actPageInfo.isLastPage ); buttonFinishW.setEnabled( getDialog().getErrorCount() < 1 && actPageInfo != null && (actPageInfo.isLastPage || actPageInfo.mayCompletePremature)); buttonBackW.setEnabled (actPageInfo != null && ! actPageInfo.isFirstPage); if ( actPageInfo.isLastPage ) getShell().setDefaultButton(buttonFinishW); else getShell().setDefaultButton(buttonNextW); super.stateChangedBaseImpl(); } /** * This method will be called every time the user clicks on buttonBackW. */ protected void buttonBackWEvent() { changePage(false); } /** * This method will be called every time the user clicks on buttonNextW. */ protected void buttonNextWEvent() { changePage(true); } /** * This method will be called every time the user clicks on buttonFinishW. */ protected void buttonFinishWEvent() { newRemoteCall("finish").execute(); closeOK(); } /** * This method will be called every time the user clicks on buttonCancelW. */ protected void buttonCancelWEvent() { closeCancel(); } /** * Does all what is necessary to move to the next or previous page * (or the first one on startup). * @param nextPressed direction in the wizard flow */ private void changePage ( boolean nextPressed ) { WizardSubPageInfo newPageInfo; try { newPageInfo = getNextPageInfo(actPageInfo,nextPressed); if ( newPageInfo == null ) return; } catch ( Exception ex ) { showException(ex); return; } if ( actPageInfo != null ) removeChild(actPageInfo.page); actPageInfo = newPageInfo; Composite compW = ((IXMAControl) actPageInfo.page).createComposite(compositeContentW); FormData data = new FormData(); data.left = new FormAttachment(0,0); data.right = new FormAttachment(100,0); data.top = new FormAttachment(0,0); data.bottom = new FormAttachment(100,0); compW.setLayoutData(data); // adjust the tab order compositeContentW.setTabList(new Control[]{compW}); // attach the embedded component as subpage addChild((IXMAControl) actPageInfo.page); setFocusToFirstControl(actPageInfo.page.getComposite().getTabList()); if ( actPageInfo.explanationText == null ) { showOrHideExplanationComposite(false); } else { showOrHideExplanationComposite(true); if ( actPageInfo.explanationTitle == null ) labelExplanationTitle.setText(""); else labelExplanationTitle.setText(actPageInfo.explanationTitle); labelExplanationText.setText(actPageInfo.explanationText); if ( actPageInfo.explanationImageUri != null ) labelExplanationImage.setImage(getComponent().getImage(actPageInfo.explanationImageUri)); else labelExplanationImage.setImage(null); compositeExplanationW.layout(); } } /** * Toggle function to show or hide the explanation composite * @param showIt yes or no? */ private void showOrHideExplanationComposite ( boolean showIt ) { if ( showIt == (compositeExplanationW.getSize().y > 0) ) return; mkLayout4ExplanationAndContentComposite(showIt); getComposite().layout(); } /** * Creates the layout for the explanation and the main composite according * to the given parameter * @param showExplanation should the explanation composite be visible? */ private void mkLayout4ExplanationAndContentComposite ( boolean showExplanation ) { final Scaler scaler = Scaler.getInstance(getComposite()); FormData data = new FormData(); data.left = new FormAttachment(0,100,scaler.convertXToCurrent(0)); data.right = new FormAttachment(100,100,scaler.convertXToCurrent(0)); data.top = new FormAttachment(0,100,scaler.convertYToCurrent(0)); data.bottom = new FormAttachment(0,100,scaler.convertYToCurrent(showExplanation ? 71 : 0)); compositeExplanationW.setLayoutData(data); compositeExplanationW.setVisible(showExplanation); data = new FormData(); data.left = new FormAttachment(0,100,scaler.convertXToCurrent(0)); data.right = new FormAttachment(100,100,scaler.convertXToCurrent(0)); data.top = new FormAttachment(compositeExplanationW,scaler.convertYToCurrent(3),SWT.BOTTOM); data.bottom = new FormAttachment(compositeButtonsW,scaler.convertYToCurrent(-3),SWT.TOP); compositeContentW.setLayoutData(data); } /** * Searches (recursively) for the first control in the given array * @param ctrls control array * @return true if focus was set by this method call (directly or indirectly) */ private boolean setFocusToFirstControl ( Control[] ctrls ) { if ( ctrls == null || ctrls.length < 1 ) return false; Control ctrl = ctrls[0]; if ( ctrl instanceof Composite && ! (ctrl instanceof Group) ) { if ( setFocusToFirstControl(((Composite) ctrl).getChildren()) ) return true; } return ctrl.setFocus(); } /** * Call this method to define a linear wizard flow (index 0 = first step, 1 = 2nd step...) * Each WizardSubPageInfo can be different not only in obvious thins (page to embed, * first-/last page flag...) also in layout. * @param pageInfos Array with information for every wizard step. May not be null. * @throws IllegalArgumentException parameter was null or length == 0 * @throws IllegalStateException method was called second time * @see WizardSubPageInfo */ public void setPageInfos ( WizardSubPageInfo[] pageInfos ) { if ( pageInfos == null ) throw new IllegalArgumentException("pageInfos may not be null!"); if ( pageInfos.length < 1 ) throw new IllegalArgumentException("pageInfos must contain at least one page!"); if ( pageInfoList != null ) throw new IllegalStateException("Cannot initialize wizard twice!"); pageInfos[0].isFirstPage = true; pageInfos[pageInfos.length - 1].isLastPage = true; pageInfoList = Arrays.asList(pageInfos); } /** * Retrieve the next page info according to the direction. * @param actPageInfo info to the current page, on which the next or * prev button was pressed or null on wizard startup * @param nextPressed true, if [next] was pressed (or first time initialization), false on [prev] * @return info of next page to display * @see WizardSubPageInfo */ protected WizardSubPageInfo getNextPageInfo ( WizardSubPageInfo actPageInfo, boolean nextPressed ) { if ( pageInfoList == null ) throw new IllegalStateException("Initialize with setPageInfos() or override getNextPageInfo()!"); WizardSubPageInfo nextInfo; int ndx; if ( actPageInfo == null ) { ndx = 0; } else { ndx = pageInfoList.indexOf(actPageInfo); if ( nextPressed ) { ndx++; } else { ndx--; } } nextInfo = (WizardSubPageInfo) pageInfoList.get(ndx); setStepOf(++ndx,pageInfoList.size()); return nextInfo; } /** * Enriches the window title with a "Step x of y" information * @param step current step (1-based!) * @param of count of all step */ protected void setStepOf ( int step, int of ) { MessageFormat mf = new MessageFormat(stepOfText,getComponent().getContext().getLocale()); String s = getDialogTitle() + " " + mf.format(new Object[] { new Integer(step), new Integer(of) }); getShell().setText(s); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy