Package org.locationtech.udig.catalog.ui.workflow

Source Code of org.locationtech.udig.catalog.ui.workflow.WorkflowWizardDialog

/*
*    uDig - User Friendly Desktop Internet GIS client
*    http://udig.refractions.net
*    (C) 2012, Refractions Research Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD
* License v1.0 (http://udig.refractions.net/files/bsd3-v10.html).
*/
package org.locationtech.udig.catalog.ui.workflow;

import java.lang.reflect.InvocationTargetException;

import org.locationtech.udig.catalog.ui.CatalogUIPlugin;
import org.locationtech.udig.catalog.ui.internal.Messages;
import org.locationtech.udig.ui.PlatformGIS;
import org.locationtech.udig.ui.ProgressManager;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

public class WorkflowWizardDialog extends WizardDialog implements Listener {

    /** flag to indicate whether headless execution is occurring * */
    boolean headless = false;
    private WorkflowWizardAdapter workflowWizardAdapter;

    public WorkflowWizardDialog( Shell parentShell, WorkflowWizard wizard ) {
        super(parentShell, wizard);


        wizard.getWorkflow().addListener(this);
    }

    @Override
    protected WorkflowWizard getWizard() {
        return (WorkflowWizard) super.getWizard();
    }
   
    public WorkflowWizard getWorkflowWizard() {
        return getWizard();
    }

    @Override
    public WorkflowWizardPage getCurrentPage() {
        return (WorkflowWizardPage) super.getCurrentPage();
    }
   
    @Override
    protected void nextPressed() {
        // if there are no more states, do nothing
        if (getWorkflowWizard().getWorkflow().isFinished()){
            return;
        }
        if( !getCurrentPage().leavingPage() ){
            return;
        }
       
        // move workflow to next state, start up a new thread to do it.
        final Workflow pipe = getWizard().getWorkflow();

        try {
          // don't fork, can cancel during transition
            run(false, true, new IRunnableWithProgress(){

                public void run( IProgressMonitor monitor ) throws InvocationTargetException,
                        InterruptedException {
                    pipe.next(monitor); // progress through the workflow
                }

            });
        } catch (Exception e) {
            CatalogUIPlugin.log("Exception while moving workflow forward", e); //$NON-NLS-1$
        }

    }
   
    @Override
    public void run( boolean fork, boolean cancelable, final IRunnableWithProgress request )
            throws InvocationTargetException, InterruptedException {
        if( headless && Display.getCurrent()==null ){
            PlatformGIS.run(request);
            return;
        }
       
        if (getProgressMonitor() instanceof ProgressMonitorPart) {
                ProgressMonitorPart part = (ProgressMonitorPart) getProgressMonitor();
                if( Display.getCurrent()!=null )
                    part.setVisible(true);
               
                try {
                    setEnablement(buttonBar,false);
                    if( fork ){
                        PlatformGIS.run(request, part);
                    }else{
                        PlatformGIS.runBlockingOperation(request, part);
                    }
                } finally {
                    setEnablement(buttonBar, true);
                    if(Display.getCurrent()!=null && !part.isDisposed())
                        part.setVisible(false);
                }
            } else {
                if( fork ){
                    PlatformGIS.run(request);
                } else {
                    PlatformGIS.runBlockingOperation(request, ProgressManager.instance().get());
                }
            }
    }

    private void setEnablement(Control controlA, boolean enabled ) {
        if( controlA==null )
            return;
        if( controlA instanceof Composite ){
            Composite composite=(Composite) controlA;
            Control[] children = composite.getChildren();
            for( Control control : children ) {
                setEnablement(control, enabled);
            }
        }else{
            if( controlA != getButton(IDialogConstants.CANCEL_ID))
            controlA.setEnabled(enabled);
        }
           
    }

    protected void nextPressedSuper() {
        try {
            super.nextPressed();
        } catch (Exception e) {
            setErrorMessage(Messages.WorkflowWizard_PageTransitionError);
            CatalogUIPlugin.log("WorkflowWizardDialog#nextPressedSuper(): Error moving to "+getWorkflowWizard().getWorkflow().getCurrentState().getName(), e); //$NON-NLS-1$
        }
    }

    @Override
    protected void backPressed() {
        // move workflow to previous state, start up a new thread to do it.
        final Workflow pipe = getWizard().getWorkflow();

        if( pipe.getCurrentState().getPreviousState()==null ){
            // this means that this wizard is part of a larger wizard and we need to return control
            // to it.  See setAdapter for details
            workflowWizardAdapter.backPressed();
        }
       
        IRunnableWithProgress runnable = new IRunnableWithProgress(){
            public void run( IProgressMonitor monitor ) throws InvocationTargetException,
                    InterruptedException {

                pipe.previous(monitor);
            }
        };
        try {
            run(false, true, runnable);
        } catch (InvocationTargetException e) {
            CatalogUIPlugin.log(e.getLocalizedMessage(), e);
        } catch (InterruptedException e) {
            CatalogUIPlugin.log(e.getLocalizedMessage(), e);
        }
    }

    protected void backPressedSuper() {
        super.backPressed();
    }

    @Override
    protected void finishPressed() {
        // if there are no more states, do nothing
        if (getWorkflowWizard().getWorkflow().isFinished())
            return;

        /*
         * what happens if the page is driven by the state?  I
         * guess it means the state knows that it can pass so
         * go for it.
         */
        if( !getCurrentPage().leavingPage() ){
            return;
        }
       
        // move workflow to next state, start up a new thread to do it.
        final Workflow pipe = getWizard().getWorkflow();

        try {
            run(false, true, new IRunnableWithProgress(){

                public void run( IProgressMonitor monitor ) throws InvocationTargetException,
                        InterruptedException {
                    pipe.run(monitor);
                }

            });
        } catch (Exception e) {
            CatalogUIPlugin.log("Exception while moving workflow forward", e); //$NON-NLS-1$
        }

    }

