com.googlecode.cppcheclipse.ui.preferences.FieldEditorOverlayPage.java Source code

Java tutorial

Introduction

Here is the source code for com.googlecode.cppcheclipse.ui.preferences.FieldEditorOverlayPage.java

Source

/*******************************************************************************
 * Copyright (c) 2003 Berthold Daum.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     Berthold Daum
 *     
 * Taken over from Codan
 * 
 * see also http://www.eclipse.org/articles/Article-Mutatis-mutandis/overlay-pages.html
 * which describes this class, except we use a ScopedPropertyStore
 *******************************************************************************/
package com.googlecode.cppcheclipse.ui.preferences;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IAdaptable;
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.graphics.Point;
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.ui.IWorkbenchPropertyPage;

import com.googlecode.cppcheclipse.core.CppcheclipsePlugin;
import com.googlecode.cppcheclipse.core.IPreferenceConstants;
import com.googlecode.cppcheclipse.ui.Messages;

/**
 * @author Berthold Daum
 */
public abstract class FieldEditorOverlayPage extends FieldEditorPreferencePage implements IWorkbenchPropertyPage {

    private final boolean isWorkspacePreferenceAvailable;

    // Stores all created field editors
    private Map<FieldEditor, Composite> editors = new HashMap<FieldEditor, Composite>();
    // Stores owning element of properties
    private IAdaptable element;
    // Additional buttons for property pages
    private Button useWorkspaceSettingsButton, useProjectSettingsButton, configureButton;
    // Overlay preference store for property pages
    private IPreferenceStore overlayStore;
    // The image descriptor of this pages title image
    private ImageDescriptor image;
    // Cache for page id
    private String pageId;

    /**
     * Constructor
     * 
     * @param style
     *            - layout style
     */
    public FieldEditorOverlayPage(int style, boolean isWorkspacePreferenceAvailable) {
        super(style);
        this.isWorkspacePreferenceAvailable = isWorkspacePreferenceAvailable;
    }

    /**
     * Constructor
     * 
     * @param title
     *            - title string
     * @param style
     *            - layout style
     */
    public FieldEditorOverlayPage(String title, int style, boolean isWorkspacePreferenceAvailable) {
        super(title, style);
        this.isWorkspacePreferenceAvailable = isWorkspacePreferenceAvailable;
    }

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

    /**
     * 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;
    }

    public IProject getProject() {
        return (IProject) element.getAdapter(IProject.class);
    }

    @Override
    public void dispose() {
        // send dispose to all editors
        // Composite parent = getFieldEditorParent();
        for (FieldEditor editor : editors.keySet()) {
            editor.dispose();
        }
        super.dispose();
    }

    /**
     * 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, Composite parent) {
        editors.put(editor, parent);
        super.addField(editor);
    }

    @Override
    protected void addField(FieldEditor editor) {
        addField(editor, getFieldEditorParent());
    }

    /**
     * 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) {
        // Special treatment for property pages
        if (isPropertyPage()) {
            // Cache the page id
            pageId = getPageId();
            overlayStore = CppcheclipsePlugin.getProjectPreferenceStore(getProject());
            // Set overlay store as current preference store
        }
        super.createControl(parent);
        // Update state of all subclass controls
        if (isPropertyPage() && isWorkspacePreferenceAvailable)
            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() && isWorkspacePreferenceAvailable)
            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 comp = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout(2, false);
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        comp.setLayout(layout);
        comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        Composite radioGroup = new Composite(comp, SWT.NONE);
        radioGroup.setLayout(new GridLayout());
        radioGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        useWorkspaceSettingsButton = createRadioButton(radioGroup, Messages.OverlayPage_UseWorkspaceSettings);
        useProjectSettingsButton = createRadioButton(radioGroup, Messages.OverlayPage_UseProjectSettings);
        configureButton = new Button(comp, SWT.PUSH);
        configureButton.setText(Messages.OverlayPage_ConfigureWorkspaceSettings);
        configureButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                configureWorkspaceSettings();
            }
        });
        // Set workspace/project radio buttons
        try {
            Boolean useWorkspace = getPreferenceStore()
                    .getBoolean(getPageId() + IPreferenceConstants.P_USE_PARENT_SUFFIX);
            if (useWorkspace) {
                useWorkspaceSettingsButton.setSelection(true);
            } else {
                useProjectSettingsButton.setSelection(true);
                configureButton.setEnabled(false);
            }
        } catch (Exception e) {
            useWorkspaceSettingsButton.setSelection(true);
        }
    }

    /**
     * Convenience method creating a radio button
     * 
     * @param parent
     *            - the parent composite
     * @param label
     *            - the button label
     * @return - the new button
     */
    private Button createRadioButton(Composite parent, String label) {
        final Button button = new Button(parent, SWT.RADIO);
        button.setText(label);
        button.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                configureButton.setEnabled(button == useWorkspaceSettingsButton);
                updateFieldEditors();
            }
        });
        return button;
    }

    /**
     * Returns in case of property pages the overlay store, in case of
     * preference pages the standard preference store
     * 
     * @see org.eclipse.jface.preference.PreferencePage#getPreferenceStore()
     */
    public IPreferenceStore getPreferenceStore() {
        if (isPropertyPage())
            return overlayStore;
        return super.getPreferenceStore();
    }

    /*
     * 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) {
        // Composite parent = getFieldEditorParent();
        for (Map.Entry<FieldEditor, Composite> entry : editors.entrySet()) {
            entry.getKey().setEnabled(enabled, entry.getValue());
        }
    }

    /**
     * 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() && isWorkspacePreferenceAvailable) {
            // Save state of radiobuttons in project properties
            getPreferenceStore().setValue(getPageId() + IPreferenceConstants.P_USE_PARENT_SUFFIX,
                    !useProjectSettingsButton.getSelection());
        }
        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() && isWorkspacePreferenceAvailable) {
            useWorkspaceSettingsButton.setSelection(true);
            useProjectSettingsButton.setSelection(false);
            configureButton.setEnabled(true);
            updateFieldEditors();
        }
        super.performDefaults();
    }

    /**
     * Creates a new preferences page and opens it
     */
    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(pageId, page);
        } catch (InstantiationException e) {
            CppcheclipsePlugin.logError("Error opening workspace settings", e);
        } catch (IllegalAccessException e) {
            CppcheclipsePlugin.logError("Error opening workspace settings", e);
        }
    }

    /**
     * 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();
            }
        });
    }

    /**
     * Must be called for each composite after some fieldeditors are added,
     * because each field editor resets the parent's layout manager in
     * FieldEditor::createControl
     * 
     * @param composite
     */
    protected void setCompositeLayout(Composite composite) {

        Point size = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
        composite.setSize(size);
        composite.setFont(getFieldEditorParent().getFont());

        GridLayout layout = new GridLayout(2, false);
        /*
         * layout.numColumns = 1; layout.marginLeft = 40; layout.marginHeight =
         * 10;
         */
        layout.horizontalSpacing = 8;
        composite.setLayout(layout);

        GridData gd = new GridData();
        gd.horizontalSpan = 2;
        composite.setLayoutData(gd);
    }
}