org.axdt.asdoc.ui.preferences.DocTableFieldEditor.java Source code

Java tutorial

Introduction

Here is the source code for org.axdt.asdoc.ui.preferences.DocTableFieldEditor.java

Source

/*******************************************************************************
 * Copyright (c) 2010 Martin Schnabel <mb0@mb0.org>.
 * 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
 ******************************************************************************/
package org.axdt.asdoc.ui.preferences;

import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

import org.axdt.asdoc.ui.AsdocUiActivator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;

import com.google.common.collect.Lists;

public class DocTableFieldEditor extends FieldEditor {

    private Composite baseComp;
    private TableViewer tableViewer;

    public DocTableFieldEditor(String name, String labelText, Composite comp) {
        super(name, labelText, comp);
    }

    @Override
    protected void adjustForNumColumns(int numColumns) {
        GridData layoutData = (GridData) baseComp.getLayoutData();
        layoutData.horizontalSpan = numColumns;
    }

    protected Composite createBaseComposite(Composite parent, int numColumns) {
        Composite result = new Composite(parent, SWT.NONE);
        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.horizontalSpan = numColumns;
        result.setLayoutData(gd);
        result.setLayout(new GridLayout(1, false));
        return result;
    }

    protected Label createLabel(Composite parent) {
        Label labelControl = getLabelControl(parent);
        labelControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        return labelControl;
    }

    protected SashForm createSashForm(Composite parent) {
        final SashForm splitComp = new SashForm(parent, SWT.NONE);
        splitComp.setLayoutData(new GridData(GridData.FILL_BOTH));
        splitComp.addControlListener(new ControlAdapter() {
            @Override
            public void controlResized(ControlEvent e) {
                int width = splitComp.getBounds().width;
                double percent = (width - 100.0) / width;
                int weight = (int) Math.round(percent * 100);
                splitComp.setWeights(new int[] { weight, 100 - weight });
            }
        });
        return splitComp;
    }

