org.rubypeople.rdt.internal.debug.ui.preferences.EvaluationExpressionsPreferencePage.java Source code

Java tutorial

Introduction

Here is the source code for org.rubypeople.rdt.internal.debug.ui.preferences.EvaluationExpressionsPreferencePage.java

Source

/*
 * Author: Markus Barchfeld
 * 
 * Copyright (c) 2005 RubyPeople.
 * 
 * This file is part of the Ruby Development Tools (RDT) plugin for eclipse. RDT is
 * subject to the "Common Public License (CPL) v 1.0". You may not use RDT except in 
 * compliance with the License. For further information see org.rubypeople.rdt/rdt.license.
 * This file is based on org.eclipse.ui.texteditor.templates.TemplatePreferencePage
 * 
 */

/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.rubypeople.rdt.internal.debug.ui.preferences;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
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.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.rubypeople.rdt.debug.ui.RdtDebugUiConstants;
import org.rubypeople.rdt.internal.debug.ui.RdtDebugUiMessages;
import org.rubypeople.rdt.internal.debug.ui.RdtDebugUiPlugin;
import org.rubypeople.rdt.internal.debug.ui.evaluation.EvaluationExpression;
import org.rubypeople.rdt.internal.debug.ui.evaluation.EvaluationExpressionReaderWriter;
import org.rubypeople.rdt.internal.ui.util.SWTUtil;

public class EvaluationExpressionsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {

    /**
     * Label provider for templates.
     */
    private class EvaluationExpressionLabelProvider extends LabelProvider implements ITableLabelProvider {

        /*
         * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
         *      int)
         */
        public Image getColumnImage(Object element, int columnIndex) {
            return null;
        }

        /*
         * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object,
         *      int)
         */
        public String getColumnText(Object element, int columnIndex) {
            EvaluationExpression exp = (EvaluationExpression) element;

            switch (columnIndex) {
            case 0:
                return exp.getName();
            case 1:
                return exp.getDescription();
            default:
                return ""; //$NON-NLS-1$
            }
        }
    }

    private class EvaluationExpressionContentProvider implements IStructuredContentProvider {

        private EditableExpressionModel model;

        /*
         * @see IStructuredContentProvider#getElements(Object)
         */
        public Object[] getElements(Object input) {
            return model.getExpressionsAsArray();
        }

        /*
         * @see IContentProvider#inputChanged(Viewer, Object, Object)
         */
        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            model = (EditableExpressionModel) newInput;
        }

