/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.ui.attribute.editor; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.*; import org.jboss.tools.common.model.ui.IListEditor; import org.jboss.tools.common.model.ui.IStructuredChangeListener; import org.jboss.tools.common.model.ui.IStructuredEditor; import org.jboss.tools.common.model.ui.IValueProvider; import org.jboss.tools.common.model.ui.StructuredChange; import org.jboss.tools.common.model.ui.StructuredChangedEvent; import org.jboss.tools.common.model.ui.attribute.IListContentProvider; import org.jboss.tools.common.model.ui.attribute.adapter.StructuredListAdapter; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.util.Assert; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.swt.SWT; 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.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.List; import org.eclipse.swt.widgets.Shell; import org.jboss.tools.common.model.ui.widgets.IWidgetSettings; public class ListStructuredFieldEditor extends ExtendedFieldEditor implements IPropertyFieldEditor, IStructuredEditor, IListEditor, IFieldEditor, PropertyChangeListener { // IPropertyEditor protected IPropertyEditor propertyEditor; protected IValueProvider valueProvider; // IStructuredEditor protected IStructuredChangeListener structuredChangeListener; // protected IStructuredContentProvider structuredContentProvider; protected StructuredListAdapter.INewValueProvider newStructuredElementProvider; // IListEditor protected ILabelProvider labelProvider; protected IListContentProvider listContentProvider; // ListStructuredFieldEditor private List list; private Composite buttonBox; private static int ADD = 0, REMOVE = 1, UP = 2, DOWN = 3; private Button[] buttons = new Button[4]; private SelectionListener selectionListener; private Composite mainPanel; private java.util.List<Object> elements; public ListStructuredFieldEditor() {} public ListStructuredFieldEditor(IWidgetSettings settings) { super(settings); } private void doAdd() { setPresentsDefaultValue(false); Object[] input = getNewInputObjects(); for (int i = 0; i < input.length; i++) { String s = this.labelProvider.getText(input[i]); int index = list.getSelectionIndex(); int target = -1; if (index >= 0) { elements.add(index + 1, input[i]); list.add(s, target = index + 1); } else { elements.add(i, input[i]); list.add(s, target = i); } selectionChanged(target); } } protected Object[] getNewInputObjects() { Object value = newStructuredElementProvider.getValue(); Object[] values = (value == null) ? new Object[0] : (value instanceof Object[]) ? (Object[])value : new Object[]{value}; if (!allowDuplicates()) { Set<Object> set = new HashSet<Object>(); ArrayList<Object> l = new ArrayList<Object>(); set.addAll(elements); for (int i = 0; i < values.length; i++) { if(set.contains(values[i])) continue; l.add(values[i]); set.add(values[i]); } values = (Object[])l.toArray(new Object[0]); } return values; } protected void adjustForNumColumns(int numColumns) { Control control = getLabelComposite(); ((GridData)control.getLayoutData()).horizontalSpan = numColumns; ((GridData)list.getLayoutData()).horizontalSpan = numColumns - 1; } private void createButtons(Composite parent) { buttons[ADD] = createButton(parent, "ListEditor.add"); //$NON-NLS-1$ buttons[REMOVE] = createButton(parent, "ListEditor.remove"); //$NON-NLS-1$ buttons[UP] = createButton(parent, "ListEditor.up"); //$NON-NLS-1$ buttons[DOWN] = createButton(parent, "ListEditor.down"); //$NON-NLS-1$ } private Button createButton(Composite parent, String key) { Button b = new Button(parent, SWT.PUSH); b.setText(JFaceResources.getString(key)); b.setFont(parent.getFont()); GridData d = new GridData(GridData.FILL_HORIZONTAL); d.heightHint = convertVerticalDLUsToPixels(b, 14/*IDialogConstants.BUTTON_HEIGHT*/); int widthHint = convertHorizontalDLUsToPixels(b, IDialogConstants.BUTTON_WIDTH); d.widthHint = Math.max(widthHint, b.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x); b.setLayoutData(d); b.addSelectionListener(getSelectionListener()); return b; } public void createSelectionListener() { selectionListener = new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { if (event.widget == buttons[ADD]) { doAdd(); } else if (event.widget == buttons[REMOVE]) { doRemove(); } else if (event.widget == buttons[UP]) { doUp(); } else if (event.widget == buttons[DOWN]) { doDown(); } else if (event.widget == list) { selectionChanged(-1); } } }; } protected void doFillIntoGrid(Composite parent, int numColumns) { Control control = getLabelComposite(parent); assignLabelLayoutData(control, numColumns); list = createListControl(parent); assignListLayoutData(list, numColumns); buttonBox = getButtonBoxControl(parent); assignButtonLayoutData(buttonBox); } private void assignLabelLayoutData(Control control, int numColumns) { GridData gd = new GridData(); gd.horizontalSpan = numColumns; control.setLayoutData(gd); } private void assignListLayoutData(Control control, int numColumns) { GridData gd = new GridData(GridData.FILL_BOTH); //gd.verticalAlignment = GridData.FILL; gd.horizontalSpan = numColumns - 1; gd.grabExcessHorizontalSpace = true; control.setLayoutData(gd); } private void assignButtonLayoutData(Control control) { GridData gd = new GridData(); gd.verticalAlignment = GridData.BEGINNING; control.setLayoutData(gd); } protected void doLoad() { } protected void doLoadDefault() { } protected void doStore() { } private void doDown() { swap(false); } protected Composite getButtonBoxControl(Composite parent) { if (buttonBox == null) { buttonBox = new Composite(parent, SWT.NULL); GridLayout layout = new GridLayout(); layout.marginWidth = 0; buttonBox.setLayout(layout); createButtons(buttonBox); buttonBox.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent event) { for (int i = 0; i < buttons.length; i++) buttons[i] = null; buttonBox = null; } }); } else { checkParent(buttonBox, parent); } selectionChanged(0); return buttonBox; } protected Composite getMainPanel(Composite parent) { if (mainPanel == null) { mainPanel = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(2, false); layout.marginWidth = 0; mainPanel.setLayout(layout); list = createListControl(mainPanel); GridData gd = new GridData(GridData.FILL_BOTH); //gd.verticalAlignment = GridData.FILL; // gd.horizontalSpan = numColumns - 1; gd.grabExcessHorizontalSpace = true; list.setLayoutData(gd); buttonBox = getButtonBoxControl(mainPanel); gd = new GridData(); gd.verticalAlignment = GridData.BEGINNING; buttonBox.setLayoutData(gd); updateSelectionDependentActions(); } else checkParent(mainPanel, parent); return mainPanel; } protected List getListControl() { return list; } protected List createListControl(Composite parent) { if (list == null) { list = new List(parent, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL); list.setFont(parent.getFont()); list.addSelectionListener(getSelectionListener()); list.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent event) { list = null; } }); list.setItems(getItems()); } else { if(mainPanel != null) { checkParent(mainPanel, parent); } else { checkParent(list, parent); } } return list; } private java.util.List<Object> createElements() { java.util.List<Object> elements = new ArrayList<Object>(); if (this.listContentProvider!=null) elements.addAll(Arrays.asList(listContentProvider.getElements(this))); return elements; } private String[] getItems() { if (this.elements==null) { elements = createElements(); } Iterator i = elements.iterator(); ArrayList<String> list = new ArrayList<String>(); while (i.hasNext()) { Object o = i.next(); String s = this.labelProvider.getText(o); list.add(s); } return list.toArray(new String[list.size()]); } public int getNumberOfControls() { return 2; } private SelectionListener getSelectionListener() { if (selectionListener == null) createSelectionListener(); return selectionListener; } protected Shell getShell() { if (buttons[ADD] == null) return null; return buttons[ADD].getShell(); } private void doRemove() { setPresentsDefaultValue(false); int index = list.getSelectionIndex(); if (index >= 0) { list.remove(index); elements.remove(index); index = list.getItemCount() <= index ? list.getItemCount() - 1 : index; selectionChanged(index); } } private void selectionChanged(int newSelection) { // make StructuredChangedEvent and notify StructuredChangeListener StructuredChange change = new StructuredChange(elements); StructuredChangedEvent event = new StructuredChangedEvent(listContentProvider, change); structuredChangeListener.structureChanged(event); if(newSelection >= 0 && newSelection < list.getItemCount()) { list.select(newSelection); } updateSelectionDependentActions(); } private void updateSelectionDependentActions() { int index = list.getSelectionIndex(); int size = list.getItemCount(); buttons[REMOVE].setEnabled(index >= 0); buttons[UP].setEnabled(size > 1 && index > 0); buttons[DOWN].setEnabled(size > 1 && index >= 0 && index < size - 1); } public void setFocus() { if (list != null) list.setFocus(); } private void swap( boolean up) { setPresentsDefaultValue(false); int index = list.getSelectionIndex(); int target = up ? index - 1 : index + 1; if (index >= 0) { String[] selection = list.getSelection(); Assert.isTrue(selection.length == 1); list.remove(index); list.add(selection[0], target); list.setSelection(target); // elements Object o = elements.get(index); elements.remove(index); elements.add(target, o); } selectionChanged(target); } private void doUp() { swap(true); } public void setEnabled(boolean enabled, Composite parent){ super.setEnabled(enabled,parent); createListControl(parent).setEnabled(enabled); buttons[ADD].setEnabled(enabled); if(!enabled) { buttons[REMOVE].setEnabled(enabled); buttons[UP].setEnabled(enabled); buttons[DOWN].setEnabled(enabled); } else { updateSelectionDependentActions(); } } // IStructuredEditor public void setStructuredChangeListener(IStructuredChangeListener structuredChangeListener) { this.structuredChangeListener = structuredChangeListener; } public void setStructuredContentProvider(IStructuredContentProvider structuredContentProvider) { //this.structuredContentProvider = structuredContentProvider; } public void setNewStructuredElementProvider(StructuredListAdapter.INewValueProvider valueProvider) { newStructuredElementProvider = valueProvider; } // IListEditor public void setLabelProvider(ILabelProvider labelProvider) { this.labelProvider = labelProvider; } public void setListContentProvider(IListContentProvider listContentProvider) { this.listContentProvider = listContentProvider; // this.structuredContentProvider = listContentProvider; } // IFieldEditor public Control[] getControls(Composite parent) { // return new Control[] {getLabelComposite(parent), getListControl(parent), getButtonBoxControl(parent)}; return new Control[] {getLabelComposite(parent), getMainPanel(parent)}; } // IPropertyFieldEditor public void setPropertyEditor(IPropertyEditor propertyEditor) { this.propertyEditor = propertyEditor; if (propertyEditor!=null) { valueProvider = (IValueProvider)propertyEditor.getAdapter(IValueProvider.class); // IStructuredEditor structuredChangeListener = (IStructuredChangeListener)propertyEditor.getAdapter(IStructuredChangeListener.class); listContentProvider = (IListContentProvider)propertyEditor.getAdapter(IListContentProvider.class); newStructuredElementProvider = (StructuredListAdapter.INewValueProvider)propertyEditor.getAdapter(StructuredListAdapter.INewValueProvider.class); // IListEditor labelProvider = (ILabelProvider)propertyEditor.getAdapter(ILabelProvider.class); } valueProvider.addValueChangeListener(this); } protected boolean allowDuplicates() { return false; } public void propertyChange(PropertyChangeEvent evt) { super.propertyChange(evt); valueProvider.removeValueChangeListener(this); if (IPropertyEditor.VALUE.equals(evt.getPropertyName())) { elements = null; if(list!=null) { list.setItems(getItems()); list.redraw(); } } valueProvider.addValueChangeListener(this); } public void setEnabled(boolean enabled){ super.setEnabled(enabled); if (getListControl()!=null) { getListControl().setEnabled(enabled); } } public void cut() { } public void copy() { } public void paste() { } public void delete() { } }