eclox.ui.action.BuildActionDelegate.java Source code

Java tutorial

Introduction

Here is the source code for eclox.ui.action.BuildActionDelegate.java

Source

/*******************************************************************************
 * Copyright (C) 2003, 2004, 2007, 2008, 2013, Guillaume Brocker
 * Copyright (C) 2015-2016, Andre Bossert
 *
 * 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:
 *     Guillaume Brocker - Initial API and implementation
 *     Andre Bossert - Add ability to use Doxyfile not in project scope
 *
 ******************************************************************************/

package eclox.ui.action;

import java.io.File;
import java.net.URI;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowPulldownDelegate;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.FileStoreEditorInput;

import eclox.core.doxyfiles.Doxyfile;
import eclox.core.doxygen.BuildJob;
import eclox.ui.DoxyfileSelector;
import eclox.ui.Plugin;
import eclox.ui.wizard.NewDoxyfileWizard;

/**
 * Implement the action handling for the build action.
 *
 * @author gbrocker
 */
public class BuildActionDelegate implements IWorkbenchWindowPulldownDelegate {
    /**
     * Listens for the popup menu items pointing to doxyfiles to build.
     *
     * @author Guillaume Brocker
     */
    private class MenuSelectionListener implements SelectionListener {
        public void widgetSelected(SelectionEvent e) {
            processData(e.widget.getData());
        }

        public void widgetDefaultSelected(SelectionEvent e) {
            processData(e.widget.getData());
        }

        private void processData(Object data) {
            Doxyfile doxyfile = null;
            if (data != null) {
                if (data instanceof Doxyfile) {
                    doxyfile = (Doxyfile) data;
                } else if (data instanceof IFile) {
                    doxyfile = new Doxyfile((IFile) data, null);
                } else if (data instanceof File) {
                    doxyfile = new Doxyfile(null, (File) data);
                }
            }
            if (doxyfile != null) {
                nextDoxyfile = doxyfile;
                doRun(false);
            } else {
                doRun(true);
            }
        }
    }

    private Menu menu; ///< The managed contextual menu.
    private Doxyfile nextDoxyfile; ///< Rembers the next doxyfile to build.
    private IWorkbenchWindow window; ///< Holds the reference to the workbench window where the action takes place.

    /**
     * @see org.eclipse.ui.IWorkbenchWindowPulldownDelegate#getMenu(org.eclipse.swt.widgets.Control)
     */
    public Menu getMenu(Control parent) {
        disposeMenu();
        this.menu = new Menu(parent);

        // Fill it up with the build history items.
        BuildJob[] buildJobs = Plugin.getDefault().getBuildManager().getRecentBuildJobs();
        for (int i = buildJobs.length - 1; i >= 0; i--) {
            MenuItem menuItem = new MenuItem(this.menu, SWT.PUSH);
            Doxyfile currentDoxyfile = buildJobs[i].getDoxyfile();
            menuItem.addSelectionListener(new MenuSelectionListener());
            menuItem.setData(currentDoxyfile);
            menuItem.setText(currentDoxyfile.getName() + " [" + currentDoxyfile.getFullPath() + "]");
        }
        // Add some sugar in the ui
        if (buildJobs.length > 0) {
            new MenuItem(this.menu, SWT.SEPARATOR);
        }

        // Add the fall-back menu item to let the user choose another doxyfile.
        MenuItem chooseMenuItem = new MenuItem(this.menu, SWT.PUSH);

        chooseMenuItem.addSelectionListener(new MenuSelectionListener());
        chooseMenuItem.setText("Choose Doxyfile...");

        // Job's done.
        return this.menu;
    }

    /**
     * Dispose the delegate.
     */
    public void dispose() {
        // Frees all resources and references.
        disposeMenu();
        nextDoxyfile = null;
        window = null;
    }

    /**
     * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
     */
    public void init(IWorkbenchWindow window) {
        this.window = window;
    }

    /**
     * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
     */
    public void run(IAction action) {
        try {
            doRun(false);
        } catch (Throwable throwable) {
            MessageDialog.openError(window.getShell(), "Unexpected Error", throwable.toString());
        }
    }

    /**
     * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
     */
    public void selectionChanged(IAction action, ISelection selection) {
        try {
            // Retrieve the next doxyfile to build from the current selection.
            IFile nextIFile = getDoxyfileFromSelection(selection);

            // Retrieve the next doxyfile from the current editor.
            if (nextIFile != null) {
                nextDoxyfile = new Doxyfile(nextIFile, null);
            } else {
                nextDoxyfile = getDoxyfileFromActiveEditor(window);
            }

            // If there is no next doxyfile to build and the history is not empty
            // set the first history element as the next doxyfile.
            if (nextDoxyfile == null) {
                BuildJob[] buildJobs = Plugin.getDefault().getBuildManager().getRecentBuildJobs();
                int buildJobsCount = buildJobs.length;
                if (buildJobsCount > 0) {
                    nextDoxyfile = buildJobs[buildJobsCount - 1].getDoxyfile();
                }
            }

            // Check the existence of the doxyfile.
            if (nextDoxyfile != null && nextDoxyfile.exists() == false) {
                nextDoxyfile = null;
            }

            // Update the tooltip.
            String tooltipText = nextDoxyfile != null ? "Build " + nextDoxyfile.getFullPath()
                    : "Choose Next Doxyfile";

            action.setToolTipText(tooltipText);
        } catch (Throwable throwable) {
            MessageDialog.openError(window.getShell(), "Unexpected Error", throwable.toString());
        }
    }