        /*
         * @see IContentProvider#dispose()
         */
        public void dispose() {
            model = null;
        }

    }

    private class EditableExpressionModel {

        private ArrayList expressions;

        public EditableExpressionModel() {
            this.load();
        }

        public Collection getExpressions() {
            return expressions;
        }

        public Object[] getExpressionsAsArray() {
            return expressions.toArray(new EvaluationExpression[expressions.size()]);
        }

        public void addExpression(EvaluationExpression expr) {
            this.expressions.add(expr);
        }

        public void replaceExpression(EvaluationExpression old, EvaluationExpression updated) {
            int index = this.expressions.indexOf(old);
            if (index >= 0) {
                this.expressions.set(index, updated);
            }
        }

        public void removeExpression(EvaluationExpression expr) {
            this.expressions.remove(expr);
        }

        public void save() {
            StringWriter xmlWriter = new StringWriter();
            try {
                new EvaluationExpressionReaderWriter().save((EvaluationExpression[]) this.getExpressionsAsArray(),
                        xmlWriter);
                RdtDebugUiPlugin.getDefault().getPluginPreferences()
                        .setValue(RdtDebugUiConstants.EVALUATION_EXPRESSIONS_PREFERENCE, xmlWriter.toString());
            } catch (IOException e) {
                RdtDebugUiPlugin.log(e);
            }
        }

        public void load() {
            EvaluationExpression[] exprs = RdtDebugUiPlugin.getDefault().getEvaluationExpressionModel()
                    .getEvaluationExpressions();
            expressions = new ArrayList(exprs.length);
            for (int i = 0; i < exprs.length; i++) {
                EvaluationExpression expression = exprs[i];
                expressions.add(expression);
            }
        }

        public void importExpressions(InputStream in) throws IOException, FileNotFoundException {
            EvaluationExpression[] importedExprs = new EvaluationExpressionReaderWriter().read(in, null);
            for (int i = 0; i < importedExprs.length; i++) {
                expressions.add(importedExprs[i]);
            }
        }

        public void exportExpressions(EvaluationExpression[] expressions, OutputStream out) throws IOException {
            new EvaluationExpressionReaderWriter().save(expressions, out);
        }

    }

    private CheckboxTableViewer fTableViewer;

    /* buttons */
    private Button fAddButton;
    private Button fEditButton;
    private Button fImportButton;
    private Button fExportButton;
    private Button fRemoveButton;
    private EditableExpressionModel fModel;

    /**
     * Creates a new template preference page.
     */
    public EvaluationExpressionsPreferencePage() {
        super();
        fModel = new EditableExpressionModel();
        setDescription(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_description);
    }

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

    /*
     * @see PreferencePage#createContents(Composite)
     */
    protected Control createContents(Composite ancestor) {
        Composite parent = new Composite(ancestor, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        parent.setLayout(layout);

        Composite innerParent = new Composite(parent, SWT.NONE);
        GridLayout innerLayout = new GridLayout();
        innerLayout.numColumns = 2;
        innerLayout.marginHeight = 0;
        innerLayout.marginWidth = 0;
        innerParent.setLayout(innerLayout);
        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.horizontalSpan = 2;
        innerParent.setLayoutData(gd);

        Table table = new Table(innerParent, SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);

        GridData data = new GridData(GridData.FILL_BOTH);
        data.widthHint = convertWidthInCharsToPixels(3);
        data.heightHint = convertHeightInCharsToPixels(10);
        table.setLayoutData(data);

        table.setHeaderVisible(true);
        table.setLinesVisible(true);

        TableLayout tableLayout = new TableLayout();
        table.setLayout(tableLayout);

        TableColumn column1 = new TableColumn(table, SWT.NONE);
        column1.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_column_name);

        TableColumn column2 = new TableColumn(table, SWT.NONE);
        column2.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_column_description);

        fTableViewer = new CheckboxTableViewer(table);
        fTableViewer.setLabelProvider(new EvaluationExpressionLabelProvider());
        fTableViewer.setContentProvider(new EvaluationExpressionContentProvider());

        fTableViewer.addDoubleClickListener(new IDoubleClickListener() {

            public void doubleClick(DoubleClickEvent e) {
                edit();
            }
        });

        fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {

            public void selectionChanged(SelectionChangedEvent e) {
                selectionChanged1();
            }
        });

        fTableViewer.addCheckStateListener(new ICheckStateListener() {

            public void checkStateChanged(CheckStateChangedEvent event) {
                ((EvaluationExpression) event.getElement()).setEnabled(event.getChecked());
            }
        });

        Composite buttons = new Composite(innerParent, SWT.NONE);
        buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
        layout = new GridLayout();
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        buttons.setLayout(layout);

        fAddButton = new Button(buttons, SWT.PUSH);
        fAddButton.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_new);
        fAddButton.setLayoutData(getButtonGridData(fAddButton));
        fAddButton.addListener(SWT.Selection, new Listener() {

            public void handleEvent(Event e) {
                add();
            }
        });

        fEditButton = new Button(buttons, SWT.PUSH);
        fEditButton.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_edit);
        fEditButton.setLayoutData(getButtonGridData(fEditButton));
        fEditButton.addListener(SWT.Selection, new Listener() {

            public void handleEvent(Event e) {
                edit();
            }
        });

        fRemoveButton = new Button(buttons, SWT.PUSH);
        fRemoveButton.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_remove);
        fRemoveButton.setLayoutData(getButtonGridData(fRemoveButton));
        fRemoveButton.addListener(SWT.Selection, new Listener() {

            public void handleEvent(Event e) {
                remove();
            }
        });

        createSeparator(buttons);

        fImportButton = new Button(buttons, SWT.PUSH);
        fImportButton.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_import);
        fImportButton.setLayoutData(getButtonGridData(fImportButton));
        fImportButton.addListener(SWT.Selection, new Listener() {

            public void handleEvent(Event e) {
                importFile();
            }
        });

        fExportButton = new Button(buttons, SWT.PUSH);
        fExportButton.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export);
        fExportButton.setLayoutData(getButtonGridData(fExportButton));
        fExportButton.addListener(SWT.Selection, new Listener() {

            public void handleEvent(Event e) {
                exportFile();
            }
        });

        fTableViewer.setInput(fModel);
        setEnabledExpresions(fTableViewer);
        updateButtons();
        configureTableResizing(innerParent, buttons, table, column1, column2);

        Dialog.applyDialogFont(parent);
        return parent;
    }

    /**
     * Sets the list checkboxes to proper state
     *
     * @param viewer checkbox viewer
     */
    private void setEnabledExpresions(CheckboxTableViewer viewer) {
        for (Object o : fModel.getExpressionsAsArray()) {
            EvaluationExpression expr = (EvaluationExpression) o;
            viewer.setChecked(o, expr.isEnabled());
        }
    }

    /**
     * Creates a separator between buttons
     * 
     * @param parent
     * @return
     */
    private Label createSeparator(Composite parent) {
        Label separator = new Label(parent, SWT.NONE);
        separator.setVisible(false);
        GridData gd = new GridData();
        gd.horizontalAlignment = GridData.FILL;
        gd.verticalAlignment = GridData.BEGINNING;
        gd.heightHint = 4;
        separator.setLayoutData(gd);
        return separator;
    }

    /**
     * Correctly resizes the table so no phantom columns appear
     */
    private static void configureTableResizing(final Composite parent, final Composite buttons, final Table table,
            final TableColumn column1, final TableColumn column2) {
        parent.addControlListener(new ControlAdapter() {

            public void controlResized(ControlEvent e) {
                Rectangle area = parent.getClientArea();
                Point preferredSize = table.computeSize(SWT.DEFAULT, SWT.DEFAULT);
                int width = area.width - 2 * table.getBorderWidth();
                if (preferredSize.y > area.height) {
                    // Subtract the scrollbar width from the total column width
                    // if a vertical scrollbar will be required
                    Point vBarSize = table.getVerticalBar().getSize();
                    width -= vBarSize.x;
                }
                width -= buttons.getSize().x;
                Point oldSize = table.getSize();
                if (oldSize.x > width) {
                    // table is getting smaller so make the columns
                    // smaller first and then resize the table to
                    // match the client area width
                    column1.setWidth(width / 3);
                    column2.setWidth(width - column1.getWidth());
                    //column3.setWidth(width - (column1.getWidth() +
                    // column2.getWidth()));
                    table.setSize(width, area.height);
                } else {
                    // table is getting bigger so make the table
                    // bigger first and then make the columns wider
                    // to match the client area width
                    table.setSize(width, area.height);
                    column1.setWidth(width / 3);
                    column2.setWidth(width - column1.getWidth());
                    //column3.setWidth(width - (column1.getWidth() +
                    // column2.getWidth()));
                }
            }
        });
    }

    private static GridData getButtonGridData(Button button) {
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        data.widthHint = SWTUtil.getButtonWidthHint(button);
        data.heightHint = SWTUtil.getButtonHeightHint(button);
        return data;
    }

    private void selectionChanged1() {
        updateButtons();
    }

    /**
     * Updates the buttons.
     */
    protected void updateButtons() {
        IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection();
        int selectionCount = selection.size();
        int itemCount = fTableViewer.getTable().getItemCount();
        fEditButton.setEnabled(selectionCount == 1);
        fExportButton.setEnabled(selectionCount > 0);
        fRemoveButton.setEnabled(selectionCount > 0 && selectionCount <= itemCount);
    }

    private void add() {

        EvaluationExpression evalExpression = new EvaluationExpression("", "", "", false);
        String title = RdtDebugUiMessages.EditEvaluationExpressionDialog_add;
        Dialog dialog = new EditEvaluationExpressionDialog(getShell(), title, evalExpression);
        if (dialog.open() == Window.OK) {
            fModel.addExpression(evalExpression);
            fTableViewer.refresh();
            fTableViewer.setSelection(new StructuredSelection(evalExpression));
        }
    }

    private void edit() {
        IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection();

        Object[] objects = selection.toArray();
        if ((objects == null) || (objects.length != 1))
            return;

        EvaluationExpression data = (EvaluationExpression) selection.getFirstElement();
        edit(data);
    }

    private void edit(EvaluationExpression evalExpression) {
        String title = RdtDebugUiMessages.EditEvaluationExpressionDialog_edit;
        Dialog dialog = new EditEvaluationExpressionDialog(getShell(), title, evalExpression);
        if (dialog.open() == Window.OK) {
            fTableViewer.refresh();
        }
    }

    private void importFile() {
        FileDialog dialog = new FileDialog(getShell());
        dialog.setText(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_import_title);
        dialog.setFilterExtensions(
                new String[] { RdtDebugUiMessages.EvaluationExpressionsPreferencePage_importexport_extension });
        String path = dialog.open();

        if (path == null)
            return;

        TemplateReaderWriter reader = new TemplateReaderWriter();
        File file = new File(path);
        if (file.exists()) {
            try {
                InputStream input = new BufferedInputStream(new FileInputStream(file));
                fModel.importExpressions(input);
            } catch (Exception e) {
                RdtDebugUiPlugin.log(e);
            }
        }

        fTableViewer.refresh();

    }

    private void exportFile() {
        IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection();
        Object[] expressions = selection.toArray();

        EvaluationExpression[] datas = new EvaluationExpression[expressions.length];
        for (int i = 0; i != expressions.length; i++)
            datas[i] = (EvaluationExpression) expressions[i];

        export(datas);
    }

    private void export(EvaluationExpression[] expressions) {
        FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
        dialog.setText(RdtDebugUiMessages.getFormattedString(
                RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_title,
                new Integer(expressions.length)));
        dialog.setFilterExtensions(
                new String[] { RdtDebugUiMessages.EvaluationExpressionsPreferencePage_importexport_extension });
        dialog.setFileName(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_filename);
        String path = dialog.open();

        if (path == null)
            return;

        File file = new File(path);

        if (file.isHidden()) {
            String title = RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_error_title;
            String message = RdtDebugUiMessages.getFormattedString(
                    RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_error_hidden,
                    file.getAbsolutePath());
            MessageDialog.openError(getShell(), title, message);
            return;
        }

        if (file.exists() && !file.canWrite()) {
            String title = RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_error_title;
            String message = RdtDebugUiMessages.getFormattedString(
                    RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_error_canNotWrite,
                    file.getAbsolutePath());
            MessageDialog.openError(getShell(), title, message);
            return;
        }

        if (!file.exists() || confirmOverwrite(file)) {
            try {
                OutputStream output = new BufferedOutputStream(new FileOutputStream(file));
                fModel.exportExpressions(expressions, output);
            } catch (Exception e) {
                //openWriteErrorDialog(e);
            }
        }
    }

    private boolean confirmOverwrite(File file) {
        return MessageDialog.openQuestion(getShell(),
                RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_exists_title,
                RdtDebugUiMessages.getFormattedString(
                        RdtDebugUiMessages.EvaluationExpressionsPreferencePage_export_exists_message,
                        file.getAbsolutePath()));
    }

    private void remove() {
        IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection();

        Iterator elements = selection.iterator();
        while (elements.hasNext()) {
            fModel.removeExpression((EvaluationExpression) elements.next());
        }
        fTableViewer.refresh();
    }

    public void setVisible(boolean visible) {
        super.setVisible(visible);
        if (visible)
            setTitle(RdtDebugUiMessages.EvaluationExpressionsPreferencePage_title);
    }

    /*
     * @see PreferencePage#performDefaults()
     */
    protected void performDefaults() {
        RdtDebugUiPlugin.getDefault().getPluginPreferences()
                .setToDefault(RdtDebugUiConstants.EVALUATION_EXPRESSIONS_PREFERENCE);
        fModel.load();
        fTableViewer.refresh();
    }

    /*
     * @see PreferencePage#performOk()
     */
    public boolean performOk() {

        fModel.save();
        return super.performOk();
    }

    /*
     * @see PreferencePage#performCancel()
     */
    public boolean performCancel() {

        fModel.load();
        return super.performCancel();
    }

    protected CheckboxTableViewer getTableViewer() {
        return fTableViewer;
    }
}