package net.sourceforge.pmd.eclipse.ui.preferences.editors; import java.util.List; import net.sourceforge.pmd.PropertyDescriptor; import net.sourceforge.pmd.PropertySource; import net.sourceforge.pmd.Rule; import net.sourceforge.pmd.eclipse.ui.preferences.br.ValueChangeListener; import net.sourceforge.pmd.lang.rule.properties.EnumeratedMultiProperty; import net.sourceforge.pmd.lang.rule.properties.PropertyDescriptorWrapper; import net.sourceforge.pmd.util.CollectionUtil; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Text; /** * Behaviour: * Provide a set of widgets that allows the user to select any number of items from a fixed set of choices. Each item can only appear once. * * Provide a combo box for each value selected while ensuring that their choices only contain unselected values. If the last combo box holds the only * remaining choice then ensure it gets disabled, the user can only delete it or the previous ones. If the user deletes a previous one then re-enable * the last one and add the deleted value to its set of choices. * * @author Brian Remedios * * ! PLACEHOLDER ONLY - NOT FINISHED YET ! */ public class MultiEnumerationEditorFactory extends AbstractMultiValueEditorFactory { public static final MultiEnumerationEditorFactory instance = new MultiEnumerationEditorFactory(); private MultiEnumerationEditorFactory() { } private static EnumeratedMultiProperty<?> enumerationPropertyFrom(PropertyDescriptor<?> desc) { if (desc instanceof PropertyDescriptorWrapper<?>) { return (EnumeratedMultiProperty<?>) ((PropertyDescriptorWrapper<?>)desc).getPropertyDescriptor(); } else { return (EnumeratedMultiProperty<?>)desc; } } @Override protected Object addValueIn(Control widget, PropertyDescriptor<?> desc, PropertySource source) { int idx = ((Combo)widget).getSelectionIndex(); if (idx < 0) return null; String newValue = ((Combo)widget).getItem(idx); String[] currentValues = (String[])valueFor(source, desc); String[] newValues = CollectionUtil.addWithoutDuplicates(currentValues, newValue); if (currentValues.length == newValues.length) return null; source.setProperty((EnumeratedMultiProperty<?>)desc, newValues); return newValue; } /** * Only add a new widget row if there are any remaining choices to make */ @Override protected boolean canAddNewRowFor(PropertyDescriptor<?> desc, PropertySource source) { Object[] choices = desc.choices(); Object[] values = (Object[])source.getProperty(desc); return choices.length > values.length; } @Override protected Control addWidget(Composite parent, Object value, PropertyDescriptor<?> desc, final PropertySource source) { final Combo combo = new Combo(parent, SWT.READ_ONLY); final EnumeratedMultiProperty<?> ep = enumerationPropertyFrom(desc); // TODO remove all choices already chosen by previous widgets combo.setItems(SWTUtil.labelsIn(ep.choices(), 0)); int selectionIdx = EnumerationEditorFactory.indexOf(value, ep.choices()); if (selectionIdx >= 0) combo.select(selectionIdx); return combo; } @Override protected void setValue(Control widget, Object value) { // not necessary, set in addWidget method? } @Override protected void update(PropertySource source, PropertyDescriptor<?> desc, List<Object> newValues) { source.setProperty((EnumeratedMultiProperty<?>)desc, newValues.toArray(new String[newValues.size()])); } @Override protected Object valueFrom(Control valueControl) { // unreferenced method? return null; } public PropertyDescriptor<?> createDescriptor(String name, String description, Control[] otherData) { return null; } @Override protected void configure(Text text, PropertyDescriptor<?> desc, PropertySource source, ValueChangeListener listener) { text.setEditable(false); } }