com.liferay.ide.ui.form.IDEFormPage.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.ide.ui.form.IDEFormPage.java

Source

/*******************************************************************************
 * Copyright (c) 2003, 2009 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
 *     Benjamin Cabe <benjamin.cabe@anyware-tech.com> - bug 251339
 *******************************************************************************/
package com.liferay.ide.ui.form;

import com.liferay.ide.core.model.IBaseModel;

import java.io.PrintWriter;
import java.io.StringWriter;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.dialogs.FilteredTree;
import org.eclipse.ui.forms.AbstractFormPart;
import org.eclipse.ui.forms.IFormPart;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;

public abstract class IDEFormPage extends FormPage {

    private Control fLastFocusControl;

    public IDEFormPage(FormEditor editor, String id, String title) {
        super(editor, id, title);
        fLastFocusControl = null;
    }

    public IDEFormEditor getLiferayFormEditor() {
        return (IDEFormEditor) getEditor();
    }

    public void dispose() {
        Control c = getPartControl();
        if (c != null && !c.isDisposed()) {
            Menu menu = c.getMenu();
            if (menu != null)
                resetMenu(menu, c);
        }
        super.dispose();
    }

    private void resetMenu(Menu menu, Control c) {
        if (c instanceof Composite) {
            Composite comp = (Composite) c;
            Control[] children = comp.getChildren();
            for (int i = 0; i < children.length; i++) {
                resetMenu(menu, children[i]);
            }
        }
        Menu cmenu = c.getMenu();
        if (cmenu != null && cmenu.equals(menu)) {
            c.setMenu(null);
        }
    }

    protected void createFormContent(IManagedForm managedForm) {
        final ScrolledForm form = managedForm.getForm();
        FormToolkit toolkit = managedForm.getToolkit();
        toolkit.decorateFormHeading(form.getForm());

        IToolBarManager manager = form.getToolBarManager();

        getFormEditor().contributeToToolbar(manager);

        //      final String href = getHelpResource();
        //      if (href != null) {
        //         Action helpAction = new Action("help") { //$NON-NLS-1$
        //            public void run() {
        //               BusyIndicator.showWhile(form.getDisplay(), new Runnable() {
        //                  public void run() {
        //                     PlatformUI.getWorkbench().getHelpSystem().displayHelpResource(href);
        //                  }
        //               });
        //            }
        //         };
        //         helpAction.setToolTipText(PDEUIMessages.PDEFormPage_help);
        //         helpAction.setImageDescriptor(PDEPluginImages.DESC_HELP);
        //         manager.add(helpAction);
        //      }
        //check to see if our form parts are contributing actions
        IFormPart[] parts = managedForm.getParts();
        for (int i = 0; i < parts.length; i++) {
            if (parts[i] instanceof IAdaptable) {
                IAdaptable adapter = (IAdaptable) parts[i];
                IAction[] actions = (IAction[]) adapter.getAdapter(IAction[].class);
                if (actions != null) {
                    for (int j = 0; j < actions.length; j++) {
                        form.getToolBarManager().add(actions[j]);
                    }
                }
            }
        }
        form.updateToolBar();
    }

    public IDEFormEditor getFormEditor() {
        return (IDEFormEditor) getEditor();
    }

    protected String getHelpResource() {
        return null;
    }

    public void contextMenuAboutToShow(IMenuManager menu) {
    }

    protected Control getFocusControl() {
        IManagedForm form = getManagedForm();
        if (form == null)
            return null;
        Control control = form.getForm();
        if (control == null || control.isDisposed())
            return null;
        Display display = control.getDisplay();
        Control focusControl = display.getFocusControl();
        if (focusControl == null || focusControl.isDisposed())
            return null;
        return focusControl;
    }

    public boolean performGlobalAction(String actionId) {
        Control focusControl = getFocusControl();
        if (focusControl == null)
            return false;

        if (canPerformDirectly(actionId, focusControl))
            return true;
        AbstractFormPart focusPart = getFocusSection();
        if (focusPart != null) {
            if (focusPart instanceof IDESection)
                return ((IDESection) focusPart).doGlobalAction(actionId);
            if (focusPart instanceof FormDetails)
                return ((FormDetails) focusPart).doGlobalAction(actionId);
        }
        return false;
    }

    public boolean canPaste(Clipboard clipboard) {
        AbstractFormPart focusPart = getFocusSection();
        if (focusPart != null) {
            if (focusPart instanceof IDESection) {
                return ((IDESection) focusPart).canPaste(clipboard);
            }
            if (focusPart instanceof FormDetails) {
                return ((FormDetails) focusPart).canPaste(clipboard);
            }
        }
        return false;
    }

