Skip to content
Snippets Groups Projects
Commit 40b31c0c authored by Simon Barner's avatar Simon Barner
Browse files

- Support to select an element more than once (enabled by default). In order...

- Support to select an element more than once (enabled by default). In order to disable this feature, use the map-based constructor of EStructuralFeatureValueProviderBase and construct the EStructuralFeature accordingly.
- Fix update of Ok button when deselecting all elements (fire second event to work around bug in DualList base class)
refs 1841
parent 5b48a072
No related branches found
No related tags found
No related merge requests found
......@@ -67,6 +67,9 @@ public class MultiSelectionCellEditor extends DialogCellEditor {
/** Mapping: label shown in GUI -> actual value. */
private LabelValueMapping labelValueMapping;
/** Flag that indicates if elements can be selected more than once. */
private boolean multiSelection;
/** The collection of elements selected using this {@link MultiSelectionCellEditor}. */
private Collection<?> selectedElements = CollectionUtils.emptyList();
......@@ -85,11 +88,12 @@ public class MultiSelectionCellEditor extends DialogCellEditor {
* Current collection of selected elements
*/
public void updateData(LabelValueMapping labelValueMapping, Collection<?> selectedElements,
int lowerMultiplicityBound, int upperMultiplicityBound) {
int lowerMultiplicityBound, int upperMultiplicityBound, boolean multiSelection) {
this.labelValueMapping = labelValueMapping;
this.selectedElements = selectedElements;
this.lowerMultiplicityBound = lowerMultiplicityBound;
this.upperMultiplicityBound = upperMultiplicityBound;
this.multiSelection = multiSelection;
}
/**
......@@ -111,17 +115,55 @@ public class MultiSelectionCellEditor extends DialogCellEditor {
return selectedElements;
}
/** Shows a dialog to that allows to select multiple values. */
private class MultiSelectionDialog extends Dialog {
/** Extension of {@link DualList} that optionally support to select an element more than once. */
private class MultiSelectionDualList extends DualList {
/**
* Initial collection of items (required to restore available items if
* {@link #multiSelection} is {@code true}.
*/
private DLItem[] initalItems;
/** Element selection dialog */
private DualList dl = null;
/**
* Constructs a new {@link MultiSelectionDualList}
*
* @param parent
* Parent {@link Composite} widget
* @param selectedElements
* Collection of elements that are selected initially
* @param labelValueMapping
* {@link LabelValueMapping} required to populate this
* {@link MultiSelectionDualList}.
*/
public MultiSelectionDualList(Composite parent, Collection<?> selectedElements,
LabelValueMapping labelValueMapping) {
/** Constructs a new {@link MultiSelectionDialog}. */
public MultiSelectionDialog(Shell parentShell) {
super(parentShell);
super(parent, SWT.NONE);
setShellStyle(getShellStyle() | SWT.RESIZE);
Image dummyImage = createDummyImage(getShell().getDisplay());
Set<String> labels = new HashSet<String>();
labels.addAll(labelValueMapping.getLabels());
for(Object selectedItem : selectedElements) {
String label = labelValueMapping.getLabelForValue(selectedItem);
DLItem item = new DLItem(label, dummyImage);
add(item);
selectDoNotFireEvent(0);
remove(item);
if(!multiSelection) {
labels.remove(label);
}
}
for(String label : labels) {
DLItem item = new DLItem(label, dummyImage);
add(item);
}
if(multiSelection) {
initalItems = getItems();
}
}
/**
......@@ -137,6 +179,78 @@ public class MultiSelectionCellEditor extends DialogCellEditor {
return image;
}
/**
* Method to be called at the beginning of any overridden select / deselect method in order
* to implement the multi selection behavior.
*/
private void selectDeselectPrologue() {
if(multiSelection) {
setRedraw(false);
}
}
/**
* Method to be called at the end of any overridden select / deselect method in order
* to implement the multi selection behavior.
*/
private void selectDeselectEpilogue() {
if(multiSelection) {
setItems(initalItems);
setRedraw(true);
}
}
/** {@inheritDoc} */
@Override
protected void selectItem() {
selectDeselectPrologue();
super.selectItem();
selectDeselectEpilogue();
}
/** {@inheritDoc} */
@Override
public void selectAll() {
selectDeselectPrologue();
super.selectAll();
selectDeselectEpilogue();
}
/** {@inheritDoc} */
@Override
protected void deselectItem() {
selectDeselectPrologue();
super.deselectItem();
selectDeselectEpilogue();
}
/** {@inheritDoc} */
@Override
public void deselectAll(final boolean shouldFireEvents) {
selectDeselectPrologue();
super.deselectAll(shouldFireEvents);
// Required to issue a selection changed event after all elements have actually been
// deselected. This is required for the invocation of
// MultiSelectionDialog.updateOkButton() to work correctly.
super.deselectAll(false);
selectDeselectEpilogue();
}
}
/** Shows a dialog to that allows to select multiple values. */
private class MultiSelectionDialog extends Dialog {
/** Element selection dialog */
private DualList dl = null;
/** Constructs a new {@link MultiSelectionDialog}. */
public MultiSelectionDialog(Shell parentShell) {
super(parentShell);
setShellStyle(getShellStyle() | SWT.RESIZE);
}
/** {@inheritDoc} */
@Override
protected Composite createDialogArea(Composite parent) {
......@@ -144,24 +258,7 @@ public class MultiSelectionCellEditor extends DialogCellEditor {
Composite area = (Composite)super.createDialogArea(parent);
area.setLayout(new FillLayout());
Set<String> labels = new HashSet<String>();
labels.addAll(labelValueMapping.getLabels());
Image dummyImage = createDummyImage(getShell().getDisplay());
dl = new DualList(area, SWT.NONE);
for(Object selectedItem : selectedElements) {
String label = labelValueMapping.getLabelForValue(selectedItem);
DLItem item = new DLItem(label, dummyImage);
dl.add(item);
dl.selectDoNotFireEvent(0);
dl.remove(item);
labels.remove(label);
}
for(String label : labels) {
DLItem item = new DLItem(label, dummyImage);
dl.add(item);
}
dl = new MultiSelectionDualList(area, selectedElements, labelValueMapping);
return area;
}
......
......@@ -91,7 +91,8 @@ public class MultiSelectionEditingSupport extends AnnotationEditingSupportBase {
multiSelectionEditDialog.updateData(labelValueMapping, valuesCopy,
eStructuralFeatureDescriptor.getEStructuralFeature(specification).getLowerBound(),
eStructuralFeatureDescriptor.getEStructuralFeature(specification).getUpperBound());
eStructuralFeatureDescriptor.getEStructuralFeature(specification).getUpperBound(),
eStructuralFeatureDescriptor.getMultiSelection());
return multiSelectionEditDialog;
}
......
......@@ -71,16 +71,32 @@ public class EStructuralFeatureDescriptor {
*/
private EReferenceScope eReferenceScope;
/** Flag that indicates if elements that have a multiplicity > 1 can be selected more than once. */
private boolean multiSelection;
/** Constructs a {@link EStructuralFeatureDescriptor} for an {@link EAttribute}. */
public EStructuralFeatureDescriptor(EAttribute eAttribute) {
this(eAttribute, true);
}
/** Constructs a {@link EStructuralFeatureDescriptor} for an {@link EAttribute}. */
public EStructuralFeatureDescriptor(EAttribute eAttribute, boolean multiSelection) {
this.eStructuralFeature = eAttribute;
this.eReferenceScope = null;
this.multiSelection = multiSelection;
}
/** Constructs a {@link EStructuralFeatureDescriptor} for an {@link EReference}. */
public EStructuralFeatureDescriptor(EReference eReference, EReferenceScope eReferenceScope) {
this(eReference, eReferenceScope, true);
}
/** Constructs a {@link EStructuralFeatureDescriptor} for an {@link EReference}. */
public EStructuralFeatureDescriptor(EReference eReference, EReferenceScope eReferenceScope,
boolean multiSelection) {
this.eStructuralFeature = eReference;
this.eReferenceScope = eReferenceScope;
this.multiSelection = multiSelection;
}
/**
......@@ -127,4 +143,9 @@ public class EStructuralFeatureDescriptor {
return eType;
}
/** Flag that indicates if elements that have a multiplicity > 1 can be selected more than once. */
public boolean getMultiSelection() {
return multiSelection;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment