eclox.core.ui.DefaultDoxygenFieldEditor.java Source code

Java tutorial

Introduction

Here is the source code for eclox.core.ui.DefaultDoxygenFieldEditor.java

Source

/*******************************************************************************
 * Copyright (C) 2003-2006, 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 - moved and improved dialog code to CustomDoxygenDialog
 *                   - added support of eclipse variables to resolve doxygen path
 *
 ******************************************************************************/

package eclox.core.ui;

import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;

import eclox.core.IPreferences;
import eclox.core.Plugin;
import eclox.core.doxygen.BundledDoxygen;
import eclox.core.doxygen.CustomDoxygen;
import eclox.core.doxygen.DefaultDoxygen;
import eclox.core.doxygen.Doxygen;

/**
 * @author Guillaume Brocker
 */
public class DefaultDoxygenFieldEditor extends FieldEditor {

    /**
     * defines the version column index
     */
    private final int VERSION_COLUMN_INDEX = 0;

    /**
     * defines the type column index
     */
    private final int TYPE_COLUMN_INDEX = 1;

    /**
     * defines the description column index
     */
    private final int DESCRIPTION_COLUMN_INDEX = 2;

    /**
     * the table control showing available doxygen wrappers
     */
    private Table table;

    /**
     * the composite containing all buttons
     */
    private Composite buttons;

    /**
     * the button that triggers the addition of a custom doxygen
     */
    private Button add;

    /**
     * the button that triggers the edition of a custom doxygen
     */
    private Button edit;

    /**
     * the button that triggers the removal of a custom doxygen
     */
    private Button remove;

    /**
     * the valid state of the field editor
     */
    private boolean valid = true;

    /**
     * Implements a selection listener for the owned table control.
     *
     * It is reponsible to ensure that only one table item is selected at a time
     * and it also fires value change notifications.
     */
    private class MySelectionListener implements SelectionListener {

        /**
         * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
         */
        public void widgetDefaultSelected(SelectionEvent e) {
            widgetSelected(e);
        }

        /**
         * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
         */
        public void widgetSelected(SelectionEvent e) {
            if (e.item instanceof TableItem)
                onItemSelected((TableItem) e.item);
            else if (e.getSource() == add)
                onAddSelected();
            else if (e.getSource() == edit)
                onEditSelected();
            else if (e.getSource() == remove)
                onRemoveSelected();
        }

    }

    /**
     * Adds a new table item for the given doxygen instance
     */
    private void addItem(Doxygen doxygen) {
        TableItem item = new TableItem(table, 0);

        item.setData(doxygen);
        updateItem(item);
    }

    /**
     * Retrieves the type of the given doxygen wrapper instance
     */
    private static String getDoxygenType(final Doxygen doxygen) {
        if (doxygen instanceof DefaultDoxygen)
            return "Default";
        else if (doxygen instanceof CustomDoxygen)
            return "Custom";
        else if (doxygen instanceof BundledDoxygen)
            return "Bundled";
        else
            return "Uknown";
    }

    /**
     * Updates the given table item.
     */
    private void updateItem(TableItem item) {
        // Item data preparation.
        final Doxygen doxygen = (Doxygen) item.getData();
        final String type = getDoxygenType(doxygen);
        final String version = doxygen.getVersion();
        final String description = doxygen.getDescription();

        // Updates the item properties.
        item.setImage((version == null)
                ? PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_WARN_TSK)
                : null);
        item.setText(VERSION_COLUMN_INDEX, (version == null) ? "unknown" : version);
        item.setText(TYPE_COLUMN_INDEX, type);
        item.setText(DESCRIPTION_COLUMN_INDEX, description);