    public boolean canCopy(ISelection selection) {
        AbstractFormPart focusPart = getFocusSection();
        if (focusPart != null) {
            if (focusPart instanceof IDESection) {
                return ((IDESection) focusPart).canCopy(selection);
            }
            if (focusPart instanceof FormDetails) {
                return ((FormDetails) focusPart).canCopy(selection);
            }
        }
        return false;
    }

    public boolean canCut(ISelection selection) {
        AbstractFormPart focusPart = getFocusSection();
        if (focusPart != null) {
            if (focusPart instanceof IDESection) {
                return ((IDESection) focusPart).canCut(selection);
            }
            if (focusPart instanceof FormDetails) {
                return ((FormDetails) focusPart).canCut(selection);
            }
        }
        return false;
    }

    private AbstractFormPart getFocusSection() {
        Control focusControl = getFocusControl();
        if (focusControl == null)
            return null;
        Composite parent = focusControl.getParent();
        AbstractFormPart targetPart = null;
        while (parent != null) {
            Object data = parent.getData("part"); //$NON-NLS-1$
            if (data != null && data instanceof AbstractFormPart) {
                targetPart = (AbstractFormPart) data;
                break;
            }
            parent = parent.getParent();
        }
        return targetPart;
    }

    protected boolean canPerformDirectly(String id, Control control) {
        if (control instanceof Text) {
            Text text = (Text) control;
            if (id.equals(ActionFactory.CUT.getId())) {
                text.cut();
                return true;
            }
            if (id.equals(ActionFactory.COPY.getId())) {
                text.copy();
                return true;
            }
            if (id.equals(ActionFactory.PASTE.getId())) {
                text.paste();
                return true;
            }
            if (id.equals(ActionFactory.SELECT_ALL.getId())) {
                text.selectAll();
                return true;
            }
            if (id.equals(ActionFactory.DELETE.getId())) {
                int count = text.getSelectionCount();
                if (count == 0) {
                    int caretPos = text.getCaretPosition();
                    text.setSelection(caretPos, caretPos + 1);
                }
                text.insert(""); //$NON-NLS-1$
                return true;
            }
        }
        return false;
    }

