| /** |
| * |
| * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * |
| * 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: |
| * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation |
| */ |
| package org.eclipse.osbp.preferences.ui.component; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Set; |
| import java.util.StringTokenizer; |
| import java.util.TreeSet; |
| |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.preference.FieldEditor; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.CLabel; |
| import org.eclipse.swt.events.DisposeEvent; |
| import org.eclipse.swt.events.DisposeListener; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| 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.Label; |
| import org.eclipse.swt.widgets.List; |
| |
| /** |
| * 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 AddRemoveListFieldEditor extends FieldEditor { |
| private static final String TO_LEFT_SIGN = "<"; //"\u0171"; |
| private static final String TO_RIGHT_SIGN = ">"; //"\u0187"; |
| |
| private static final String DEFAULT_SELECT_LABEL = TO_LEFT_SIGN+" select "+TO_LEFT_SIGN; |
| private static final String DEFAULT_DESELECT_LABEL = TO_RIGHT_SIGN+" deselect "+TO_RIGHT_SIGN; |
| private static final String DEFAULT_SEPERATOR = ";"; |
| |
| private static final int VERTICAL_DIALOG_UNITS_PER_CHAR = 8; |
| private static final int HORIZONTAL_DIALOG_UNITS_PER_CHAR = 4; |
| private static final int LIST_HEIGHT_IN_CHARS = 10; |
| private static final int LIST_HEIGHT_IN_DLUS = LIST_HEIGHT_IN_CHARS * VERTICAL_DIALOG_UNITS_PER_CHAR; |
| |
| // The top-level control for the field editor. |
| private Composite top; |
| // The list of selected tags. |
| private List selectedList; |
| // The list with available and not selected tags. |
| private List availableList; |
| // The button for adding the contents of |
| // the available list to the selected list. |
| private Button select; |
| // The button for removing the currently-selected list item. |
| private Button deselect; |
| // The string used to seperate list items |
| // in a single String representation. |
| private String seperator = DEFAULT_SEPERATOR; |
| protected CLabel label; |
| |
| private String[][]availableNamesAndValues; |
| |
| public AddRemoveListFieldEditor( |
| String name, |
| String labelText, |
| String[][] availableNamesAndValues, |
| Composite parent) { |
| super(name, labelText, parent); |
| this.availableNamesAndValues = availableNamesAndValues; |
| } |
| |
| public AddRemoveListFieldEditor( |
| String name, |
| String labelText, |
| String[][] availableNamesAndValues, |
| String selectButtonText, |
| String deselectButtonText, |
| Composite parent) { |
| this(name, labelText, availableNamesAndValues, parent); |
| setSelectButtonText(selectButtonText); |
| setDeselectButtonText(deselectButtonText); |
| } |
| |
| public void setAvailableNamesAndValues(String[][] availableNamesAndValues) { |
| this.availableNamesAndValues = availableNamesAndValues; |
| refreshAvailableList(); |
| } |
| |
| /** |
| * @see org.eclipse.jface.preference.FieldEditor#adjustForNumColumns(int) |
| */ |
| protected void adjustForNumColumns(int numColumns) { |
| ((GridData)top.getLayoutData()).horizontalSpan = numColumns; |
| } |
| |
| /** |
| * @see org.eclipse.jface.preference.FieldEditor#doFillIntoGrid |
| * (Composite, int) |
| */ |
| protected void doFillIntoGrid(Composite parent, int numColumns) { |
| top = parent; |
| |
| int buttonWidth = convertHorizontalDLUsToPixels(top, IDialogConstants.BUTTON_WIDTH); |
| int buttonHeight = convertVerticalDLUsToPixels(top, IDialogConstants.BUTTON_HEIGHT); |
| |
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); |
| gd.horizontalSpan = numColumns; |
| top.setLayoutData(gd); |
| |
| getLabelControl(top); |
| GridData labelData = new GridData(); |
| labelData.horizontalSpan = numColumns; |
| label.setLayoutData(labelData); |
| |
| Composite components = new Composite(top, SWT.NONE); |
| |
| GridData componentsData = new GridData(); |
| componentsData.horizontalSpan = numColumns; |
| componentsData.heightHint = buttonHeight * 10+10; |
| components.setLayoutData(componentsData); |
| //components.setBackground(new org.eclipse.swt.graphics.Color(components.getDisplay(), 255,255,255)); |
| GridLayout componentsLayout = new GridLayout(3, false); |
| components.setLayout(componentsLayout); |
| |
| selectedList = new List(components, SWT.BORDER | SWT.V_SCROLL); |
| GridData selectedData = new GridData(); |
| selectedData.heightHint = buttonHeight * 10; |
| selectedList.setLayoutData(selectedData); |
| //selectedList.setBackground(new org.eclipse.swt.graphics.Color(components.getDisplay(), 255,0,0)); |
| |
| // Create a grid data that takes up the extra |
| // space in the dialog and spans both columns. |
| //*GridData selectedListData = new GridData(GridData.FILL_HORIZONTAL); |
| //*selectedListData.heightHint = convertVerticalDLUsToPixels(selectedList, LIST_HEIGHT_IN_DLUS); |
| //*selectedListData.horizontalSpan = numColumns; |
| |
| //*selectedList.setLayoutData(selectedListData); |
| selectedList.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| selectedSelectionChanged(); |
| } |
| }); |
| |
| // Create a composite for the add and remove |
| // buttons and the input text field. |
| Composite addRemoveGroup = new Composite(components, SWT.NONE); |
| // GridData addRemoveData = new GridData(); |
| // addRemoveData.heightHint = buttonHeight * 10; |
| // addRemoveGroup.setLayoutData(addRemoveData); |
| //addRemoveGroup.setBackground(new org.eclipse.swt.graphics.Color(components.getDisplay(), 0,255,0)); |
| |
| //*GridData addRemoveData = new GridData(GridData.FILL_HORIZONTAL); |
| //*addRemoveData.horizontalSpan = numColumns; |
| //*addRemoveGroup.setLayoutData(addRemoveData); |
| |
| GridLayout addRemoveLayout = new GridLayout(); |
| addRemoveLayout.numColumns = numColumns; |
| addRemoveLayout.marginHeight = 0; |
| addRemoveLayout.marginWidth = 0; |
| addRemoveGroup.setLayout(addRemoveLayout); |
| addRemoveGroup.setSize(buttonWidth, buttonHeight*2); |
| |
| // Create a composite for the add and remove buttons. |
| Composite buttonGroup = new Composite(addRemoveGroup, SWT.NONE); |
| //*buttonGroup.setLayoutData(new GridData()); |
| |
| GridLayout buttonLayout = new GridLayout(); |
| buttonLayout.marginHeight = 0; |
| buttonLayout.marginWidth = 0; |
| buttonGroup.setLayout(buttonLayout); |
| |
| // Create the remove button. |
| deselect = new Button(buttonGroup, SWT.NONE); |
| deselect.setEnabled(false); |
| deselect.setText(DEFAULT_DESELECT_LABEL); |
| deselect.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| deselect(); |
| showDefaultHint(); |
| } |
| }); |
| GridData removeData = new GridData(GridData.FILL_HORIZONTAL); |
| removeData.heightHint = buttonHeight; |
| removeData.widthHint = buttonWidth; |
| deselect.setLayoutData(removeData); |
| |
| // Create the add button. |
| select = new Button(buttonGroup, SWT.NONE); |
| select.setEnabled(false); |
| select.setText(DEFAULT_SELECT_LABEL); |
| select.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| select(); |
| showDefaultHint(); |
| } |
| }); |
| GridData addData = new GridData(GridData.FILL_HORIZONTAL); |
| addData.heightHint = buttonHeight; |
| addData.widthHint = buttonWidth; |
| select.setLayoutData(addData); |
| |
| // available list |
| availableList = new List(components, SWT.BORDER | SWT.V_SCROLL); |
| GridData availableData = new GridData(); |
| availableData.heightHint = buttonHeight * 10; |
| availableList.setLayoutData(availableData); |
| //availableList.setBackground(new org.eclipse.swt.graphics.Color(components.getDisplay(), 0,0,255)); |
| |
| // Create a grid data that takes up the extra |
| // space in the dialog and spans both columns. |
| //*GridData availableListData = new GridData(GridData.FILL_HORIZONTAL); |
| //*availableListData.heightHint = convertVerticalDLUsToPixels(availableList, LIST_HEIGHT_IN_DLUS); |
| //*availableListData.horizontalSpan = numColumns; |
| |
| //*availableList.setLayoutData(availableListData); |
| availableList.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| availableSelectionChanged(); |
| } |
| }); |
| } |
| |
| protected void showDefaultHint() { |
| String defaults = getPreferenceStore().getDefaultString(getPreferenceName()); |
| String selected = createListString(selectedList.getItems()); |
| APreferencePage.showLabelDefaultHint(label, defaults.equals(selected)); |
| } |
| |
| @Override |
| public Label getLabelControl(Composite parent) { |
| if (label == null) { |
| label = new CLabel(parent, SWT.LEFT | SWT.RIGHT_TO_LEFT); |
| label.setFont(parent.getFont()); |
| String text = getLabelText(); |
| if (text != null) { |
| label.setText(text); |
| } |
| label.addDisposeListener(new DisposeListener() { |
| @Override |
| public void widgetDisposed(DisposeEvent event) { |
| label = null; |
| } |
| }); |
| } else { |
| checkParent(label, parent); |
| } |
| return null; |
| } |
| |
| @Override |
| public void setEnabled(boolean enabled, Composite parent) { |
| label.setEnabled(enabled); |
| } |
| |
| /** |
| * @see org.eclipse.jface.preference.FieldEditor#doLoad() |
| */ |
| protected void doLoad() { |
| String items = getPreferenceStore().getString(getPreferenceName()); |
| setList(items); |
| showDefaultHint(); |
| } |
| |
| /** |
| * @see org.eclipse.jface.preference.FieldEditor#doLoadDefault() |
| */ |
| protected void doLoadDefault() { |
| String items = getPreferenceStore().getDefaultString(getPreferenceName()); |
| setList(items); |
| showDefaultHint(); |
| } |
| |
| // Parses the string into seperate list items and adds them to the list. |
| private void setList(String items) { |
| String[] itemArray = parseString(items); |
| selectedList.setItems(itemArray); |
| } |
| |
| /** |
| * @see org.eclipse.jface.preference.FieldEditor#doStore() |
| */ |
| protected void doStore() { |
| String s = createListString(selectedList.getItems()); |
| if (s != null) |
| getPreferenceStore().setValue(getPreferenceName(), s); |
| } |
| |
| /** |
| * @see org.eclipse.jface.preference.FieldEditor#getNumberOfControls() |
| */ |
| public int getNumberOfControls() { |
| // The button composite and the text field. |
| return 2; |
| } |
| |
| // Adds the string in the text field to the list. |
| private void select() { |
| Set<String> items = new TreeSet<String>(); |
| items.addAll(Arrays.asList(selectedList.getItems())); |
| items.addAll(Arrays.asList(availableList.getSelection())); |
| selectedList.removeAll(); |
| for (String addItem : items) { |
| selectedList.add(addItem); |
| } |
| refreshAvailableList(); |
| } |
| |
| private void deselect() { |
| Set<String> items = new TreeSet<String>(); |
| items.addAll(Arrays.asList(selectedList.getItems())); |
| items.removeAll(Arrays.asList(selectedList.getSelection())); |
| selectedList.removeAll(); |
| for (String addItem : items) { |
| selectedList.add(addItem); |
| } |
| refreshAvailableList(); |
| } |
| |
| private void refreshAvailableList() { |
| java.util.List<String> ignoreItems = Arrays.asList(selectedList.getItems()); |
| availableList.removeAll(); |
| for (int idx = 0; idx < availableNamesAndValues.length; idx++) { |
| String addItem = availableNamesAndValues[idx][1]; |
| if ((addItem != null) && !ignoreItems.contains(addItem)) { |
| availableList.add(addItem); |
| } |
| } |
| selectedList.deselectAll(); |
| availableList.deselectAll(); |
| select.setEnabled(false); |
| deselect.setEnabled(false); |
| } |
| |
| /** |
| * Sets the label for the button that adds |
| * the contents of the text field to the list. |
| */ |
| public void setSelectButtonText(String text) { |
| select.setText(text); |
| } |
| |
| /** |
| * Sets the label for the button that removes |
| * the selected item from the list. |
| */ |
| public void setDeselectButtonText(String text) { |
| deselect.setText(text); |
| } |
| |
| /** |
| * Sets the string that seperates items in the list when the |
| * list is stored as a single String in the preference store. |
| */ |
| public void setSeperator(String seperator) { |
| this.seperator = seperator; |
| } |
| |
| /** |
| * Creates the single String representation of the list |
| * that is stored in the preference store. |
| */ |
| private String createListString(String[] items) { |
| StringBuffer path = new StringBuffer("");//$NON-NLS-1$ |
| for (int i = 0; i < items.length; i++) { |
| if (i > 0) { |
| path.append(seperator); |
| } |
| path.append(items[i]); |
| } |
| return path.toString(); |
| } |
| |
| /** |
| * Parses the single String representation of the list |
| * into an array of list items. |
| */ |
| private String[] parseString(String stringList) { |
| StringTokenizer st = |
| new StringTokenizer(stringList, seperator); //$NON-NLS-1$ |
| ArrayList v = new ArrayList(); |
| while (st.hasMoreElements()) { |
| v.add(st.nextElement()); |
| } |
| return (String[])v.toArray(new String[v.size()]); |
| } |
| |
| // Sets the enablement of the remove button depending |
| // on the selection in the list. |
| private void selectedSelectionChanged() { |
| int index = selectedList.getSelectionIndex(); |
| deselect.setEnabled(index >= 0); |
| availableList.deselectAll(); |
| select.setEnabled(false); |
| } |
| |
| // Sets the enablement of the remove button depending |
| // on the selection in the list. |
| private void availableSelectionChanged() { |
| int index = availableList.getSelectionIndex(); |
| select.setEnabled(index >= 0); |
| selectedList.deselectAll(); |
| deselect.setEnabled(false); |
| } |
| } |