        // Updates the table layout.
        table.getColumn(VERSION_COLUMN_INDEX).pack();
        table.getColumn(TYPE_COLUMN_INDEX).pack();
        table.getColumn(DESCRIPTION_COLUMN_INDEX).pack();
        table.layout();
    }

    /**
     * Checkes the table item representing the given doxygen identifier.
     */
    private void checkItem(final String identifier) {
        TableItem[] items = table.getItems();

        for (int i = 0; i < items.length; ++i) {
            Doxygen current = (Doxygen) items[i].getData();

            items[i].setChecked(current.getIdentifier().equalsIgnoreCase(identifier));
        }
    }

    /**
     * Retrieves checked items.
     *
     * @return   the checked item or null if none
     */
    private TableItem[] getCheckedItems() {
        // Pre-condition
        assert (table != null);

        Vector<TableItem> checked = new Vector<TableItem>();
        TableItem[] items = table.getItems();

        for (int i = 0; i < items.length; ++i) {
            if (items[i].getChecked() == true) {
                checked.add(items[i]);
            }
        }
        return (TableItem[]) checked.toArray(new TableItem[0]);
    }

    /**
     * Process the click on the add button.
     */
    private void onAddSelected() {
        // Asks the user to select a location containing a doxygen binary.
        CustomDoxygenDialog dialog = new CustomDoxygenDialog(getPage().getShell(), null);
        dialog.open();
        String directory = dialog.getTargetDirectory();
        if (directory != null) {
            addItem(new CustomDoxygen(directory));
        }
    }

    /**
     * Process the click on the edit button
     */
    private void onEditSelected() {
        // Pre-condition
        assert (table != null);

        // Retrieves the checked items
        TableItem[] selected = table.getSelection();

        // Retrieves the doxygen wrapper associated to the selected item
        assert (selected.length == 1);
        Doxygen doxygen = (Doxygen) selected[0].getData();

        // Asks the user to select a location containing a doxygen binary.
        assert (doxygen instanceof CustomDoxygen);
        CustomDoxygen customDoxygen = (CustomDoxygen) doxygen;
        CustomDoxygenDialog dialog = new CustomDoxygenDialog(getPage().getShell(), customDoxygen.getLocation());
        dialog.open();
        String directory = dialog.getTargetDirectory();
        if (directory != null) {
            customDoxygen.setLocation(directory);
            updateItem(selected[0]);
        }
    }

    /**
     * Process the click on the remove button
     */
    private void onRemoveSelected() {
        // Pre-condition
        assert (table != null);

        table.remove(table.getSelectionIndex());
        refreshValidState();
    }

    /**
     * Process the selection of the given table item.
     */
    private void onItemSelected(TableItem item) {
        if (item.getChecked() == true) {
            TableItem[] checked = getCheckedItems();

            // Updates checked items so that only one is checked at the same time.
            for (int i = 0; i < checked.length; ++i) {
                if (checked[i] != item) {
                    checked[i].setChecked(false);
                }
            }

            // Selects the item that has been checked.
            table.setSelection(table.indexOf(item));

            // TODO only supported in eclipse 3.2
            // table.setSelection( item );

            // Fires some notifications.
            fireValueChanged(VALUE, null, null);
        }

        // Updates button states
        final boolean enable = item.getData() instanceof CustomDoxygen;

        edit.setEnabled(enable);
        remove.setEnabled(enable);

        // Refreshes the field validity.
        refreshValidState();
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#adjustForNumColumns(int)
     */
    protected void adjustForNumColumns(int numColumns) {
        // Pre-condition
        assert (table != null);

        GridData tableData = (GridData) table.getLayoutData();
        GridData buttonsData = (GridData) buttons.getLayoutData();

        tableData.horizontalSpan = numColumns - 1;
        buttonsData.horizontalSpan = 1;
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#doFillIntoGrid(org.eclipse.swt.widgets.Composite, int)
     */
    protected void doFillIntoGrid(Composite parent, int numColumns) {
        // Pre-condition
        assert (table == null);

        // Creates the combo controls containing all available doxygen wrappers.
        GridData tableData = new GridData(GridData.FILL_BOTH);

        table = new Table(parent, SWT.SINGLE | SWT.CHECK | SWT.BORDER | SWT.FULL_SELECTION);
        tableData.horizontalSpan = numColumns - 1;
        table.setLayoutData(tableData);
        table.addSelectionListener(new MySelectionListener());

        TableColumn versionColumn = new TableColumn(table, SWT.LEFT, VERSION_COLUMN_INDEX);
        TableColumn typeColumn = new TableColumn(table, SWT.LEFT, TYPE_COLUMN_INDEX);
        TableColumn descriptionColumn = new TableColumn(table, SWT.LEFT, DESCRIPTION_COLUMN_INDEX);

        versionColumn.setText("Version");
        typeColumn.setText("Type");
        descriptionColumn.setText("Description");
        table.setHeaderVisible(true);

        // Creates the composite containing all buttons and located on the right side of the table.
        GridData buttonsData = new GridData(GridData.END);
        FillLayout buttonsLayout = new FillLayout(SWT.VERTICAL);

        buttons = new Composite(parent, SWT.NO_FOCUS);
        buttonsData.horizontalSpan = 1;
        buttonsData.horizontalAlignment = SWT.FILL;
        buttons.setLayoutData(buttonsData);
        buttonsLayout.spacing = 5;
        buttons.setLayout(buttonsLayout);

        // Creates the button controlling custom doyxgen wrappers.
        add = new Button(buttons, SWT.PUSH);
        edit = new Button(buttons, SWT.PUSH);
        remove = new Button(buttons, SWT.PUSH);

        add.setText("Add...");
        add.addSelectionListener(new MySelectionListener());
        edit.setText("Edit...");
        edit.addSelectionListener(new MySelectionListener());
        edit.setEnabled(false);
        remove.setText("Remove");
        remove.addSelectionListener(new MySelectionListener());
        remove.setEnabled(false);
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#doLoad()
     */
    protected void doLoad() {
        // Adds default doxygen instance.
        addItem(new DefaultDoxygen());

        // Adds custom doxygens.
        final String raw = getPreferenceStore().getString(IPreferences.CUSTOM_DOXYGENS);
        final String[] splitted = raw.split("\n");
        for (int i = 0; i < splitted.length; ++i) {
            Doxygen doxygen = Doxygen.getFromClassAndIdentifier(CustomDoxygen.class, splitted[i]);
            if (doxygen != null) {
                addItem(doxygen);
            } else {
                Plugin.getDefault().logError(splitted[i] + ": invalid custom doxygen identifier found.");
            }
        }

        // Adds bundled doxygens.
        Collection<?> bundled = BundledDoxygen.getAll();
        Iterator<?> i = bundled.iterator();
        while (i.hasNext()) {
            addItem((Doxygen) i.next());
        }

        // Select the default doxygen wrapper
        checkItem(getPreferenceStore().getString(IPreferences.DEFAULT_DOXYGEN));
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#doLoadDefault()
     */
    protected void doLoadDefault() {
        // Adds default doxygen instance.
        addItem(new DefaultDoxygen());

        // Select the default doxygen wrapper
        checkItem(getPreferenceStore().getDefaultString(IPreferences.DEFAULT_DOXYGEN));
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#doStore()
     */
    protected void doStore() {
        // Pre-condition
        assert (table != null);

        // Saves all custom doxygen wrappers.
        TableItem[] items = table.getItems();
        String serialized = new String();
        for (int i = 0; i < items.length; ++i) {
            Object itemData = items[i].getData();

            if (itemData instanceof CustomDoxygen) {
                CustomDoxygen doxygen = (CustomDoxygen) itemData;

                serialized = serialized.concat(doxygen.getIdentifier());
                serialized = serialized.concat("\n");
            }
        }
        getPreferenceStore().setValue(IPreferences.CUSTOM_DOXYGENS, serialized);

        // Saves the checked item.
        TableItem[] checked = getCheckedItems();
        String defaultDoxygen = new String();
        if (checked.length == 1) {
            Doxygen doxygen = (Doxygen) checked[0].getData();

            defaultDoxygen = doxygen.getIdentifier();
        }
        getPreferenceStore().setValue(IPreferences.DEFAULT_DOXYGEN, defaultDoxygen);
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#refreshValidState()
     */
    protected void refreshValidState() {
        TableItem[] checked = getCheckedItems();
        boolean oldValid = valid;
        boolean newValid = checked.length == 1;

        // Updates validity and error message.
        valid = newValid;
        if (valid == false) {
            showErrorMessage("Select the doxygen version to use.");
        } else {
            clearErrorMessage();
        }

        // Send some notifications.
        if (newValid != oldValid) {
            fireStateChanged(IS_VALID, oldValid, newValid);
        }
    }

    /**
     * Constructor
     */
    public DefaultDoxygenFieldEditor(Composite parent) {
        super(IPreferences.DEFAULT_DOXYGEN, "Doxygen:", parent);
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#getNumberOfControls()
     */
    public int getNumberOfControls() {
        return 2;
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#isValid()
     */
    public boolean isValid() {
        return valid;
    }

    /**
     * @see org.eclipse.jface.preference.FieldEditor#setFocus()
     */
    public void setFocus() {
        super.setFocus();
        table.setFocus();
    }

}