net.sourceforge.texlipse.properties.ViewerListFieldEditor.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.texlipse.properties.ViewerListFieldEditor.java

Source

/*
 * $Id$
 *
 * Copyright (c) 2004-2005 by the TeXlapse Team.
 * 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 net.sourceforge.texlipse.properties;

import java.util.ArrayList;
import java.util.Arrays;

import net.sourceforge.texlipse.TexlipsePlugin;
import net.sourceforge.texlipse.viewer.ViewerAttributeRegistry;
import net.sourceforge.texlipse.viewer.ViewerConfigDialog;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.preference.ListEditor;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.List;

/**
 * A FieldEditor that holds a list of strings as its value.
 * 
 * The list of strings is converted into a single String object by 
 * putting a separator character between the items while concatenating.
 * 
 * @author Kimmo Karlsson
 * @author Tor Arne Vestb
 */
public class ViewerListFieldEditor extends ListEditor {

    // separator character for strings
    public static final String SEPARATOR = ",";

    // registry for the configs
    private ViewerAttributeRegistry registry;

    // cache for name list
    private ArrayList nameList;

    // button to launch the config editor
    private Button editButton;

    // parent component for accessing default components 
    private Composite parent;

    /**
     * Creates a new string list field editor.
     * 
     * @param labelText text for description label
     * @param parent parent component
     */
    public ViewerListFieldEditor(String labelText, Composite parent) {
        super(ViewerAttributeRegistry.VIEWER_NAMES + ".TEMP", labelText, parent);
        nameList = new ArrayList();
        registry = new ViewerAttributeRegistry();
    }

    /**
     * Load the values from preferences.
     * @see super.doLoad()
     */
    protected void doLoad() {
        super.doLoad();
        registry.load(getPreferenceStore());
        List list = getListControl(parent);
        list.setItems(addPaths(TexlipsePlugin.getPreferenceArray(ViewerAttributeRegistry.VIEWER_NAMES)));
    }

    /**
     * Load the default values from preferences.
     * @see super.doLoadDefault()
     */
    protected void doLoadDefault() {
        super.doLoadDefault();
        registry = new ViewerAttributeRegistry();
        List list = getListControl(parent);
        list.setItems(addPaths(TexlipsePlugin.getPreferenceArray(ViewerAttributeRegistry.VIEWER_NAMES)));
    }

    /**
     * Adds path information to the list of viewer names.
     * @param items viewer names
     * @return an array of viewer names with viewer path information added
     */
    private String[] addPaths(String[] items) {
        String oldViewer = registry.getActiveViewer();
        String[] array = new String[items.length];
        for (int i = 0; i < items.length; i++) {
            registry.setActiveViewer(items[i]);
            array[i] = items[i] + " (" + registry.getCommand() + ")";
        }
        registry.setActiveViewer(oldViewer);
        return array;
    }

    /**
     * Store the values to preferences.
     * @see super.doStore()
     */
    protected void doStore() {
        super.doStore();
        List list = getListControl(parent);
        String[] trueNames = removePaths(list.getItems());
        registry.setActiveViewer(trueNames[0]);
        registry.save(getPreferenceStore(), trueNames);
    }

    /**
     * Strips path information from the list of viewer names.
     * @param items the items from the list component
     * @return the given array of items, with path information left out
     */
    private String[] removePaths(String[] items) {
        String[] array = new String[items.length];
        for (int i = 0; i < items.length; i++) {
            array[i] = items[i].substring(0, items[i].indexOf('(') - 1);
        }
        return array;
    }

    /**
     * Creates a new editor button for the field editor.
     * @param parent parent component
     * @return the "edit"-button
     */
    protected Button createEditButton(Composite parent) {

        Button button = new Button(parent, SWT.PUSH);
        button.setText(TexlipsePlugin.getResourceString("openEdit"));
        button.setFont(parent.getFont());
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        data.heightHint = convertVerticalDLUsToPixels(button, IDialogConstants.BUTTON_HEIGHT);
        int widthHint = convertHorizontalDLUsToPixels(button, IDialogConstants.BUTTON_WIDTH);
        data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
        button.setLayoutData(data);
        button.setEnabled(false);
        button.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                openEditorDialog();
            }
        });

        return button;
    }

    /**
     * Open the config editor dialog for editing an existing configuration.
     * This is called, when edit button is pressed.
     */
    private void openEditorDialog() {

        List list = getListControl(parent);
        int index = list.getSelectionIndex();
        if (index < 0) {
            // no item selected from the list, do nothing
            return;
        }

        String name = list.getItem(index);
        if (name == null || name.length() == 0) {
            // no name for the item, can't load config
            return;
        }

        registry.setActiveViewer(name.substring(0, name.indexOf('(') - 1));
        ViewerConfigDialog dialog = new ViewerConfigDialog(editButton.getShell(),
                (ViewerAttributeRegistry) registry.clone());

        int code = dialog.open();
        if (code == Window.OK) {
            registry.mergeWith(dialog.getRegistry());
            list.setItem(index, registry.getActiveViewer() + " (" + registry.getCommand() + ")");
        }
    }

    /**
     * Insert a button to the button box.
     * This method calls super and creates a the "edit"-button to the list.
     */
    public Composite getButtonBoxControl(Composite parent) {
        Composite box = super.getButtonBoxControl(parent);
        if (editButton == null) {
            this.parent = parent;
            editButton = createEditButton(box);
        }
        return box;
    }

    /**
     * Add an additional SelectionListener to the list component.
     * This method call super and installs a SelectionListener,
     * which enables and disables the "edit"-button.
     */
    public List getListControl(Composite parent) {
        List list = super.getListControl(parent);
        list.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                List listWidget = (List) event.widget;
                editButton.setEnabled(listWidget.getSelectionIndex() >= 0);
            }
        });
        return list;
    }

    /**
     * Combines the given list of items into a single string.
     * @param items list of items
     * @return a single string
     */
    protected String createList(String[] items) {

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < items.length - 1; i++) {
            sb.append(items[i]);
            sb.append(SEPARATOR);
        }
        sb.append(items[items.length - 1]);

        nameList.clear();
        nameList.addAll(Arrays.asList(items));

        return sb.toString();
    }

    /**
     * Creates and returns a new item for the list.
     * This implementation opens a question dialog, where user can
     * enter a new item.
     * 
     * @return the string the user wanted to add, or null
     *         if the cancel button was pressed or the string was an empty one
     */
    protected String getNewInputObject() {

        ViewerConfigDialog dialog = new ViewerConfigDialog(this.getLabelControl().getShell(), nameList);

        int code = dialog.open();
        if (code == Window.OK) {

            ViewerAttributeRegistry reg = dialog.getRegistry();
            String name = reg.getActiveViewer();
            nameList.add(name);

            registry.mergeWith(reg);

            return name + " (" + reg.getCommand() + ")";

        }
        return null;
    }

    /**
     * Parse the given string into a list of items.
     * @return a list of items parsed from the given string 
     */
    protected String[] parseString(String stringList) {
        String[] arr = stringList.split(SEPARATOR);
        nameList.clear();
        nameList.addAll(Arrays.asList(arr));
        return arr;
    }
}