    protected TableViewer createTableViewer(Composite parent) {
        Composite tableComp = new Composite(parent, SWT.NONE);
        tableComp.setLayout(new TableColumnLayout());

        TableViewer tableViewer = new TableViewer(tableComp, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION);
        tableViewer.setContentProvider(new ArrayContentProvider());
        tableViewer.getTable().setHeaderVisible(true);
        tableViewer.getTable().setLinesVisible(true);

        createTableViwerColumn(tableViewer, "Name", new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                if (element instanceof DocItem) {
                    DocItem item = (DocItem) element;
                    return item.name;
                }
                return super.getText(element);
            }
        }, new ColumnWeightData(1, 50, true));

        createTableViwerColumn(tableViewer, "Url", new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                if (element instanceof DocItem) {
                    DocItem item = (DocItem) element;
                    return item.url;
                }
                return super.getText(element);
            }
        }, new ColumnWeightData(5, 250, true));
        return tableViewer;
    }

    private void createTableViwerColumn(TableViewer tableViewer2, String string, CellLabelProvider labelProvider,
            ColumnLayoutData layoutData) {
        TableViewerColumn viewerNameColumn = new TableViewerColumn(tableViewer2, SWT.NONE);
        viewerNameColumn.getColumn().setText(string);
        viewerNameColumn.setLabelProvider(labelProvider);
        Layout layout = tableViewer2.getControl().getParent().getLayout();
        if (layout instanceof TableColumnLayout) {
            ((TableColumnLayout) layout).setColumnData(viewerNameColumn.getColumn(), layoutData);
        }
    }

    protected Button createButton(Composite parent, String label, SelectionListener listener) {
        Button button = new Button(parent, SWT.PUSH);
        button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        button.setText(label);
        button.addSelectionListener(listener);
        return button;
    }

    protected Composite createButtons(Composite parent) {
        Composite buttonsComp = new Composite(parent, SWT.NONE);
        buttonsComp.setLayout(new GridLayout(1, true));

        createButton(buttonsComp, "Add", new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                DocItem item = new DocItem("New", "");
                boolean doAdd = doEdit(item);
                if (doAdd) {
                    Object[] input = (Object[]) tableViewer.getInput();
                    List<Object> list = new ArrayList<Object>();
                    list.addAll(Arrays.asList(input));
                    list.add(item);
                    tableViewer.setInput(list.toArray());
                }
            }
        });
        createButton(buttonsComp, "Remove", new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
                Object firstElement = selection.getFirstElement();
                Object[] input = (Object[]) tableViewer.getInput();
                List<Object> list = new ArrayList<Object>();
                list.addAll(Arrays.asList(input));
                list.remove(firstElement);
                tableViewer.setInput(list.toArray());
            }
        });
        createButton(buttonsComp, "Edit", new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                IStructuredSelection selection = (IStructuredSelection) tableViewer.getSelection();
                Object firstElement = selection.getFirstElement();
                if (firstElement instanceof DocItem) {
                    doEdit((DocItem) firstElement);
                    tableViewer.refresh();
                }
            }
        });
        return buttonsComp;
    }

    protected boolean doEdit(DocItem item) {
        EditDialog dialog = new EditDialog(tableViewer.getControl().getShell(), item.name, item.url);
        if (dialog.open() == Window.OK) {
            IStatus status = dialog.getStatus();
            if (status.getCode() == IStatus.OK) {
                item.name = dialog.getNameText();
                item.url = dialog.getUrlText();
                return true;
            }
        }
        return false;
    }

    @Override
    protected void doFillIntoGrid(Composite parent, int numColumns) {
        baseComp = createBaseComposite(parent, numColumns);
        createLabel(baseComp);
        SashForm sashForm = createSashForm(baseComp);
        tableViewer = createTableViewer(sashForm);
        createButtons(sashForm);
    }

    @Override
    protected void doLoad() {
        if (tableViewer != null) {
            String value = getPreferenceStore().getString(getPreferenceName());
            Object[] objects = deserializeValue(value);
            tableViewer.setInput(objects);
        }
    }

    @Override
    protected void doLoadDefault() {
        if (tableViewer != null) {
            String value = getPreferenceStore().getDefaultString(getPreferenceName());
            Object[] objects = deserializeValue(value);
            tableViewer.setInput(objects);
        }
    }

    protected static Object[] deserializeValue(String value) {
        List<DocItem> list = deserializeList(value);
        return list.toArray();
    }

    protected static List<DocItem> deserializeList(String value) {
        List<DocItem> list = Lists.newArrayList();
        if (value == null)
            return list;
        value = value.trim();
        if (value.length() == 0)
            return list;
        if (Pattern.matches("('[^']*')([,;]('[^']*'))*", value)) {
            // rows
            for (String part : value.split(";")) {
                // items
                String[] items = part.split(",");
                if (items.length == 0)
                    continue;
                String item = items[0].substring(1, items[0].length() - 1);
                if (items.length == 1) {
                    list.add(new DocItem("New", item));
                } else if (items.length == 2) {
                    String url = items[1].substring(1, items[1].length() - 1);
                    list.add(new DocItem(item, url));
                }
            }
        } else {
            // try to reconstruct from old schema
            for (String part : value.split(" ;,")) {
                list.add(new DocItem("New", part));
            }
        }
        return list;
    }

    protected static String serializeValue(Object[] items) {
        StringBuilder value = new StringBuilder();
        for (Object item : items) {
            if (value.length() != 0)
                value.append(";");
            value.append(item.toString());
        }
        return value.toString();
    }

    @Override
    protected void doStore() {
        Object[] items = (Object[]) tableViewer.getInput();
        getPreferenceStore().setValue(getPreferenceName(), serializeValue(items));
    }

    @Override
    public int getNumberOfControls() {
        return 1;
    }

    public static class DocItem {
        public String url;
        public String name;
        public IStatus status = null;
        public String asdocUrl = null;

        public DocItem(String name, String url) {
            this.name = name;
            this.url = url;
        }

        @Override
        public String toString() {
            StringBuilder builder = new StringBuilder();
            builder.append('\'').append(name).append('\'');
            builder.append(',');
            builder.append('\'').append(url).append('\'');
            return builder.toString();
        }
    }

    public static class EditDialog extends StatusDialog {

        private Text nameText;
        private Text urlText;
        private String name;
        private String url;

        public EditDialog(Shell parent, String initialName, String initialUrl) {
            super(parent);
            this.name = initialName;
            this.url = initialUrl;
        }

        public String getUrlText() {
            return url;
        }

        public String getNameText() {
            return name;
        }

        @Override
        protected Control createDialogArea(Composite ancestor) {
            Composite parent = new Composite(ancestor, SWT.NONE);
            parent.setLayout(new GridLayout(2, false));

            ModifyListener listener = new ModifyListener() {
                public void modifyText(ModifyEvent e) {
                    doTextChanged(e.widget);
                }
            };

            Label description = createLabel(parent, "Please add a name and a valid url to an asdoc folder.");
            GridData gd = new GridData(GridData.FILL_HORIZONTAL);
            gd.horizontalSpan = 2;
            description.setLayoutData(gd);

            createLabel(parent, "Name");
            nameText = createText(parent, name);
            nameText.addModifyListener(listener);

            createLabel(parent, "Url");
            urlText = createText(parent, url);
            urlText.addModifyListener(listener);

            return parent;
        }

        @Override
        public void create() {
            super.create();
            updateStatus(checkValid());
        }

        protected void doTextChanged(Widget widget) {
            updateStatus(checkValid());
        }

        public IStatus checkValid() {
            if (nameText == null || urlText == null)
                return EditDialogStatus.INVALID_STATUS;
            name = nameText.getText().trim();
            url = urlText.getText().trim();
            if (name == null || url == null)
                return EditDialogStatus.INVALID_STATUS;
            if (name.length() == 0)
                return EditDialogStatus.getInvalidStatus("name must be set");
            if (url.length() == 0)
                return EditDialogStatus.getInvalidStatus("url must be set");
            try {
                URI uri = URI.create(url);
                if (!uri.isAbsolute())
                    return EditDialogStatus.getInvalidStatus("url must be absolute");
            } catch (Exception e) {
                return EditDialogStatus.getInvalidStatus("url must be valid");
            }
            return EditDialogStatus.OK_STATUS;
        }

        private Label createLabel(Composite parent, String string) {
            Label label = new Label(parent, SWT.NONE);
            label.setText(string);
            label.setLayoutData(new GridData());
            return label;
        }

        private Text createText(Composite parent, String string) {
            Text text = new Text(parent, SWT.BORDER);
            text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            text.setText(string);
            return text;
        }
    }

    public static class EditDialogStatus extends Status {
        public static final IStatus INVALID_STATUS = getInvalidStatus("Error");

        public EditDialogStatus(int severity, String pluginId, int code, String message, Throwable exception) {
            super(severity, pluginId, code, message, exception);
        }

        public static IStatus getInvalidStatus(String message) {
            return getInvalidStatus(message, null);
        }

        public static IStatus getInvalidStatus(String message, Throwable exception) {
            return new EditDialogStatus(ERROR, AsdocUiActivator.PLUGIN_ID, ERROR, message, exception);
        }
    }
}