    /**
     * Uses the next doxyfile specified to determine what to do.
     *
     * @param   forceChoose   @c true to ask the user for a doxyfile to build.
     */
    protected void doRun(boolean forceChoose) {
        try {
            Doxyfile doxyfile = (forceChoose == true) ? null : this.nextDoxyfile;
            IFile doxyIFile = null;
            DoxyfileSelector selector = new DoxyfileSelector(null);

            // If there is no next doxyfile to build, ask the user for one.
            if (doxyfile == null) {
                selector.open();
                doxyIFile = selector.getDoxyfile();
                if (doxyIFile != null) {
                    doxyfile = new Doxyfile(doxyIFile, null);
                }
            }

            // If there is no doxyfile,
            // we will prompt the user to create one and then edit it.
            if (doxyfile == null && selector.hadDoxyfiles() == false) {
                doxyIFile = askUserToCreateDoxyfile();
                if (doxyIFile != null) {
                    doxyfile = new Doxyfile(doxyIFile, null);
                }
            } else if (doxyfile != null) {
                Plugin.getDefault().getBuildManager().build(doxyfile);
            }
        } catch (Throwable throwable) {
            MessageDialog.openError(window.getShell(), "Unexpected Error", throwable.toString());
        }
    }

    /**
     * Dispose the owned menu.
     */
    private void disposeMenu() {
        if (this.menu != null) {
            this.menu.dispose();
            this.menu = null;
        }
    }

    /**
     * Retrieves a doxyfile from the active editor.
     *
     * @param   window   a reference to a workbench window
     *
     * @return   a doxfile retrieved from the active editor input.
     */
    private static Doxyfile getDoxyfileFromActiveEditor(IWorkbenchWindow window) {
        IFile ifile = null;
        File file = null;
        IWorkbenchPage activePage = window.getActivePage();
        IEditorPart activeEditorPart = activePage != null ? window.getActivePage().getActiveEditor() : null;
        if (activeEditorPart != null) {
            IEditorInput input = activeEditorPart.getEditorInput();
            if (input instanceof IFileEditorInput) {
                ifile = ((IFileEditorInput) input).getFile();
            } else if (input instanceof IAdaptable) {
                IAdaptable adaptable = (IAdaptable) input;
                ifile = (IFile) adaptable.getAdapter(IFile.class);
                if (ifile == null) {
                    if (adaptable instanceof FileStoreEditorInput) {
                        URI fileuri = ((FileStoreEditorInput) adaptable).getURI();
                        file = new File(fileuri.getPath());
                    } else {
                        file = (File) adaptable.getAdapter(File.class);
                    }
                }
            }
            if (ifile != null && !Doxyfile.isDoxyfile(ifile)) {
                ifile = null;
            }
        }
        if (ifile != null || file != null) {
            return new Doxyfile(ifile, file);
        } else {
            return null;
        }
    }

    /**
     * Retrieves a doxyfile from the specified selection.
     *
     * @return   a doxyfile retrieved from the specified selection.
     */
    private static IFile getDoxyfileFromSelection(ISelection selection) {
        IFile doxyfile = null;

        // Test if the current selection is not empty.
        if (selection instanceof IStructuredSelection && selection.isEmpty() == false) {
            IStructuredSelection structSel = (IStructuredSelection) selection;
            Object element = structSel.getFirstElement();

            if (element != null && element instanceof IFile) {
                IFile fileElement = (IFile) element;

                if (fileElement.exists() == true && Doxyfile.isDoxyfile(fileElement) == true) {
                    doxyfile = fileElement;
                }
            }
        }

        // Job's done.
        return doxyfile;
    }

    /**
     * Prompts the user to create a new doxyfile.
     *
     * @return   a doxyfile, or null if none.
     */
    private static IFile askUserToCreateDoxyfile() {
        IFile doxyfile = null;
        Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
        boolean wantDoxyfile = MessageDialog.openQuestion(shell, "No Doxyfile Found",
                "No doxyfile has been found in opened projects.\n\nDo you want to create a new doxyfile now ?");

        if (wantDoxyfile) {
            NewDoxyfileWizard wizard = new NewDoxyfileWizard();
            ISelection selection = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService()
                    .getSelection();
            IStructuredSelection strcSelection = (selection != null && selection instanceof IStructuredSelection)
                    ? (IStructuredSelection) selection
                    : new StructuredSelection();

            wizard.init(PlatformUI.getWorkbench(), strcSelection);

            WizardDialog wizardDialog = new WizardDialog(shell, wizard);

            wizardDialog.open();
            doxyfile = wizard.getDoxyfile();
        }

        return doxyfile;
    }

}