    public void cancelEdit() {
        IFormPart[] parts = getManagedForm().getParts();
        for (int i = 0; i < parts.length; i++) {
            IFormPart part = parts[i];
            if (part instanceof IContextPart)
                ((IContextPart) part).cancelEdit();
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.forms.editor.FormPage#createPartControl(org.eclipse.swt.widgets.Composite)
     */
    public void createPartControl(Composite parent) {
        super.createPartControl(parent);
        // Dynamically add focus listeners to all the forms children in order
        // to track the last focus control
        IManagedForm managedForm = getManagedForm();
        if (managedForm != null) {
            addLastFocusListeners(managedForm.getForm());
        }
    }

    /**
     * Programatically and recursively add focus listeners to the specified
     * composite and its children that track the last control to have focus 
     * before a page change or the editor lost focus
     * 
     * @param composite
     */
    public void addLastFocusListeners(Composite composite) {
        Control[] controls = composite.getChildren();
        for (int i = 0; i < controls.length; i++) {
            Control control = controls[i];
            // Add a focus listener if the control is any one of the below types
            // Note that the controls listed below represent all the controls
            // currently in use by all form pages in PDE.  In the future,
            // more controls will have to be added.
            // Could not add super class categories of controls because it 
            // would include things like tool bars that we don't want to track
            // focus for.
            if ((control instanceof Text) || (control instanceof Button) || (control instanceof Combo)
                    || (control instanceof CCombo) || (control instanceof Tree) || (control instanceof Table)
                    || (control instanceof Spinner) || (control instanceof Link) || (control instanceof List)
                    || (control instanceof TabFolder) || (control instanceof CTabFolder)
                    || (control instanceof Hyperlink) || (control instanceof FilteredTree)) {
                addLastFocusListener(control);
            }
            if (control instanceof Composite) {
                // Recursively add focus listeners to this composites children
                addLastFocusListeners((Composite) control);
            }
        }
    }

    /**
     * Add a focus listener to the specified control that tracks the last 
     * control to have focus on this page.
     * When focus is gained by this control, it registers itself as the last
     * control to have focus.  The last control to have focus is stored in order
     * to be restored after a page change or editor loses focus.
     * 
     * @param control
     */
    private void addLastFocusListener(final Control control) {
        control.addFocusListener(new FocusListener() {
            public void focusGained(FocusEvent e) {
                // NO-OP
            }

            public void focusLost(FocusEvent e) {
                fLastFocusControl = control;
            }
        });
    }

    /**
     * Set the focus on the last control to have focus before a page change
     * or the editor lost focus.
     */
    public void updateFormSelection() {
        if ((fLastFocusControl != null) && (fLastFocusControl.isDisposed() == false)) {
            Control lastControl = fLastFocusControl;
            // Set focus on the control
            lastControl.forceFocus();
            // If the control is a Text widget, select its contents
            if (lastControl instanceof Text) {
                Text text = (Text) lastControl;
                text.setSelection(0, text.getText().length());
            }
        } else {
            // No focus control set
            // Fallback on managed form selection mechanism by setting the 
            // focus on this page itself.
            // The managed form will set focus on the first managed part.
            // Most likely this will turn out to be a section.
            // In order for this to work properly, we must override the 
            // sections setFocus() method and set focus on a child control
            // (preferrably first) that can practically take focus.
            setFocus();
        }
    }

    public Control getLastFocusControl() {
        return fLastFocusControl;
    }

    /**
     * @param control
     */
    public void setLastFocusControl(Control control) {
        fLastFocusControl = control;
    }

    protected void createFormErrorContent(IManagedForm managedForm, String errorTitle, String errorMessage,
            Exception e) {

        ScrolledForm form = managedForm.getForm();
        FormToolkit toolkit = managedForm.getToolkit();
        toolkit.decorateFormHeading(form.getForm());

        Composite parent = form.getBody();
        GridLayout layout = new GridLayout();
        GridData data2 = new GridData(GridData.FILL_BOTH);
        layout.marginWidth = 7;
        layout.marginHeight = 7;
        parent.setLayout(layout);
        parent.setLayoutData(data2);
        // Set the title and image of the form
        form.setText(errorTitle);
        form.setImage(JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_ERROR));

        int sectionStyle = Section.DESCRIPTION | ExpandableComposite.TITLE_BAR;
        // Create the message section
        Section messageSection = createUISection(parent, Msgs.message, errorMessage, sectionStyle);
        Composite messageClient = createUISectionContainer(messageSection, 1);
        // Bind the widgets
        toolkit.paintBordersFor(messageClient);
        messageSection.setClient(messageClient);
        // Ensure the exception was defined
        if (e == null) {
            return;
        }
        // Create the details section
        Section detailsSection = createUISection(parent, Msgs.details, e.getMessage(), sectionStyle);
        Composite detailsClient = createUISectionContainer(detailsSection, 1);
        // Create text widget holding the exception trace
        int style = SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY;
        Text text = toolkit.createText(detailsClient, getStackTrace(e), style);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        data.heightHint = 160;
        data.widthHint = 200;
        text.setLayoutData(data);
        // Bind the widgets
        toolkit.paintBordersFor(detailsClient);
        detailsSection.setClient(detailsClient);
        // Note: The veritical scrollbar fails to appear when text widget is
        // not entirely shown
    }

    public Section createUISection(Composite parent, String text, String description, int style) {
        Section section = getManagedForm().getToolkit().createSection(parent, style);
        section.clientVerticalSpacing = FormLayoutFactory.SECTION_HEADER_VERTICAL_SPACING;
        section.setLayout(FormLayoutFactory.createClearGridLayout(false, 1));
        section.setText(text);
        section.setDescription(description);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        section.setLayoutData(data);
        return section;
    }

    public Composite createUISectionContainer(Composite parent, int columns) {
        Composite container = getManagedForm().getToolkit().createComposite(parent);
        container.setLayout(FormLayoutFactory.createSectionClientGridLayout(false, columns));
        return container;
    }

    private String getStackTrace(Throwable throwable) {
        StringWriter swriter = new StringWriter();
        PrintWriter pwriter = new PrintWriter(swriter);
        throwable.printStackTrace(pwriter);
        pwriter.flush();
        pwriter.close();
        return swriter.toString();
    }

    /**
     * Used to align the section client / decriptions of two section headers 
     * horizontally adjacent to each other.  The misalignment is caused by one
     * section header containing toolbar icons and the other not.
     * 
     * @param masterSection
     * @param detailsSection
     */
    public void alignSectionHeaders(Section masterSection, Section detailsSection) {
        detailsSection.descriptionVerticalSpacing += masterSection.getTextClientHeightDifference();
    }

    public IBaseModel getModel() {
        return ((IDEFormEditor) getEditor()).getModel();
    }

    public Shell getShell() {
        return null;
    }

    private static class Msgs extends NLS {
        public static String details;
        public static String message;

        static {
            initializeMessages(IDEFormPage.class.getName(), Msgs.class);
        }
    }
}