    protected void finishPressedSuper() {
        super.finishPressed();
    }

    @Override
    public int open() {
        initWorkflow();
        return super.open();
    }

    @Override
    public boolean close() {
        getWorkflowWizard().getWorkflow().shutdown();
        return super.close();
    }
   
    @Override
    public void showPage( IWizardPage page ) {
        super.showPage(page);

        // let the page know that is is being shown in the wizard, lets page
        // do some lazy initalization of ui widgets, etc.
        ((WorkflowWizardPage) page).shown();
    }

    /**
     * Runs the dialog in headless mode. The dialog will run headless while the workflow can run.
     *
     * @param monitor
     * @param true if the workflow ran and completed correctly.
     *        False if it failed or the user cancelled (because user interaction was required)
     */
    public boolean runHeadless( IProgressMonitor monitor ) {
        try {
            this.headless = true;
            int ticks = getWorkflowWizard().getWorkflow().getStates().length * 10;
            monitor.beginTask(Messages.WorkflowWizardDialog_importTask, ticks);
            // we must ensure that the contents of the dialog (shell) have been
            // creates, needed for wizard pages
            if (getShell() == null) {
                // do in ui thread
                    PlatformGIS.syncInDisplayThread(new Runnable(){
                        public void run() {
                            create();
                        }
                    });
            }

            Workflow pipe = getWizard().getWorkflow();
            pipe.run(new SubProgressMonitor(monitor, ticks));
            final boolean[] result = new boolean[]{true};
            if (!pipe.isFinished()) {
                // show the page corresponding to the current state
                final IWizardPage page = getWizard().getPage(pipe.getCurrentState());
                if (page != null) {
                    // ensure the page has a state if it is a DataPipelinePage
                    if (page instanceof WorkflowWizardPage) {
                        WorkflowWizardPage dpPage = (WorkflowWizardPage) page;
                        if (dpPage.getState() == null)
                            dpPage.setState(pipe.getCurrentState());
                    }

                   PlatformGIS.syncInDisplayThread(new Runnable(){
                        public void run() {
                            headless = false;
                            showPage(page);
                            if( open() == Window.CANCEL ){
                                result[0]=false;
                            }
                        };
                    });
                }

            }

            this.headless = false;
            return result[0];
        } finally {
            monitor.done();
        }
    }

    /**
     * Performs the initialization of the workflow.
     */
    protected void initWorkflow() {
        // start the workflow
        // TODO: This can potentially freeze up the ui if the fist state
        // does alot of work in the #init(IProgressMonitor) method. Perhaps
        // it should be made part of the contract of the dialog that the pipe
        // already be started before open is called.
        final Workflow pipe = getWizard().getWorkflow();
        final IRunnableWithProgress runnable = new IRunnableWithProgress(){
            public void run( IProgressMonitor monitor ) throws InvocationTargetException,
                    InterruptedException {
                if (!pipe.started)
                    pipe.start(monitor);
            }
        };

        if (Display.getCurrent()!=null ){
            try {
                runnable.run(ProgressManager.instance().get());
            } catch (Exception e) {
                throw (RuntimeException) new RuntimeException( ).initCause( e );
            }
        }else{
            PlatformGIS.syncInDisplayThread(new Runnable(){
                public void run() {
                    try {
                        PlatformUI.getWorkbench().getActiveWorkbenchWindow()
                                .run(false, false, runnable);
                    } catch (Throwable e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
    }

    public void started( State first ) {
        // do nothing
    }

    public void forward( State current, State prev ) {
        if (headless)
            return;

            // move the wizard to the next page
            PlatformGIS.syncInDisplayThread(new Runnable(){

                public void run() {
                    nextPressedSuper();
                }
            });
    }

    public void backward( State current, State next ) {
        if (headless)
            return;

            // move the wizard to the previous page
            PlatformGIS.syncInDisplayThread(new Runnable(){

                public void run() {
                    backPressedSuper();
                }
            });
    }

    public void statePassed( State state ) {
        // do nothing

    }

    public void stateFailed( State state ) {
        // do nothing

    }

    public void finished( State last ) {
        if (headless) {
            // signal to the wizard that we are finished
            getWizard().performFinish();
        } else {
            Runnable runnable=new Runnable(){
                public void run() {
                    finishPressedSuper();
                }
            };
            PlatformGIS.asyncInDisplayThread(runnable, true);
        }
    }

    /**
     * This method is a hook for the {@link WorkflowWizardAdapter} so that it can get notification when the previous button
     * is pressed on the first page.  If there is a {@link WorkflowWizardAdapter} it means that this wizard is really part of a
     * large wizard that is created by the eclipse framework.  This dialog is opened to handle the workflow wizard work but
     * it needs the previous button on always and needs to notify the adapter when that button is pressed so that this
     * dialog can be hidden until needed again.
     *
     * @param workflowWizardAdapter the adapter that interfaces with the other wizard.
     * @param previousPage the page that is previous to this page
     */
    void setAdapter(final WorkflowWizardAdapter workflowWizardAdapter, IWizardPage previousPage ) {
        this.workflowWizardAdapter = workflowWizardAdapter;
        IWizardPage startingPage = getWizard().getStartingPage();
        startingPage.setPreviousPage(previousPage);
        updateButtons();
    }
}
TOP

Related Classes of org.locationtech.udig.catalog.ui.workflow.WorkflowWizardDialog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.