net.rim.ejde.internal.ui.preferences.PreprocessDirectiveUI.java Source code

Java tutorial

Introduction

Here is the source code for net.rim.ejde.internal.ui.preferences.PreprocessDirectiveUI.java

Source

/*
* Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License, Version 1.0,
* which accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*
*/
package net.rim.ejde.internal.ui.preferences;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import net.rim.ejde.internal.core.IConstants;
import net.rim.ejde.internal.model.BasicBlackBerryProperties.PreprocessorTag;
import net.rim.ejde.internal.model.BlackBerryProject;
import net.rim.ejde.internal.model.BlackBerrySDKInstall;
import net.rim.ejde.internal.model.BlackBerryVMInstallType;
import net.rim.ejde.internal.model.preferences.PreprocessorPreferences;
import net.rim.ejde.internal.util.Messages;
import net.rim.ejde.internal.util.VMUtils;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstallChangedListener;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ICheckStateProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
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.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

/**
 * This class represent a common UI of the view for preprocess directives.
 *
 */
public abstract class PreprocessDirectiveUI implements IPropertyChangeListener, IVMInstallChangedListener {
    static private final Logger log = Logger.getLogger(PreprocessDirectiveUI.class);
    private BlackBerryProject _bbProject;
    private int _scope;
    private Composite _parent;
    private CheckboxTableViewer _preprocessorTableViewer;
    private Table _fTable;
    private Button _addButton;
    private Button _removeButton;
    private Button _editButton;
    private Button _selectAllButton;
    private Button _deselectAllButton;

    /**
     * Construct a PreprocessDirectiveUI instance.
     *
     * @param parent
     * @param scope
     */
    public PreprocessDirectiveUI(Composite parent, int scope) {
        this(parent, scope, null);
    }

    /**
     * Construct a PreprocessDirectiveUI instance.
     *
     * @param parent
     * @param scope
     * @param bbProject
     */
    public PreprocessDirectiveUI(Composite parent, int scope, BlackBerryProject bbProject) {
        _parent = parent;
        _scope = scope;
        _bbProject = bbProject;
        createContent();
    }

