at.spardat.xma.guidesign.preferences.AbstractPreferenceAndPropertyPage.java Source code

Java tutorial

Introduction

Here is the source code for at.spardat.xma.guidesign.preferences.AbstractPreferenceAndPropertyPage.java

Source

/*******************************************************************************
 * Copyright (c) 2003, 2007 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.guidesign.preferences;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.preferences.ConfigurationScope;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IPreferenceNode;
import org.eclipse.jface.preference.IPreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.preference.PreferenceManager;
import org.eclipse.jface.preference.PreferenceNode;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.IWorkbenchPropertyPage;
import org.eclipse.ui.preferences.ScopedPreferenceStore;

/**
 * The class AbstractPreferenceAndPropertyPage represents a common superclass
 * for all field editor preference pages that also want to behave as property
 * pages.
 * 
 * @author <a href="mailto:michael.clay@s-itsolutions.at">Michael Clay</a>
 * @version $Revision: 4130 $ $Date: 2009-09-23 17:40:11 +0200 (Mit, 23. Sep 2009) $
 */
public abstract class AbstractPreferenceAndPropertyPage extends FieldEditorPreferencePage
        implements IWorkbenchPreferencePage, IWorkbenchPropertyPage {

    /**
     * Name of resource property for the selection of workbench or project
     * settings
     */
    public static final String USEPROJECTSETTINGS = "useProjectSettings"; //$NON-NLS-1$

    private static final String FALSE = "false"; //$NON-NLS-1$
    private static final String TRUE = "true"; //$NON-NLS-1$

    // Stores all created field editors
    private List<FieldEditor> editors = new ArrayList<FieldEditor>();
    private Map<FieldEditor, Composite> editorParentMap = new HashMap<FieldEditor, Composite>();
    // Stores owning element of properties
    private IAdaptable element;

    // Additional buttons for property pages
    private Button useProjectSettingsButton;

    Link changeWorkspaceSettings;

    // The image descriptor of this pages title image
    private ImageDescriptor image;

    /**
     * Constructor
     * 
     * @param style
     *            - layout style
     */
    public AbstractPreferenceAndPropertyPage(int style) {
        super(style);
    }

    /**
     * Constructor
     * 
     * @param title
     *            - title string
     * @param style
     *            - layout style
     */
    public AbstractPreferenceAndPropertyPage(String title, int style) {
        super(title, style);
    }

    /**
     * Constructor
     * 
     * @param title
     *            - title string
     * @param image
     *            - title image
     * @param style
     *            - layout style
     */
    public AbstractPreferenceAndPropertyPage(String title, ImageDescriptor image, int style) {
        super(title, image, style);
        this.image = image;
    }

    /**
     * Returns the id of the current preference page as defined in plugin.xml
     * Subclasses must implement.
     * 
     * @return - the qualifier
     */
    protected abstract String getPageId();

    /**
     * Receives the object that owns the properties shown in this property page.
     * 
     * @see org.eclipse.ui.IWorkbenchPropertyPage#setElement(org.eclipse.core.runtime.IAdaptable)
     */
    public void setElement(IAdaptable element) {
        this.element = element;
    }

    /**
     * Delivers the object that owns the properties shown in this property page.
     * 
     * @see org.eclipse.ui.IWorkbenchPropertyPage#getElement()
     */
    public IAdaptable getElement() {
        return element;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
     */
    public void init(IWorkbench workbench) {
    }

    /**
     * Returns true if this instance represents a property page
     * 
     * @return - true for property pages, false for preference pages
     */
    public boolean isPropertyPage() {
        return getElement() != null;
    }

    /**
     * We override the addField method. This allows us to store each field
     * editor added by subclasses in a list for later processing.
     * 
     * @see org.eclipse.jface.preference.FieldEditorPreferencePage#addField(org.eclipse.jface.preference.FieldEditor)
     */
    protected void addField(FieldEditor editor) {
        editors.add(editor);
        editorParentMap.put(editor, getFieldEditorParent());
        super.addField(editor);
    }

    protected void addField(FieldEditor editor, Composite parent) {
        editors.add(editor);
        editorParentMap.put(editor, parent);
        super.addField(editor);
    }

    /**
     * We override the createControl method. In case of property pages we create
     * a new PropertyStore as local preference store. After all control have
     * been create, we enable/disable these controls.
     * 
     * @see org.eclipse.jface.preference.PreferencePage#createControl()
     */
    public void createControl(Composite parent) {
        super.createControl(parent);
        // Update state of all subclass controls
        if (isPropertyPage())
            updateFieldEditors();
    }

    /**
     * We override the createContents method. In case of property pages we
     * insert two radio buttons at the top of the page.
     * 
     * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
     */
    protected Control createContents(Composite parent) {
        if (isPropertyPage())
            createSelectionGroup(parent);
        return super.createContents(parent);
    }

    /**
     * Creates and initializes a selection group with two choice buttons and one
     * push button.
     * 
     * @param parent
     *            - the parent composite
     */
    private void createSelectionGroup(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.numColumns = 2;
        composite.setLayout(layout);
        composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        useProjectSettingsButton = new Button(composite, SWT.CHECK);
        useProjectSettingsButton.setText(Messages.getString("OverlayPage.Use_Project_Settings"));
        useProjectSettingsButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                changeWorkspaceSettings.setEnabled(!((Button) e.getSource()).getSelection());
                updateFieldEditors();
            }
        });
        changeWorkspaceSettings = createLink(composite,
                Messages.getString("OverlayPage.Configure_Workspace_Settings"));
        changeWorkspaceSettings.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
        Label horizontalLine = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
        horizontalLine.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, 2, 1));
        horizontalLine.setFont(composite.getFont());
        try {
            String useProjectSettings = ((IResource) getElement())
                    .getPersistentProperty(new QualifiedName(getPageId(), USEPROJECTSETTINGS));
            if (TRUE.equals(useProjectSettings)) {
                useProjectSettingsButton.setSelection(true);
                changeWorkspaceSettings.setEnabled(false);
            } else
                useProjectSettingsButton.setSelection(false);
        } catch (CoreException e) {
            useProjectSettingsButton.setSelection(false);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.preference.PreferencePage#doGetPreferenceStore()
     */
    protected IPreferenceStore doGetPreferenceStore() {
        String qualifier = getNodeQualifier();
        if (isPropertyPage()) {
            ProjectScope projectScope = new ProjectScope((IProject) getElement());
            ScopedPreferenceStore scopedPreferenceStore = new ScopedPreferenceStore(projectScope, qualifier);
            scopedPreferenceStore.setSearchContexts(
                    new IScopeContext[] { projectScope, new InstanceScope(), new ConfigurationScope() });
            return scopedPreferenceStore;
        }
        ScopedPreferenceStore scopedPreferenceStore = new ScopedPreferenceStore(new InstanceScope(), qualifier);
        scopedPreferenceStore
                .setSearchContexts(new IScopeContext[] { new InstanceScope(), new ConfigurationScope() });
        return scopedPreferenceStore;
    }

    protected abstract String getNodeQualifier();

    /*
     * Enables or disables the field editors and buttons of this page
     */
    private void updateFieldEditors() {
        // We iterate through all field editors
        boolean enabled = useProjectSettingsButton.getSelection();
        updateFieldEditors(enabled);
    }

    /**
     * Enables or disables the field editors and buttons of this page Subclasses
     * may override.
     * 
     * @param enabled
     *            - true if enabled
     */
    protected void updateFieldEditors(boolean enabled) {
        Iterator<FieldEditor> fieldEditorIterator = editors.iterator();
        while (fieldEditorIterator.hasNext()) {
            FieldEditor editor = (FieldEditor) fieldEditorIterator.next();
            doEnableFieldEditor(enabled, editorParentMap.get(editor), editor);
        }
    }

    /**
     * 
     * @param enabled  true if enabled
     * @param parent parent of the given editor
     * @param editor to enable or disable
     */
    protected void doEnableFieldEditor(boolean enabled, Composite parent, FieldEditor editor) {
        editor.setEnabled(enabled, parent);
    }

    /**
     * We override the performOk method. In case of property pages we copy the
     * values in the overlay store into the property values of the selected
     * project. We also save the state of the radio buttons.
     * 
     * @see org.eclipse.jface.preference.IPreferencePage#performOk()
     */
    public boolean performOk() {
        boolean result = super.performOk();
        if (result && isPropertyPage()) {
            IResource resource = (IResource) getElement();
            try {
                String value = (useProjectSettingsButton.getSelection()) ? TRUE : FALSE;
                resource.setPersistentProperty(new QualifiedName(getPageId(), USEPROJECTSETTINGS), value);
            } catch (CoreException e) {
            }
        }
        return result;
    }

    /**
     * We override the performDefaults method. In case of property pages we
     * switch back to the workspace settings and disable the field editors.
     * 
     * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
     */
    protected void performDefaults() {
        if (isPropertyPage()) {
            useProjectSettingsButton.setSelection(false);
            changeWorkspaceSettings.setEnabled(true);
            updateFieldEditors();
        }
        super.performDefaults();
    }

    /**
     * Creates a new preferences page and opens it
     * 
     * @see com.bdaum.SpellChecker.preferences.SpellCheckerPreferencePage#configureWorkspaceSettings()
     */
    protected void configureWorkspaceSettings() {
        try {
            // create a new instance of the current class
            IPreferencePage page = (IPreferencePage) this.getClass().newInstance();
            page.setTitle(getTitle());
            page.setImageDescriptor(image);
            // and show it
            showPreferencePage(getPageId(), page);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * Show a single preference pages
     * 
     * @param id
     *            - the preference page identification
     * @param page
     *            - the preference page
     */
    protected void showPreferencePage(String id, IPreferencePage page) {
        final IPreferenceNode targetNode = new PreferenceNode(id, page);
        PreferenceManager manager = new PreferenceManager();
        manager.addToRoot(targetNode);
        final PreferenceDialog dialog = new PreferenceDialog(getControl().getShell(), manager);
        BusyIndicator.showWhile(getControl().getDisplay(), new Runnable() {
            public void run() {
                dialog.create();
                dialog.setMessage(targetNode.getLabelText());
                dialog.open();
            }
        });
    }

    private Link createLink(Composite composite, String text) {
        Link link = new Link(composite, SWT.NONE);
        link.setFont(composite.getFont());
        link.setText("<A>" + text + "</A>"); //$NON-NLS-1$//$NON-NLS-2$
        link.addSelectionListener(new SelectionListener() {
            public void widgetSelected(SelectionEvent e) {
                configureWorkspaceSettings();
            }

            public void widgetDefaultSelected(SelectionEvent e) {
                configureWorkspaceSettings();
            }
        });
        return link;
    }
}