carisma.ui.eclipse.preferences.pages.EditorPriorityList.java Source code

Java tutorial

Introduction

Here is the source code for carisma.ui.eclipse.preferences.pages.EditorPriorityList.java

Source

/*******************************************************************************
 * Copyright (c) 2011 Software Engineering Institute, TU Dortmund.
 * 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:
 *    {SecSE group} - initial API and implementation and/or initial documentation
 *******************************************************************************/
package carisma.ui.eclipse.preferences.pages;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.SWT;
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.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.ui.dialogs.ListDialog;

import carisma.core.Carisma;
import carisma.core.models.ModelType;
import carisma.ui.eclipse.CarismaGUI;
import carisma.ui.eclipse.editors.descriptions.EditorDescriptor;
import carisma.ui.eclipse.editors.descriptions.TextEditorDescriptor;
import carisma.ui.eclipse.preferences.Constants;

/**
 * A field editor for displaying and storing a list of strings. Buttons are
 * provided for adding items to the list and removing items from the list.
 */
public class EditorPriorityList extends FieldEditor {

    /**
     * Button Add.
     */
    private Button btAdd = null;
    /**
     * Button Remove. (cannot be null-> NullPointerException)
     */
    private Button btRemove = null;
    /**
     * Button Down. (cannot be null-> NullPointerException)
     */
    private Button btDown = null;
    /**
     * Button Up. (cannot be null-> NullPointerException)
     */
    private Button btUp = null;
    /**
     * Model type label.
     */
    private Label modelTypeLabel = null;
    /**
     * Title label.
     */
    private Label titleLabel = null;
    /**
     * Note label1.
     */
    private Label noteLabel1 = null;
    /**
     * Note label2.
     */
    private Label noteLabel2 = null;
    /**
     * Composite container for the Field Editor.
     */
    private Composite container = null;
    /**
     * List Control for the items. 
     */
    List guiList = null;
    /** 
     * Constant to separate different entries.
     */
    private static final String SEPARATOR = ";";
    /**
     * Constant to separate List entries.
     */
    private static final String SEPARATOR_LIST = ",";
    /**
     * Constant to identify the model type.
     */
    private static final String SELECTED_MODELTYPE = "MODELTYPE=";
    /**
     * Constant to identify list items.
     */
    private static final String LIST_ITEMS = "LIST_ITEMS=";
    /**
     * Combo box for available model types.
     */
    Combo modelTypeCombo = null;
    /**
     * List of available model types.
     */
    private java.util.List<ModelType> listModelTypes = null;
    /**
     * Structure to manage model types and selected editors. 
     */
    HashMap<String, ArrayList<String>> selectedEditors = null;

    /**
     * Konstruktor.
     * @param name the name of the FieldEditor in the Preference Page
     * @param labelText Label
     * @param parent parent
     */
    public EditorPriorityList(final String name, final String labelText, final Composite parent) {
        init(name, labelText);
        createControl(parent);

        this.container = parent;
    }

    @Override
    protected final void adjustForNumColumns(final int numColumns) {

        ((GridData) this.container.getLayoutData()).horizontalSpan = numColumns;
    }

