/******************************************************************* * Copyright (c) 2006-2013, Cloudsmith Inc. * The code, documentation and other materials contained herein * are the sole and exclusive property of Cloudsmith Inc. and may * not be disclosed, used, modified, copied or distributed without * prior written consent or license from Cloudsmith Inc. ******************************************************************/ package org.eclipse.buckminster.ui.editor; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import org.eclipse.buckminster.runtime.BuckminsterException; import org.eclipse.buckminster.ui.Messages; import org.eclipse.buckminster.ui.UiUtils; import org.eclipse.buckminster.ui.dialogs.Property; import org.eclipse.buckminster.ui.dialogs.PropertyDialog; import org.eclipse.buckminster.ui.internal.DynamicTableLayout; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FillLayout; 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.Table; import org.eclipse.swt.widgets.TableColumn; /** * @author Karel Brezina * */ public class Properties extends Composite { class PropertiesContentProvider implements IStructuredContentProvider { @Override public void dispose() { // Nothing to dispose } @Override public Object[] getElements(Object inputElement) { return properties.toArray(); } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { // Nothing to do } } class PropertiesLabelProvider extends LabelProvider implements ITableLabelProvider { @Override public Image getColumnImage(Object element, int columnIndex) { return null; } @Override public String getColumnText(Object element, int columnIndex) { Property prop = (Property) element; String lbl; switch (columnIndex) { case 0: lbl = prop.getKey().toString(); break; case 1: lbl = prop.getValue(); break; default: lbl = null; } return lbl; } } private List<Property> properties; private TableViewer tableViewer; private Button newButton; private Button editButton; private Button removeButton; private final ArrayList<PropertiesModifyListener> listeners = new ArrayList<PropertiesModifyListener>(); public Properties(Composite parent, int style) { super(parent, style); properties = Collections.emptyList(); initComposite(); } public void addPropertiesModifyListener(PropertiesModifyListener listener) { if (!listeners.contains(listener)) { listeners.add(listener); } } public void fillProperties(Map<String, String> mappedProperties) { mappedProperties.clear(); for (Property prop : properties) { mappedProperties.put(prop.getKey(), prop.getValue()); } } public List<Property> getProperties() { return properties; } public void refreshList() { tableViewer.setInput(properties); } public void removePropertiesModifyListener(PropertiesModifyListener listener) { listeners.remove(listener); } @Override public void setEnabled(boolean enabled) { tableViewer.getTable().setEnabled(enabled); if (enabled) { newButton.setEnabled(true); enableDisableButtonGroup(); } else { newButton.setEnabled(false); editButton.setEnabled(false); removeButton.setEnabled(false); } } public void setProperties(Map<String, String> mappedProperties) { properties = new ArrayList<Property>(); for (String key : mappedProperties.keySet()) { Property newProp = new Property(key, mappedProperties.get(key)); try { addProperty(newProp); } catch (CoreException e) { addPropertyErrorDialog(e); } } } private void addProperty(Property newProp) throws CoreException { String key = newProp.getKey(); int idx = -1; for (Property prop : properties) { if (prop.getKey().compareTo(key) == 0) { throw BuckminsterException.fromMessage(NLS.bind(Messages.duplicity_of_key_0, key)); } if (prop.getKey().compareTo(key) > 0) { idx = properties.indexOf(prop); break; } } if (idx >= 0) { properties.add(idx, newProp); } else { properties.add(newProp); } } private void addPropertyErrorDialog(Throwable e) { MessageDialog.openError(this.getShell(), Messages.error, NLS.bind(Messages.a_0_property_will_not_be_added, e.getMessage())); } private void createButtonBox(Composite parent) { Composite buttonBox = new Composite(parent, SWT.None); buttonBox.setLayout(new FillLayout(SWT.VERTICAL)); buttonBox.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); newButton = UiUtils.createPushButton(buttonBox, Messages.new_label, new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { newProperty(); } }); editButton = UiUtils.createPushButton(buttonBox, Messages.edit, new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { editProperty(); } }); removeButton = UiUtils.createPushButton(buttonBox, Messages.remove, new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { removeProperty(); } }); enableDisableButtonGroup(); } private void editProperty() { PropertyDialog dialog = new PropertyDialog(this.getShell(), getSelectedProperty()); int idx = tableViewer.getTable().getSelectionIndex(); if (dialog.open() == IDialogConstants.OK_ID) { properties.set(idx, dialog.getProperty()); notifyListeners(); refreshList(); } } private void enableDisableButtonGroup() { boolean enable = false; if (tableViewer.getTable().getSelectionIndex() >= 0) { enable = true; } editButton.setEnabled(enable); removeButton.setEnabled(enable); } private Property getSelectedProperty() { int idx = tableViewer.getTable().getSelectionIndex(); return idx >= 0 ? (Property) tableViewer.getElementAt(idx) : null; } private void initComposite() { GridLayout gridLayout = new GridLayout(2, false); gridLayout.marginHeight = gridLayout.marginWidth = 0; setLayout(gridLayout); setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Table table = new Table(this, SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); table.setHeaderVisible(false); String[] columnNames = new String[] { Messages.key, Messages.value }; int[] columnWeights = new int[] { 5, 15 }; table.setHeaderVisible(true); DynamicTableLayout layout = new DynamicTableLayout(50); for (int idx = 0; idx < columnNames.length; idx++) { TableColumn tableColumn = new TableColumn(table, SWT.LEFT, idx); tableColumn.setText(columnNames[idx]); layout.addColumnData(new ColumnWeightData(columnWeights[idx], true)); } table.setLayout(layout); GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); // gridData.widthHint = 600; table.setLayoutData(gridData); tableViewer = new TableViewer(table); tableViewer.setLabelProvider(new PropertiesLabelProvider()); tableViewer.setContentProvider(new PropertiesContentProvider()); tableViewer.setInput(properties); tableViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { enableDisableButtonGroup(); } }); tableViewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { if (tableViewer.getTable().getSelectionIndex() >= 0) { editProperty(); } } }); createButtonBox(this); } private void newProperty() { PropertyDialog dialog = new PropertyDialog(this.getShell(), null); if (dialog.open() == IDialogConstants.OK_ID) { try { addProperty(dialog.getProperty()); notifyListeners(); refreshList(); } catch (CoreException e) { addPropertyErrorDialog(e); } } } private void notifyListeners() { PropertiesModifyEvent e = new PropertiesModifyEvent(this); for (PropertiesModifyListener listener : listeners) listener.modifyProperties(e); } private void removeProperty() { Property prop = getSelectedProperty(); properties.remove(prop); notifyListeners(); refreshList(); } }