    private void createContent() {
        Composite main = new Composite(_parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        layout.numColumns = 1;
        main.setLayout(layout);
        main.setLayoutData(new GridData(GridData.FILL_BOTH));

        Composite tableButtonComposite = new Composite(main, SWT.NONE);
        tableButtonComposite.setLayout(BasicPrefsPage.getGridLayout(2, 5, 0, 0, 0));
        tableButtonComposite.setLayoutData(new GridData(GridData.FILL_BOTH));

        Composite tableComposite = new Composite(tableButtonComposite, SWT.NONE);
        tableComposite.setLayout(BasicPrefsPage.getGridLayout(1, 0, 0, 0, 5));
        tableComposite.setLayoutData(new GridData(GridData.FILL_BOTH));

        Font font = _parent.getFont();
        _fTable = new Table(tableComposite, SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);

        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.heightHint = 250;
        gd.widthHint = 338;
        _fTable.setLayoutData(gd);
        _fTable.setFont(font);
        _fTable.setHeaderVisible(true);
        _fTable.setLinesVisible(true);
        _fTable.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                updateButtons();
            }
        });

        TableColumn statusColumn = new TableColumn(_fTable, SWT.NONE);
        statusColumn.setText(Messages.BuildPrefsPage_PreprocessActiveColulmnHeader);
        statusColumn.setWidth(50);

        TableColumn tagsColumn = new TableColumn(_fTable, SWT.NONE);
        tagsColumn.setText(Messages.BuildPrefsPage_PreprocessTagsColulmnHeader);
        tagsColumn.setWidth(200);
        tagsColumn.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                Object input = _preprocessorTableViewer.getInput();
                if (input instanceof PreprocessorTag[]) {
                    PreprocessorTag[] tags = (PreprocessorTag[]) input;
                    Arrays.sort(tags, new DirectiveString());
                    _preprocessorTableViewer.setInput(tags);
                }
            }
        });
        TableColumn scopeColumn = new TableColumn(_fTable, SWT.NONE);
        scopeColumn.setText(Messages.BuildPrefsPage_PreprocessScopeColulmnHeader);
        scopeColumn.setWidth(100);
        scopeColumn.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                Object input = _preprocessorTableViewer.getInput();
                if (input instanceof PreprocessorTag[]) {
                    PreprocessorTag[] tags = (PreprocessorTag[]) input;
                    Arrays.sort(tags, new ScopeComparator());
                    _preprocessorTableViewer.setInput(tags);
                }
            }
        });

        _preprocessorTableViewer = new CheckboxTableViewer(_fTable);
        _preprocessorTableViewer.setContentProvider(new PreprocessorTagContentProvider());
        _preprocessorTableViewer.setLabelProvider(new PreprocessorTagLabelProvider());
        _preprocessorTableViewer.setCheckStateProvider(new PreprocessorTagCheckStateProvider());
        _preprocessorTableViewer.addCheckStateListener(new ICheckStateListener() {
            @Override
            public void checkStateChanged(CheckStateChangedEvent event) {
                Object element = event.getElement();
                if (element instanceof PreprocessorTag) {
                    PreprocessorTag tag = (PreprocessorTag) element;
                    if (tag.getScopeID() <= _scope) {
                        tag.setIsActive(Boolean.valueOf(event.getChecked()));
                        performChanged();
                    } else {
                        _preprocessorTableViewer.setChecked(tag, !event.getChecked());
                    }
                }
            }
        });
        // create a button group with buttons
        Composite buttonComposite = new Composite(tableButtonComposite, SWT.NONE);
        buttonComposite.setLayout(BasicPrefsPage.getGridLayout(1, 0, 0, 0, 0));
        buttonComposite.setLayoutData(new GridData(GridData.FILL_VERTICAL));

        // add "Add..." button
        _addButton = new Button(buttonComposite, SWT.PUSH);
        _addButton.setText(Messages.BasicPrefsPage_AddButtonLabel);
        BasicPrefsPage.setDialogConfirmButtonLayoutData(_addButton, 0);

        // add "Remove" button
        _removeButton = new Button(buttonComposite, SWT.PUSH);
        _removeButton.setText(Messages.BasicPrefsPage_RemoveButtonLabel);
        BasicPrefsPage.setDialogConfirmButtonLayoutData(_removeButton, 5);

        // add "Edit" button
        _editButton = new Button(buttonComposite, SWT.PUSH);
        _editButton.setText(Messages.BasicPrefsPage_EditButtonLabel);
        BasicPrefsPage.setDialogConfirmButtonLayoutData(_editButton, 5);

        // add "Select All" button
        _selectAllButton = new Button(buttonComposite, SWT.PUSH);
        _selectAllButton.setText(Messages.BasicPrefsPage_SelectAllButtonLabel);
        BasicPrefsPage.setDialogConfirmButtonLayoutData(_selectAllButton, 5);

        // add "De-select All" button
        _deselectAllButton = new Button(buttonComposite, SWT.PUSH);
        _deselectAllButton.setText(Messages.BasicPrefsPage_DeselectAllButtonLabel);
        BasicPrefsPage.setDialogConfirmButtonLayoutData(_deselectAllButton, 5);

        // add listener to listen to the event when "Add..." button is pressed
        final PreprocessDirectiveUI ui = this;
        _addButton.addSelectionListener(new SelectionAdapter() {
            PreprocessDefineInputValidator validator = new PreprocessDefineInputValidator(ui);

            @Override
            public void widgetSelected(SelectionEvent e) {
                InputDialog dialog = new InputDialog(_parent.getShell(),
                        Messages.BuildPrefsPage_PreprocessAddDialogTitle,
                        Messages.BuildPrefsPage_PreprocessDialogLabel, "", validator);
                dialog.open();
                String tags = dialog.getValue();
                PreprocessorTag tag = null;
                List<PreprocessorTag> input = getInput();
                boolean changed = false;
                for (String tagString : StringUtils.split(tags, IConstants.SEMICOLON_MARK)) {
                    tag = new PreprocessorTag(tagString, true, _scope);
                    input.add(tag);
                    if (!changed) {
                        changed = true;
                    }
                }
                if (changed) {
                    performChanged();
                }
                _preprocessorTableViewer.setInput(input.toArray(new PreprocessorTag[input.size()]));
                enableNonAddButtons();
            }
        });

        // add listener to listen to the event when "Remove" button is pressed
        _removeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                List<PreprocessorTag> input = getInput();
                TableItem[] selections = _fTable.getSelection();
                for (int i = 0; i < selections.length; i++) {
                    input.remove(selections[i].getData());
                }
                _preprocessorTableViewer.setInput(input.toArray(new PreprocessorTag[input.size()]));
                disableNonAddButtons();
                if (selections.length > 0) {
                    performChanged();
                }
            }
        });

        // add listener to listen to the event when "Edit..." button is pressed
        _editButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                int[] selectedIndexes = _fTable.getSelectionIndices();
                PreprocessDefineInputValidator validator = null;
                String tagString = null;
                List<PreprocessorTag> input = getInput();
                PreprocessorTag tag;
                boolean changed = false;
                for (int tagIndex : selectedIndexes) {
                    TableItem item = _fTable.getItem(tagIndex);
                    String initialText = item.getText(1);
                    validator = new PreprocessDefineInputValidator(ui, true, initialText);
                    InputDialog dialog = new InputDialog(_parent.getShell(),
                            Messages.BuildPrefsPage_PreprocessEditDialogTitle,
                            Messages.BuildPrefsPage_PreprocessEditLabel, initialText, validator);
                    dialog.open();
                    tagString = dialog.getValue();
                    if ((!initialText.equals(tagString)) && (validator.isValid(tagString) == null)) {
                        tag = new PreprocessorTag(tagString, true, _scope);
                        input.remove(tagIndex);
                        input.add(tagIndex, tag);
                        if (!changed) {
                            changed = true;
                        }
                    }
                }
                _preprocessorTableViewer.setInput(input.toArray(new PreprocessorTag[input.size()]));
                if (changed) {
                    performChanged();
                }
            }
        });

        // add listener to listen to the event when "Select All" button is pressed
        _selectAllButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                List<PreprocessorTag> input = getInput();
                boolean changed = false;
                for (PreprocessorTag tag : input) {
                    if (tag.getScopeID() == _scope && !tag.isActive()) {
                        tag.setIsActive(true);
                        if (!changed) {
                            changed = true;
                        }
                    }
                }
                _preprocessorTableViewer.setInput(input.toArray(new PreprocessorTag[input.size()]));
                if (changed) {
                    performChanged();
                }
            }
        });
        // add listener to listen to the event when "Deselect All" button is pressed
        _deselectAllButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                List<PreprocessorTag> input = getInput();
                boolean changed = false;
                for (PreprocessorTag tag : input) {
                    if (tag.getScopeID() == _scope && tag.isActive()) {
                        tag.setIsActive(false);
                        if (!changed) {
                            changed = true;
                        }
                    }
                }
                _preprocessorTableViewer.setInput(input.toArray(new PreprocessorTag[input.size()]));
                if (changed) {
                    performChanged();
                }
            }
        });
        // show data
        showData();
    }

    private boolean isValidSelections(TableItem[] selections) {
        if (selections == null) {
            return false;
        }
        PreprocessorTag tag;
        for (int i = 0; i < selections.length; i++) {
            tag = (PreprocessorTag) selections[i].getData();
            if (tag.getScopeID() != _scope) {
                return false;
            }
        }
        return true;
    }

    /**
     * Display data.
     */
    public void showData() {
        List<PreprocessorTag> scopeDirectives = getDirectives();
        List<PreprocessorTag> otherDirectives = getUnChangableDirectives();
        List<PreprocessorTag> allDefines = new ArrayList<PreprocessorTag>();
        allDefines.addAll(otherDirectives);
        allDefines.addAll(scopeDirectives);
        PreprocessorTag[] directiveArray = allDefines.toArray(new PreprocessorTag[allDefines.size()]);
        Arrays.sort(directiveArray, new ScopeComparator());
        setInput(directiveArray);
    }

    protected void setInput(final PreprocessorTag[] input) {
        Display.getDefault().asyncExec(new Runnable() {
            public void run() {
                _preprocessorTableViewer.setInput(input);
                updateButtons();
            }
        });

    }

    private List<PreprocessorTag> getDirectives() {
        switch (_scope) {
        case PreprocessorTag.WS_SCOPE: {
            return getWorkspaceDirectives();
        }
        case PreprocessorTag.PJ_SCOPE: {
            if (_bbProject != null) {
                return Arrays.asList(_bbProject.getProperties()._compile.getPreprocessorDefines());
            } else {
                return new ArrayList<PreprocessorTag>(0);
            }
        }
        default: {
            return new ArrayList<PreprocessorTag>(0);
        }
        }
    }

    protected List<PreprocessorTag> getUnChangableDirectives() {
        ArrayList<PreprocessorTag> unChangableDirectives = new ArrayList<PreprocessorTag>();
        unChangableDirectives.addAll(getJREWorkspaceDirectives());
        if (_scope == PreprocessorTag.PJ_SCOPE) {
            unChangableDirectives.addAll(getWorkspaceDirectives());
        }
        return unChangableDirectives;
    }

    protected List<PreprocessorTag> getJREWorkspaceDirectives() {
        ArrayList<PreprocessorTag> JREDirectives = new ArrayList<PreprocessorTag>();
        List<String> JREDirectiveStrings = VMUtils.getAllJREDirectives();
        String currentCPDefine = IConstants.EMPTY_STRING;
        switch (_scope) {
        case PreprocessorTag.PJ_SCOPE: {
            if (_bbProject != null) {
                try {
                    currentCPDefine = VMUtils.getJREDirective(_bbProject);
                } catch (Exception e) {
                    // the jre used by the project may be removed
                    log.error(e.getMessage());
                }
            }
            break;
        }
        case PreprocessorTag.WS_SCOPE: {
            IVMInstall defaultVm = JavaRuntime.getDefaultVMInstall();
            if (BlackBerryVMInstallType.VM_ID.equals(defaultVm.getVMInstallType().getId())) {
                currentCPDefine = VMUtils.getJREDirective((BlackBerrySDKInstall) defaultVm);
            }
            break;
        }
        }

        for (String define : JREDirectiveStrings) {
            JREDirectives
                    .add(new PreprocessorTag(define, define.equals(currentCPDefine), PreprocessorTag.SDK_SCOPE));
        }
        return JREDirectives;
    }

    protected List<PreprocessorTag> getWorkspaceDirectives() {
        List<PreprocessorTag> workspaceDefines = PreprocessorPreferences.getPreprocessDefines();
        for (PreprocessorTag ppDefine : workspaceDefines) {
            ppDefine.setScopeID(PreprocessorTag.WS_SCOPE);
        }
        return workspaceDefines;
    }

    protected void disableNonAddButtons() {
        if (isTableEmpty(_fTable)) {
            _removeButton.setEnabled(false);
            _editButton.setEnabled(false);
            _selectAllButton.setEnabled(false);
            _deselectAllButton.setEnabled(false);
        }
    }

    protected List<String> getDefineList() {
        List<String> defines = new ArrayList<String>();
        for (TableItem itm : _fTable.getItems()) {
            defines.add(itm.getText(1));
        }
        return defines;
    }

    private void enableNonAddButtons() {
        if (!isTableEmpty(_fTable)) {
            _selectAllButton.setEnabled(true);
            _deselectAllButton.setEnabled(true);
        }
    }

    protected boolean isTableEmpty(Table table) {
        if (table == null)
            return false;

        return (table.getItems().length == 0);
    }

    protected int getIndexof(PreprocessorTag tag) {
        List<PreprocessorTag> tags = getInput();
        return tags.indexOf(tag);
    }

    /**
     * Gets the preprocess directives of the scope of this UI.
     *
     * @return
     */
    public List<PreprocessorTag> getScopeDirectives() {
        List<PreprocessorTag> tagList = new ArrayList<PreprocessorTag>();
        Object input = _preprocessorTableViewer.getInput();
        if (input instanceof PreprocessorTag[]) {
            PreprocessorTag[] tags = (PreprocessorTag[]) input;
            for (int i = 0; i < tags.length; i++) {
                if (tags[i].getScopeID() == _scope) {
                    tagList.add(tags[i]);
                }
            }
            return tagList;
        } else {
            return new ArrayList<PreprocessorTag>(0);
        }
    }

    private void updateButtons() {
        List<PreprocessorTag> tagList = getScopeDirectives();
        if (tagList.size() == 0) {
            _removeButton.setEnabled(false);
            _editButton.setEnabled(false);
            _selectAllButton.setEnabled(false);
            _deselectAllButton.setEnabled(false);
        } else {
            _removeButton.setEnabled(true);
            _editButton.setEnabled(true);
            _selectAllButton.setEnabled(true);
            _deselectAllButton.setEnabled(true);
        }
        TableItem[] selections = _fTable.getSelection();
        if (isValidSelections(selections)) {
            _editButton.setEnabled(_fTable.getSelectionCount() == 1);
            _removeButton.setEnabled(_fTable.getSelectionCount() >= 1);
        } else {
            _editButton.setEnabled(false);
            _removeButton.setEnabled(false);
        }
    }

    /**
     * Set a BlackBerry project.
     *
     * @param bbProject
     */
    public void setProject(BlackBerryProject bbProject) {
        _bbProject = bbProject;
    }

    public List<PreprocessorTag> getInput() {
        List<PreprocessorTag> tagList = new ArrayList<PreprocessorTag>();
        Object input = _preprocessorTableViewer.getInput();
        if (input instanceof PreprocessorTag[]) {
            PreprocessorTag[] tags = (PreprocessorTag[]) input;
            for (int i = 0; i < tags.length; i++) {
                tagList.add(tags[i]);
            }
            return tagList;
        } else {
            return new ArrayList<PreprocessorTag>(0);
        }
    }

    public void removeAllDirectives() {
        _fTable.removeAll();
    }

    @Override
    public void propertyChange(PropertyChangeEvent event) {
        if (event.getProperty().equalsIgnoreCase(PreferenceConstants.PREPROCESSOR_DEFINE_LIST)
                && _scope != PreprocessorTag.WS_SCOPE) {
            showData();
        }
    }

    abstract protected void performDefaults();

    abstract protected void performChanged();

    abstract protected void addListener();

    abstract protected void removeListener();

    /**
     * The label provider used for the PreprocessorTag table within the UI
     *
     */
    class PreprocessorTagLabelProvider extends LabelProvider implements ITableLabelProvider {

        @Override
        public Image getColumnImage(Object element, int columnIndex) {
            return null;
        }

        @Override
        public String getColumnText(Object element, int columnIndex) {
            if ((null != element) && PreprocessorTag.class.equals(element.getClass()) && (columnIndex >= 0)) {
                PreprocessorTag tag = (PreprocessorTag) element;
                switch (columnIndex) {
                case 0: {
                    return ""; //$NON-NLS-1$
                }

                case 1:
                    return tag.getPreprocessorDefine();
                case 2: {
                    if (tag.getScopeID() > _scope) {
                        int index = getIndexof((PreprocessorTag) element);
                        if (index >= 0) {
                            TableItem item = _preprocessorTableViewer.getTable().getItem(index);
                            if (item != null) {
                                item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY));
                            }
                        }
                    }
                    return PreprocessorTag.getScope(tag.getScopeID());
                }

                }
            }
            return ""; //$NON-NLS-1$
        }

    }

    /**
     * The content provider used for the PreprocessorTags table within the UI
     *
     *
     */
    class PreprocessorTagContentProvider implements IStructuredContentProvider {
        public Object[] getElements(Object inputElement) {
            if (inputElement instanceof PreprocessorTag[]) {
                PreprocessorTag input[] = (PreprocessorTag[]) inputElement;
                return input;
            }
            return new Object[0];
        }

        public void dispose() {
        }

        @Override
        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }
    }

    /**
     * The content provider used for the PreprocessorTags table within the UI
     *
     *
     */
    class PreprocessorTagCheckStateProvider implements ICheckStateProvider {

        @Override
        public boolean isChecked(Object element) {
            boolean result = false;
            if (element instanceof PreprocessorTag) {
                result = ((PreprocessorTag) element).isActive().booleanValue();
            }
            return result;
        }

        @Override
        public boolean isGrayed(Object element) {
            return false;
        }

    }

    class ScopeComparator implements Comparator<PreprocessorTag> {

        @Override
        public int compare(PreprocessorTag o1, PreprocessorTag o2) {
            if (o1.getScopeID() > o2.getScopeID()) {
                return -1;
            } else if (o1.getScopeID() < o2.getScopeID()) {
                return 1;
            } else {
                return o1.getPreprocessorDefine().compareToIgnoreCase(o2.getPreprocessorDefine());
            }
        }

    }

    class DirectiveString implements Comparator<PreprocessorTag> {

        @Override
        public int compare(PreprocessorTag o1, PreprocessorTag o2) {
            return o1.getPreprocessorDefine().compareToIgnoreCase(o2.getPreprocessorDefine());
        }

    }

    @Override
    public void defaultVMInstallChanged(IVMInstall previous, IVMInstall current) {
        showData();
    }

    @Override
    public void vmAdded(IVMInstall vm) {
        showData();
    }

    @Override
    public void vmChanged(org.eclipse.jdt.launching.PropertyChangeEvent event) {
        showData();

    }

    @Override
    public void vmRemoved(IVMInstall vm) {
        showData();
    }
}