    @Override
    protected final void doFillIntoGrid(final Composite parent, final int numColumns) {
        this.container = parent;
        GridLayout layout = new GridLayout(2, false);
        this.container.setLayout(layout);
        this.container.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        this.modelTypeLabel = new Label(this.container, SWT.LEFT);
        this.modelTypeLabel.setText("Select ModelType:");
        this.modelTypeCombo = new Combo(this.container, SWT.READ_ONLY);

        this.modelTypeCombo.addSelectionListener(new SelectionListener() {

            @Override
            public void widgetSelected(final SelectionEvent e) {
                updatePriorityList();
                selectionChanged();
            }

            @Override
            public void widgetDefaultSelected(final SelectionEvent e) {
                updatePriorityList();
                selectionChanged();
            }
        });

        this.titleLabel = getLabelControl(this.container);
        GridData gdTitleLabel = new GridData(GridData.FILL_HORIZONTAL);
        gdTitleLabel.horizontalSpan = 2;
        this.titleLabel.setLayoutData(gdTitleLabel);

        this.guiList = new List(this.container, SWT.BORDER);
        GridData listGd = new GridData(SWT.FILL, SWT.FILL, true, true);
        listGd.verticalAlignment = GridData.FILL;
        listGd.horizontalAlignment = GridData.FILL;
        this.guiList.setLayoutData(listGd);
        this.guiList.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                selectionChanged();
            }
        });

        Composite addRemoveGroup = new Composite(this.container, SWT.NONE);
        addRemoveGroup.setLayoutData(new GridData());

        GridLayout addRemoveLayout = new GridLayout();
        addRemoveLayout.numColumns = 2;
        addRemoveLayout.marginHeight = 0;
        addRemoveLayout.marginWidth = 0;
        addRemoveGroup.setLayout(addRemoveLayout);

        Composite buttonGroup = new Composite(addRemoveGroup, SWT.NONE);
        buttonGroup.setLayoutData(new GridData(SWT.RIGHT));
        GridLayout buttonLayout = new GridLayout();
        buttonLayout.marginHeight = 0;
        buttonLayout.marginWidth = 0;
        buttonGroup.setLayout(buttonLayout);

        this.btAdd = new Button(buttonGroup, SWT.PUSH);
        this.btAdd.setText("Add");
        this.btAdd.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        this.btAdd.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                super.widgetSelected(e);
                String result = openEditorSelectionDialog();
                if (result != null) {
                    EditorPriorityList.this.guiList.add(result);
                    ArrayList<String> list = EditorPriorityList.this.selectedEditors
                            .get(EditorPriorityList.this.modelTypeCombo.getText());
                    if (list != null) {
                        list.add(result);
                    } else {
                        ArrayList<String> editor = new ArrayList<>();
                        editor.add(result);
                        EditorPriorityList.this.selectedEditors
                                .put(EditorPriorityList.this.modelTypeCombo.getText(), editor);
                    }
                    selectionChanged();
                }
            }
        });

        this.btRemove = new Button(buttonGroup, SWT.PUSH);
        this.btRemove.setText("Remove");
        this.btRemove.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        this.btRemove.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                super.widgetSelected(e);
                int selection = EditorPriorityList.this.guiList.getSelectionIndex();
                if (selection > -1) {
                    java.util.List<String> editors = EditorPriorityList.this.selectedEditors
                            .get(EditorPriorityList.this.modelTypeCombo.getText());
                    editors.remove(EditorPriorityList.this.guiList
                            .getItem(EditorPriorityList.this.guiList.getSelectionIndex()));

                    EditorPriorityList.this.guiList.remove(EditorPriorityList.this.guiList.getSelectionIndex());
                    selectionChanged();
                }
            }
        });

        this.btUp = new Button(buttonGroup, SWT.PUSH);
        this.btUp.setText("Up");
        this.btUp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        this.btUp.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                super.widgetSelected(e);
                int index = EditorPriorityList.this.guiList.getSelectionIndex();
                if (index > 0) {
                    String selectedItem = EditorPriorityList.this.guiList.getItem(index);
                    String itemAboveSelected = EditorPriorityList.this.guiList.getItem(index - 1);

                    java.util.List<String> editors = EditorPriorityList.this.selectedEditors
                            .get(EditorPriorityList.this.modelTypeCombo.getText());
                    editors.add(index - 1, editors.remove(index));

                    EditorPriorityList.this.guiList.add(selectedItem, index - 1);
                    EditorPriorityList.this.guiList.remove(index);
                    EditorPriorityList.this.guiList.add(itemAboveSelected, index);
                    EditorPriorityList.this.guiList.remove(index + 1);
                    EditorPriorityList.this.guiList.select(index - 1);
                }
            }
        });

        this.btDown = new Button(buttonGroup, SWT.PUSH);
        this.btDown.setText("Down");
        this.btDown.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        this.btDown.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                super.widgetSelected(e);
                int index = EditorPriorityList.this.guiList.getSelectionIndex();
                if (index > -1 && index < EditorPriorityList.this.guiList.getItemCount() - 1) {
                    String selectedItem = EditorPriorityList.this.guiList.getItem(index);
                    String itemBelowSelected = EditorPriorityList.this.guiList.getItem(index + 1);

                    java.util.List<String> editors = EditorPriorityList.this.selectedEditors
                            .get(EditorPriorityList.this.modelTypeCombo.getText());
                    editors.add(index + 1, editors.remove(index));

                    EditorPriorityList.this.guiList.remove(index + 1);
                    EditorPriorityList.this.guiList.remove(index);
                    EditorPriorityList.this.guiList.add(itemBelowSelected, index);
                    EditorPriorityList.this.guiList.add(selectedItem, index + 1);
                    EditorPriorityList.this.guiList.select(index + 1);
                }
            }
        });
        Composite addComposite = new Composite(this.container, SWT.NONE);
        layout = new GridLayout(2, false);
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        addComposite.setLayout(layout);
        gdTitleLabel = new GridData(GridData.FILL_HORIZONTAL);
        gdTitleLabel.horizontalSpan = 2;
        addComposite.setLayoutData(gdTitleLabel);

        /*noteLabel1 = new Label(addComposite, SWT.NONE);
        noteLabel1.setFont(new Font(addComposite.getDisplay(), "Arial", 9, SWT.BOLD)); 
        noteLabel1.setText("Note:");
        noteLabel2 = new Label(addComposite, SWT.NONE);
        noteLabel2.setText("If the model can't be opened using any of the above editors, the user will be asked for an editor to use.");*/
        selectionChanged();
    }

    @Override
    protected final void doLoad() {
        //CarismaGUI.INSTANCE.getPreferenceStore().setValue(getPreferenceName(), "");
        String savedProperties = CarismaGUI.INSTANCE.getPreferenceStore().getString(getPreferenceName());
        init(savedProperties);
        updatePriorityList();
    }

    @Override
    public final void load() {
        doLoad();
        //super.load();
    }

    @Override
    protected final void doLoadDefault() {
        //CarismaGUI.INSTANCE.getPreferenceStore().setValue(getPreferenceName(), "");
        //String savedProperties = getPreferenceStore().getDefaultString(getPreferenceName());
        init("");
        updatePriorityList();
    }

    @Override
    protected final void doStore() {
        java.util.List<String> toBeSaved = new java.util.ArrayList<>();
        Set<Map.Entry<String, java.util.ArrayList<String>>> set = this.selectedEditors.entrySet();
        for (Map.Entry<String, java.util.ArrayList<String>> entry : set) {
            for (String editor : entry.getValue()) {
                toBeSaved.add(entry.getKey() + ":" + editor);
            }
        }
        StringBuffer result = new StringBuffer();
        result.append(SELECTED_MODELTYPE + this.modelTypeCombo.getText() + SEPARATOR);
        result.append(LIST_ITEMS);
        for (int i = 0; i < toBeSaved.size(); i++) {
            result.append(toBeSaved.get(i));
            if (i + 1 < toBeSaved.size()) {
                result.append(SEPARATOR_LIST);
            }
        }
        CarismaGUI.INSTANCE.getPreferenceStore().setValue(getPreferenceName(), result.toString());
    }

    @Override
    public final void store() {
        doStore();
        //super.store();

    }

    @Override
    public final int getNumberOfControls() {

        return 1;
    }

    /**
     * Initializes the internal data structure and the GUI elements.
     * @param propertyString The saved properties represented as string
     */
    private void init(final String propertyString) {
        this.listModelTypes = Carisma.getInstance().getModelTypeRegistry().getSupportedTypes();

        this.modelTypeCombo.removeAll();
        for (ModelType type : this.listModelTypes) {
            this.modelTypeCombo.add(type.getName());
        }

        this.selectedEditors = new HashMap<>();
        this.guiList.removeAll();
        for (ModelType mt : this.listModelTypes) {
            java.util.List<String> editors = getSavedEditorsByModelType(propertyString, mt.getName());
            if (editors.size() > 0) {
                this.selectedEditors.put(mt.getName(), (ArrayList<String>) editors);
            } else {
                this.selectedEditors.put(mt.getName(),
                        new ArrayList<>(Arrays.asList(new String[] { TextEditorDescriptor.NAME })));
            }
        }

        initModeltypeCombo(propertyString);
    }

    /**
     * Initializes the GUI element ModelTypeCombo.
     * @param propertyString The saved properties represented as string
     */
    private void initModeltypeCombo(final String propertyString) {
        String selectedModeltype = getProperty(propertyString, SELECTED_MODELTYPE);

        String[] comboItems = this.modelTypeCombo.getItems();
        int index = -1;
        for (int i = 0; i < comboItems.length; i++) {
            if (comboItems[i].equalsIgnoreCase(selectedModeltype)) {
                index = i;
            }
        }
        if (index != -1) {
            this.modelTypeCombo.select(index);
        } else {
            if (comboItems.length > 0) {
                this.modelTypeCombo.select(0);
            }
        }
    }

    /**
     * Updates the priority list.
     */
    void updatePriorityList() {
        this.guiList.removeAll();
        String selectedModeltype = this.modelTypeCombo.getText();
        java.util.List<String> items = this.selectedEditors.get(selectedModeltype);
        if (items != null) {
            for (String editor : items) {
                this.guiList.add(editor);
            }
        }
    }

    /**
     * Opens a dialog to add an editor to the priority list.
     * @return the result, or <code>null</code> if nothing chosen
     */
    String openEditorSelectionDialog() {
        ListDialog dialog = new ListDialog(this.container.getShell());
        dialog.setContentProvider(ArrayContentProvider.getInstance());
        dialog.setLabelProvider(new LabelProvider());
        dialog.setTitle("Add editor for automatic opening");
        // TODO write Context help and reference it here

        java.util.List<String> input = getAvailableEditors();
        dialog.setInput(input);
        dialog.open();

        Object[] result = dialog.getResult();
        if (result != null && result.length > 0) {
            return (String) result[0];
        }

        return null;

    }

    /**
     * Filters the available editors in regard to the selected model type.
     * @return java.util.List<String> List of available editors represented as string object
     */
    private java.util.List<String> getAvailableEditors() {
        java.util.List<String> choosenEditors = Arrays.asList(this.guiList.getItems());

        // Info: availableItems must be a copy of list. Otherwise, when removing items in list, they are no more there
        java.util.ArrayList<String> availableItems = new ArrayList<>();

        java.util.List<EditorDescriptor> edDescriptors = CarismaGUI.INSTANCE.getEditorRegistry()
                .getRegisteredEditors();
        for (EditorDescriptor edDesc : edDescriptors) {
            if (edDesc.isAvailable() && !choosenEditors.contains(edDesc.getName()) && (edDesc.getTypes()
                    .contains(".*")
                    || edDesc.getTypes().contains(this.modelTypeCombo.getText().toLowerCase())
                    || (this.modelTypeCombo.getText().equalsIgnoreCase("uml2") ? edDesc.getTypes().contains("uml")
                            : this.modelTypeCombo.getText().equalsIgnoreCase("bpmn2")
                                    ? edDesc.getTypes().contains("bpmn")
                                    : false))) {
                availableItems.add(edDesc.getName());
            }
        }

        return availableItems;
    }

    /**
     * Remove-/Up-/Down-Buttons are disabled, when listControl contains only one entry.
     */
    void selectionChanged() {

        int count = this.guiList.getItemCount();
        if (count > 1) {
            this.btRemove.setEnabled(true);
            this.btUp.setEnabled(true);
            this.btDown.setEnabled(true);
            return;
        }
        this.btRemove.setEnabled(false);
        this.btUp.setEnabled(false);
        this.btDown.setEnabled(false);

    }

    /**
      * Set whether or not the controls in the field editor are enabled.
      * @param enabled The enabled state.
      * @param parent The parent of the controls in the group.
      *  Used to create the controls if required.
      */
    @Override
    public final void setEnabled(final boolean enabled, final Composite parent) {
        super.setEnabled(enabled, parent);
        this.btAdd.setEnabled(enabled);
        this.btRemove.setEnabled(enabled);
        this.btUp.setEnabled(enabled);
        this.btDown.setEnabled(enabled);

        this.modelTypeCombo.setEnabled(enabled);
        this.guiList.setEnabled(enabled);

        this.modelTypeLabel.setEnabled(enabled);
        this.titleLabel.setEnabled(enabled);
        /*noteLabel1.setEnabled(enabled);
        noteLabel2.setEnabled(enabled);*/

        if (enabled) {
            selectionChanged();
        }
    }

    /**
     * Method extract a saved property. 
     * @param savedString The saved property string
     * @param propertyName The property name
     * @return If available the desired property represented as string,
     *    otherwise an empty string.
     */
    private static String getProperty(final String savedString, final String propertyName) {
        String[] properties = savedString.split(SEPARATOR);
        for (String prop : properties) {
            if (prop.length() > propertyName.length()
                    && prop.substring(0, propertyName.length()).equalsIgnoreCase(propertyName)) {
                return prop.substring(propertyName.length());
            }
        }
        return "";
    }

    /**
     * Method will look up the saved editors by model type.
     * @param savedString The saved property string
     * @param modelType The desired model type
     * @return List of available editors represented as string object
     */
    private static java.util.List<String> getSavedEditorsByModelType(final String savedString,
            final String modelType) {
        String[] tmp = getProperty(savedString, LIST_ITEMS).split(SEPARATOR_LIST);
        ArrayList<String> result = new ArrayList<>();
        if (tmp.length != 0) {
            for (String str : tmp) {
                if (str.length() > modelType.length() + 1
                        && str.substring(0, modelType.length() + 1).equalsIgnoreCase(modelType + ":")) {
                    result.add(str.substring(modelType.length() + 1));
                }
            }
            return result;
        }
        return result;
    }

    /**
     * Method will look up the saved editors by model type.
     * @param modelType The desired model type 
     * @return List of available editors represented as string object
     */
    public static java.util.List<String> getPriorityList(final String modelType) {
        String savedProperties = CarismaGUI.INSTANCE.getPreferenceStore().getString(Constants.EDITORS_LIST);
        return getSavedEditorsByModelType(savedProperties, modelType);
    }
}