]> gerrit.simantics Code Review - simantics/district.git/blobdiff - org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/EditSelectorDialog.java
More rigorous content validation for element selection dialog
[simantics/district.git] / org.simantics.district.selection.ui / src / org / simantics / district / selection / ui / parts / EditSelectorDialog.java
index 4814124b010954cffb030c3aa39aeb3f81b31b43..414eb33998e7ada921f6a63de19b9bcc2879d290 100644 (file)
@@ -14,10 +14,8 @@ import java.util.function.Consumer;
 
 import javax.inject.Inject;
 
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
 import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.layout.GridLayoutFactory;
 import org.eclipse.jface.layout.RowDataFactory;
@@ -143,10 +141,18 @@ public class EditSelectorDialog extends Dialog {
 
        private LocalResourceManager resourceManager;
        
+       static class ValidationException extends Exception {
+               private static final long serialVersionUID = 1L;
+
+               public ValidationException(String message) {
+                       super(message);
+               }
+       }
+       
        // Function type for updating condition objects with optional validation
        static interface Updater {
                // If 'validate' is true, a runtime exception may be thrown for invalid values
-               void update(boolean validate);
+               void update(boolean validate) throws ValidationException;
        }
        
        final static Updater NULL_UPDATE = validate -> {};
@@ -294,7 +300,13 @@ public class EditSelectorDialog extends Dialog {
        }
        
        private void updateDialog() {
-               updater.update(false);
+               try {
+                       updater.update(false);
+               } catch (ValidationException e) {
+                       // Should not happend with argument false
+                       assert(false);
+               }
+               
                updater = updateConditionPanel();
                
                content.layout(true, true);
@@ -303,38 +315,53 @@ public class EditSelectorDialog extends Dialog {
 
        @Override
        protected void okPressed() {
-               generatorIndex = sourceField.getSelectionIndex();
-               if (generatorIndex == 1) {
-                       int selectionIndex = diagramField.getSelectionIndex();
-                       if (selectionIndex < 0) {
-                               ErrorDialog.openError(getShell(), "Error", "Please select a diagram", new Status(IStatus.ERROR, "org.simantics.district.selection.ui", "No diagram selected"));
-                               return;
+               try {
+                       generatorIndex = sourceField.getSelectionIndex();
+                       if (generatorIndex == 1) {
+                               int selectionIndex = diagramField.getSelectionIndex();
+                               if (selectionIndex < 0) {
+                                       diagramField.setFocus();
+                                       throw new ValidationException("Please select a diagram");
+                               }
+                               
+                               diagram = diagrams.get(selectionIndex);
                        }
                        
-                       diagram = diagrams.get(selectionIndex);
-               }
-               
-               name = nameField.getText();
-               componentType = componentTypes.get(componentTypeField.getSelectionIndex());
-               selectorIndex = selectorField.getSelectionIndex();
-               int propertyIndex = propertyField.getSelectionIndex();
-               propertyName = propertyIndex >= 0 ? propertyNames.get(propertyIndex) : propertyField.getText();
-               
-               // Try to parse number of items
-               if (useNumberOfItems()) {
-                       try {
-                               numberOfItems = Integer.parseInt(nField.getText());
-                       } catch (RuntimeException e) {
-                               nField.selectAll();
-                               nField.forceFocus();
-                               return;
+                       name = nameField.getText();
+                       if (name.isEmpty()) {
+                               nameField.setFocus();
+                               throw new ValidationException("Please enter a name");
                        }
-               }
-
-               // To to update condition definitions
-               try {
+                       
+                       componentType = componentTypes.get(componentTypeField.getSelectionIndex());
+                       selectorIndex = selectorField.getSelectionIndex();
+                       int propertyIndex = propertyField.getSelectionIndex();
+                       propertyName = propertyIndex >= 0 ? propertyNames.get(propertyIndex) : propertyField.getText();
+                       if (propertyName.isEmpty()) {
+                               propertyField.setFocus();
+                               throw new ValidationException("Please select a property");
+                       }
+                       
+                       // Try to parse number of items
+                       if (useNumberOfItems()) {
+                               try {
+                                       numberOfItems = Integer.parseInt(nField.getText());
+                                       if (numberOfItems <= 0) {
+                                               nField.selectAll();
+                                               nField.setFocus();
+                                               throw new ValidationException("Number of elements must be positive");
+                                       }
+                               } catch (NumberFormatException e) {
+                                       nField.selectAll();
+                                       nField.setFocus();
+                                       throw new ValidationException("Please enter a valid number of elements");
+                               }
+                       }
+       
+                       // To to update condition definitions
                        updater.update(true);
-               } catch (RuntimeException e) {
+               } catch (ValidationException e) {
+                       MessageDialog.openError(this.getShell(), "Missing data", e.getMessage());
                        return;
                }
                
@@ -469,7 +496,7 @@ public class EditSelectorDialog extends Dialog {
 
                Composite selectorComposite = new Composite(content, SWT.NONE);
                GridDataFactory.swtDefaults().applyTo(selectorComposite);
-               RowLayoutFactory.swtDefaults().applyTo(selectorComposite);
+               RowLayoutFactory.fillDefaults().applyTo(selectorComposite);
                
                nField = new Text(selectorComposite, SWT.BORDER);
                RowDataFactory.swtDefaults().hint(40, SWT.DEFAULT).applyTo(nField);
@@ -493,7 +520,7 @@ public class EditSelectorDialog extends Dialog {
                RowDataFactory.swtDefaults().hint(40, SWT.DEFAULT).applyTo(selectorField);
                
                propertyField = new Combo(selectorComposite, SWT.NONE);
-               RowDataFactory.swtDefaults().hint(80, SWT.DEFAULT).applyTo(propertyField);
+               RowDataFactory.swtDefaults().hint(120, SWT.DEFAULT).applyTo(propertyField);
                propertyField.setItems(propertyLabels.toArray(new String[] {}));
                {
                        int index = propertyName != null ? propertyNames.indexOf(propertyName) : -1;
@@ -524,7 +551,7 @@ public class EditSelectorDialog extends Dialog {
                
                Composite sourceComposite = new Composite(content, SWT.NONE);
                GridDataFactory.swtDefaults().applyTo(sourceComposite);
-               RowLayoutFactory.swtDefaults().applyTo(sourceComposite);
+               RowLayoutFactory.fillDefaults().applyTo(sourceComposite);
                
                sourceField = new Combo(sourceComposite, SWT.BORDER | SWT.READ_ONLY);
                RowDataFactory.swtDefaults().applyTo(sourceField);
@@ -532,7 +559,7 @@ public class EditSelectorDialog extends Dialog {
                sourceField.select(generatorIndex);
                
                diagramField = new Combo(sourceComposite, SWT.BORDER | SWT.READ_ONLY);
-               RowDataFactory.swtDefaults().applyTo(diagramField);
+               RowDataFactory.swtDefaults().hint(120, SWT.DEFAULT).applyTo(diagramField);
                diagramField.setItems(diagramNames.toArray(new String[diagramNames.size()]));
                diagramField.setEnabled(isDiagramFieldVisible());
                
@@ -586,7 +613,7 @@ public class EditSelectorDialog extends Dialog {
                Button notCheck = new Button(parent, SWT.CHECK);
                GridDataFactory.swtDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(notCheck);
                notCheck.setText("not");
-               notCheck.setSelection(condition.isInverse);
+               notCheck.setSelection(condition != null && condition.isInverse);
                
                Composite conditionComp = new Composite(parent, SWT.NONE);
                GridDataFactory.fillDefaults().applyTo(conditionComp);
@@ -601,6 +628,8 @@ public class EditSelectorDialog extends Dialog {
                                "Any of"
                        );
                
+               typeCombo.addSelectionListener(new ConditionTypeSelectionListener(typeCombo, consumer, condition));
+
                final Updater updater;
                if (condition instanceof PropertyCondition) {
                        typeCombo.select(1);
@@ -619,11 +648,9 @@ public class EditSelectorDialog extends Dialog {
                        ROW_LAYOUT.applyTo(conditionComp);
                        notCheck.setEnabled(false);
                        typeCombo.select(0);
-                       updater = validate -> {};
+                       return NULL_UPDATE;
                }
                
-               typeCombo.addSelectionListener(new ConditionTypeSelectionListener(typeCombo, consumer, condition));
-
                return validate -> {
                        updater.update(validate);
                        condition.isInverse = notCheck.getSelection();
@@ -695,7 +722,7 @@ public class EditSelectorDialog extends Dialog {
                addButton.addSelectionListener(new SelectionAdapter() {
                        @Override
                        public void widgetSelected(SelectionEvent e) {
-                               cond.conditions.add(createPropertyCondition("property", null, null));
+                               cond.conditions.add(createPropertyCondition("", null, null));
                                updateDialog();
                        }
                });
@@ -745,7 +772,7 @@ public class EditSelectorDialog extends Dialog {
 
                // Create combo-box
                Combo routeCombo = new Combo(conditionComp, SWT.READ_ONLY);
-               RowDataFactory.swtDefaults().applyTo(routeCombo);
+               RowDataFactory.swtDefaults().hint(120, SWT.DEFAULT).applyTo(routeCombo);
                routeCombo.setItems(routeNames);
                
                // Set current selection
@@ -756,6 +783,11 @@ public class EditSelectorDialog extends Dialog {
                // Register update
                return validate -> {
                        int i = routeCombo.getSelectionIndex();
+                       if (validate && i < 0) {
+                               routeCombo.forceFocus();
+                               throw new RuntimeException("Must select a route");
+                       }
+                               
                        condition.routeResource = i >= 0 ? routeResources[i] : null;
                };
        }
@@ -765,7 +797,7 @@ public class EditSelectorDialog extends Dialog {
                
                // Create combo-box
                Combo regionCombo = new Combo(conditionComp, SWT.READ_ONLY);
-               RowDataFactory.swtDefaults().applyTo(regionCombo);
+               RowDataFactory.swtDefaults().hint(120, SWT.DEFAULT).applyTo(regionCombo);
                regionCombo.setItems(regionNames);
                
                // Set current selection
@@ -776,6 +808,11 @@ public class EditSelectorDialog extends Dialog {
                // Register update
                return validate -> {
                        int i = regionCombo.getSelectionIndex();
+                       if (validate && i < 0) {
+                               regionCombo.forceFocus();
+                               throw new ValidationException("Please select a region");
+                       }
+                       
                        condition.regionResource = i >= 0 ? regionResources[i] : null;
                };
        }
@@ -784,13 +821,13 @@ public class EditSelectorDialog extends Dialog {
                ROW_LAYOUT.applyTo(conditionComp);
                
                Text lowerLimitText = new Text(conditionComp, SWT.BORDER);
-               RowDataFactory.swtDefaults().applyTo(lowerLimitText);
+               RowDataFactory.swtDefaults().hint(40, SWT.DEFAULT).applyTo(lowerLimitText);
                lowerLimitText.setText(condition.lowerLimit != null ? Double.toString(condition.lowerLimit) : "");
                
                new Label(conditionComp, SWT.NONE).setText("\u2264");
                
                Combo propertyNameText = new Combo(conditionComp, SWT.NONE);
-               RowDataFactory.swtDefaults().applyTo(propertyNameText);
+               RowDataFactory.swtDefaults().hint(120, SWT.DEFAULT).applyTo(propertyNameText);
                propertyNameText.setItems(propertyLabels.toArray(new String[] {}));
                int index = propertyNames.indexOf(condition.propertyName);
                if (index >= 0)
@@ -801,7 +838,7 @@ public class EditSelectorDialog extends Dialog {
                new Label(conditionComp, SWT.NONE).setText("\u2264");
                
                Text upperLimitText = new Text(conditionComp, SWT.BORDER);
-               RowDataFactory.swtDefaults().applyTo(upperLimitText);
+               RowDataFactory.swtDefaults().hint(40, SWT.DEFAULT).applyTo(upperLimitText);
                upperLimitText.setText(condition.upperLimit != null ? Double.toString(condition.upperLimit) : "");
                
                // Register update
@@ -813,7 +850,7 @@ public class EditSelectorDialog extends Dialog {
                                if (validate) {
                                        lowerLimitText.selectAll();
                                        lowerLimitText.forceFocus();
-                                       throw e;
+                                       throw new ValidationException("Please enter a valid lower limit");
                                }
                        }
                        
@@ -824,7 +861,7 @@ public class EditSelectorDialog extends Dialog {
                                if (validate) {
                                        upperLimitText.selectAll();
                                        upperLimitText.forceFocus();
-                                       throw e;
+                                       throw new ValidationException("Please enter a valid upper limit");
                                }
                        }
                        
@@ -837,7 +874,7 @@ public class EditSelectorDialog extends Dialog {
                        
                        if (validate && name.isEmpty()) {
                                propertyNameText.forceFocus();
-                               throw new RuntimeException();
+                               throw new ValidationException("Please select a property");
                        } else {
                                condition.propertyName = name;
                        }
@@ -862,462 +899,6 @@ public class EditSelectorDialog extends Dialog {
                condition.isInverse = isInverse;
                return condition;
        }
-
-       /*
-       class ConditionDialog extends Dialog {
-               // Resource of the edited condition
-               private Resource existingResource;
-               
-               // Inverse condition button
-               private boolean isInverse;
-               private Button inverseField;
-
-               // Condition type
-               private int typeIndex;
-               private Combo typeField;
-               
-               // Type-specific control panels under a stack layout
-               private Composite stackPanel;
-               private StackLayout stack;
-               
-               private Composite propertyPanel;
-               private Composite regionPanel;
-               private Composite routePanel;
-               private Composite aggregatePanel;
-               
-               // Property condition
-               private Double lowerLimit;
-               private Double upperLimit;
-               private String propertyName;
-       
-               private Text propertyNameField;
-               private Text lowerLimitField;
-               private Text upperLimitField;
-               
-               // Region condition
-               private Resource region;
-               private Combo regionField;
-               
-               // Route condition
-               private Resource route;
-               private Combo routeField;
-               
-               // Aggregate condition
-               private List<Condition> subConditions;
-               private boolean isConjunction;
-               
-               private org.eclipse.swt.widgets.List subConditionField;
-               private Combo operatorField;
-               
-               public ConditionDialog(Shell shell, Condition condition) {
-                       super(shell);
-                       
-                       typeIndex = 0;
-                       isInverse = false;
-                       propertyName = "";
-                       upperLimit = null;
-                       lowerLimit = null;
-                       subConditions = new ArrayList<>();
-                       
-                       existingResource = condition != null ? condition.resource : null;
-
-                       if (condition != null) {
-                               if (condition instanceof PropertyCondition) {
-                                       typeIndex = 0;
-                                       PropertyCondition propertyCondition = (PropertyCondition)condition;
-                                       propertyName = propertyCondition.propertyName;
-                                       upperLimit = propertyCondition.upperLimit;
-                                       lowerLimit = propertyCondition.lowerLimit;
-                               }
-                               else if (condition instanceof RegionCondition) {
-                                       typeIndex = 1;
-                                       region = ((RegionCondition)condition).regionResource;
-                               }
-                               else if (condition instanceof RouteCondition) {
-                                       typeIndex = 2;
-                                       route = ((RouteCondition)condition).routeResource;
-                               }
-                               else if (condition instanceof AggregateCondition) {
-                                       typeIndex = 3;
-                                       subConditions = new ArrayList<>(((AggregateCondition)condition).conditions);
-                                       isConjunction = ((AggregateCondition)condition).type == Type.CONJUNCTION;
-                                       isInverse = ((AggregateCondition)condition).type == Type.NEGATION;
-                               }
-                       }
-               }
-               
-               @Override
-               protected Control createDialogArea(Composite parent) {
-                       getShell().setText("Edit selector condition");
-                       
-                       Composite content = (Composite)super.createDialogArea(parent);
-                       GridLayoutFactory.swtDefaults().numColumns(1).applyTo(content);
-                       
-                       GridDataFactory defaultWidth = GridDataFactory.swtDefaults().hint(200, SWT.DEFAULT);
-                       
-                       // Is inverse
-                       inverseField = new Button(content, SWT.CHECK);
-                       inverseField.setText("Is inverse");
-                       inverseField.setSelection(isInverse);
-                       
-                       // Condition type
-                       typeField = new Combo(content, SWT.BORDER | SWT.READ_ONLY);
-                       typeField.setItems("Property value", "In region", "On route", "Combination");
-                       typeField.select(typeIndex);
-                       
-                       // Type-dependent stacked panels
-                       stackPanel = new Composite(content, SWT.NONE);
-                       stack = new StackLayout();
-                       stackPanel.setLayout(stack);
-                       
-                       // Property condition panel
-                       propertyPanel = new Composite(stackPanel, SWT.NONE);
-                       GridLayoutFactory.swtDefaults().numColumns(2).applyTo(propertyPanel);
-                       
-                       new Label(propertyPanel, SWT.NONE).setText("Property name");
-                       propertyNameField = new Text(propertyPanel, SWT.BORDER);
-                       propertyNameField.setText(propertyName);
-                       defaultWidth.applyTo(propertyNameField);
-                       
-                       new Label(propertyPanel, SWT.NONE).setText("Lower limit");
-                       lowerLimitField = new Text(propertyPanel, SWT.BORDER);
-                       defaultWidth.applyTo(lowerLimitField);
-                       if (lowerLimit != null) lowerLimitField.setText(lowerLimit.toString());
-                       
-                       new Label(propertyPanel, SWT.NONE).setText("Upper limit");
-                       upperLimitField = new Text(propertyPanel, SWT.BORDER);
-                       defaultWidth.applyTo(upperLimitField);
-                       if (upperLimit != null) upperLimitField.setText(upperLimit.toString());
-                       
-                       // Region condition panel
-                       regionPanel = new Composite(stackPanel, SWT.NONE);
-                       GridLayoutFactory.swtDefaults().numColumns(2).applyTo(regionPanel);
-                       
-                       new Label(regionPanel, SWT.NONE).setText("Region");
-                       regionField = new Combo(regionPanel, SWT.BORDER | SWT.READ_ONLY);
-                       regionField.setItems(regionNames);
-                       defaultWidth.applyTo(regionField);
-                       
-                       if (region != null) {
-                               int regionIndex = Arrays.indexOf(regionResources, region);
-                               regionField.select(regionIndex);
-                       }
-                       else {
-                               regionField.select(0);
-                       }
-                       
-                       // Route condition panel
-                       routePanel = new Composite(stackPanel, SWT.NONE);
-                       GridLayoutFactory.swtDefaults().numColumns(2).applyTo(routePanel);
-                       
-                       new Label(routePanel, SWT.NONE).setText("Route");
-                       routeField = new Combo(routePanel, SWT.BORDER | SWT.READ_ONLY);
-                       routeField.setItems(routeNames);
-                       defaultWidth.applyTo(routeField);
-                       
-                       if (route != null) {
-                               int routeIndex = Arrays.indexOf(routeResources, route);
-                               routeField.select(routeIndex);
-                       }
-                       else {
-                               routeField.select(0);
-                       }
-                       
-                       // Aggregate condition panel
-                       aggregatePanel = new Composite(stackPanel, SWT.NONE);
-                       GridLayoutFactory.swtDefaults().numColumns(2).applyTo(aggregatePanel);
-                       
-                       new Label(aggregatePanel, SWT.NONE).setText("Operator");
-                       operatorField = new Combo(aggregatePanel, SWT.READ_ONLY);
-                       operatorField.setItems("And", "Or");
-                       operatorField.select(isConjunction ? 0 : 1);
-                       
-                       new Label(aggregatePanel, SWT.NONE).setText("Sub-conditions");
-                       Composite buttons = new Composite(aggregatePanel, SWT.NONE);
-                       RowLayoutFactory.swtDefaults().justify(true).fill(true).extendedMargins(0, 0, 0, 0).type(SWT.HORIZONTAL).applyTo(buttons);
-                       
-                       Button addButton = new Button(buttons, SWT.PUSH);
-                       addButton.setText("Add");
-                       Button removeButton = new Button(buttons, SWT.PUSH);
-                       removeButton.setText("Remove");
-                       Button editButton = new Button(buttons, SWT.PUSH);
-                       editButton.setText("Edit");
-
-                       new Label(aggregatePanel, SWT.NONE);
-                       subConditionField = new org.eclipse.swt.widgets.List(aggregatePanel, SWT.BORDER);
-                       GridDataFactory.swtDefaults().hint(200, 150).applyTo(subConditionField);
-                       if (subConditions != null) {
-                               Session session = Simantics.getSession();
-                               List<String> items = new ArrayList<>();
-                               for (Condition c : subConditions) {
-                                       try {
-                                               items.add(ElementSelector.getExpression(session, c.resource));
-                                       } catch (DatabaseException e1) {
-                                               LOGGER.error("Condition expression read failed", e1);
-                                               items.add("<Unknown expression>");
-                                       }
-                               }
-                               
-                               subConditionField.setItems(items.toArray(new String[items.size()]));
-                       }
-                       
-                       addButton.addSelectionListener(new SelectionAdapter() {
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       ConditionDialog conditionDialog = new ConditionDialog(getShell(), null);
-                                       if (conditionDialog.open() == Window.OK) {
-                                               Condition condition;
-                                               try {
-                                                       condition = conditionDialog.createCondition();
-                                                       subConditions.add(condition);
-                                                       
-                                                       try {
-                                                               subConditionField.add(ElementSelector.getExpression(Simantics.getSession(), condition.resource));
-                                                       } catch (DatabaseException e1) {
-                                                               LOGGER.error("Condition expression read failed", e1);
-                                                               subConditionField.add("<Unknown expression>");
-                                                       }
-                                               } catch (DatabaseException e2) {
-                                                       LOGGER.error("Create condition failed", e2);
-                                               }
-                                       }
-                               }
-                       });
-                       
-                       removeButton.addSelectionListener(new SelectionAdapter() {
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       int index = subConditionField.getSelectionIndex();
-                                       if (index >= 0) {
-                                               subConditionField.deselectAll();
-                                               subConditionField.remove(index);
-                                               subConditions.remove(index);
-                                               
-                                               if (index < subConditions.size())
-                                                       subConditionField.setSelection(index);
-                                       }
-                                       
-                                       boolean selected = subConditionField.getSelectionIndex() >= 0;
-                                       removeButton.setEnabled(selected);
-                                       editButton.setEnabled(selected);
-                               }
-                       });
-                       
-                       editButton.addSelectionListener(new SelectionAdapter() {
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       int index = subConditionField.getSelectionIndex();
-                                       if (index >= 0) {
-                                               Condition condition = subConditions.get(index);
-                                               ConditionDialog conditionDialog = new ConditionDialog(getShell(), condition);
-                                               if (conditionDialog.open() == Window.OK) {
-                                                       try {
-                                                               condition = conditionDialog.createCondition();
-                                                               subConditions.set(index, condition);
-                                                               
-                                                               try {
-                                                                       subConditionField.setItem(index, ElementSelector.getExpression(Simantics.getSession(), condition.resource));
-                                                               } catch (DatabaseException e1) {
-                                                                       LOGGER.error("Condition expression read failed", e1);
-                                                                       subConditionField.setItem(index, "<Unknown expression>");
-                                                               }
-                                                       } catch (DatabaseException e2) {
-                                                               LOGGER.error("Create condition failed", e2);
-                                                       }
-                                               }
-                                       }
-                               }
-                       });
-                       
-                       subConditionField.addSelectionListener(new SelectionAdapter() {
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       boolean selected = subConditionField.getSelectionIndex() >= 0;
-                                       removeButton.setEnabled(selected);
-                                       editButton.setEnabled(selected);
-                               }
-                       });
-
-                       // Stack layout update
-                       typeField.addSelectionListener(new SelectionAdapter() {
-                               @Override
-                               public void widgetSelected(SelectionEvent e) {
-                                       updateStack();
-                               }
-                       });
-                       
-                       updateStack();
-                       
-                       return content;
-               }
-               
-               @Override
-               protected void okPressed() {
-                       isInverse = inverseField.getSelection();
-                       
-                       switch (typeIndex) {
-                       case 0: // Property condition
-                               propertyName = propertyNameField.getText();
-                               try {
-                                       String lowerLimitText = lowerLimitField.getText();
-                                       lowerLimit = lowerLimitText.equals("") ? null : Double.valueOf(lowerLimitText);
-                                       String upperLimitText = upperLimitField.getText();
-                                       upperLimit = upperLimitText.equals("") ? null : Double.valueOf(upperLimitText);
-                               }
-                               catch (NumberFormatException e) {
-                                       ErrorDialog.openError(getShell(), "Error", "Invalid numeric value: " + e.getMessage(), new Status(OK, "org.simantics.district.selection.ui", e.getMessage()));
-                                       return;
-                               }
-                               break;
-                       case 1: { // Region condition
-                               int selectionIndex = regionField.getSelectionIndex();
-                               if (selectionIndex < 0) {
-                                       ErrorDialog.openError(getShell(), "Error", "Please select a region", new Status(OK, "org.simantics.district.selection.ui", "No region selection"));
-                                       return;
-                               }
-                               region = regionResources[selectionIndex];
-                               break;
-                       }
-                       case 2: // Route condition
-                               route = routeResources[routeField.getSelectionIndex()];
-                               break;
-                       case 3: // Aggregate condition
-                               isConjunction = operatorField.getSelectionIndex() == 0;
-                               break;
-                       }
-                       
-                       super.okPressed();
-               }
-       
-               protected Condition createCondition() throws DatabaseException {
-                       if (isInverse && !(typeIndex == 3 && !isConjunction)) {
-                               Resource resource0 = createCondition0(typeIndex);
-                               
-                               // Create a negation
-                               Resource resource = Simantics.getSession().syncRequest(new WriteResult<Resource>() {
-                                       @Override
-                                       public Resource perform(WriteGraph graph) throws DatabaseException {
-                                               ElementSelectionResource ES = ElementSelectionResource.getInstance(graph);
-                                               Layer0 L0 = Layer0.getInstance(graph);
-                                               
-                                               Resource r = graph.newResource();
-                                               graph.claim(r, L0.InstanceOf, ES.Negation);
-                                               graph.claim(r, ES.HasSubcondition, resource0);
-                                               return r;
-                                       }
-                               });
-                               
-                               return ElementSelector.getCondition(Simantics.getSession(), resource);
-                       }
-                       else {
-                               return ElementSelector.getCondition(Simantics.getSession(), createCondition0(typeIndex));
-                       }
-               }
-       
-               private Resource createCondition0(int index) throws DatabaseException {
-                       switch (index) {
-                       case 0: return createPropertyCondition();
-                       case 1: return createRegionCondition();
-                       case 2: return createRouteCondition();
-                       case 3: return createAggregateCondition();
-                       default: throw new IllegalStateException("Invalid condition type code " + index);
-                       }
-               }
-       
-               private Resource createPropertyCondition() throws DatabaseException {
-                       return Simantics.getSession().syncRequest(new WriteResult<Resource>() {
-                               @Override
-                               public Resource perform(WriteGraph graph) throws DatabaseException {
-                                       ElementSelectionResource ES = ElementSelectionResource.getInstance(graph);
-                                       Layer0 L0 = Layer0.getInstance(graph);
-                                       
-                                       Resource r = graph.newResource();
-                                       graph.claim(r, L0.InstanceOf, ES.PropertyCondition);
-                                       graph.claimLiteral(r, ES.PropertyCondition_HasPropertyName, propertyName);
-                                       if (lowerLimit != null)
-                                               graph.claimLiteral(r, ES.PropertyCondition_HasLowerLimit, L0.Double, lowerLimit);
-                                       if (upperLimit != null)
-                                               graph.claimLiteral(r, ES.PropertyCondition_HasUpperLimit, L0.Double, upperLimit);
-                                       
-                                       return r;
-                               }
-                       });
-               }
-               
-               private Resource createAggregateCondition() throws DatabaseException {
-                       return Simantics.getSession().syncRequest(new WriteResult<Resource>() {
-                               @Override
-                               public Resource perform(WriteGraph graph) throws DatabaseException {
-                                       ElementSelectionResource ES = ElementSelectionResource.getInstance(graph);
-                                       Layer0 L0 = Layer0.getInstance(graph);
-                                       
-                                       Resource r;
-                                       if (existingResource != null) {
-                                               // Reuse existing resource
-                                               r = existingResource;
-                                               // Clear any previous statements
-                                               graph.deny(existingResource);
-                                       }
-                                       else {
-                                               r = graph.newResource();
-                                       }
-                                       
-                                       Resource type;
-                                       type = isConjunction ? ES.Conjunction : isInverse ? ES.Negation : ES.Disjunction;
-                                       
-                                       graph.claim(r, L0.InstanceOf, type);
-                                       for (Condition c : subConditions) {
-                                               graph.claim(r, ES.HasSubcondition, c.resource);
-                                       }
-                                       
-                                       return r;
-                               }
-                       });
-               }
-       
-               private Resource createRouteCondition() throws DatabaseException {
-                       return Simantics.getSession().syncRequest(new WriteResult<Resource>() {
-                               @Override
-                               public Resource perform(WriteGraph graph) throws DatabaseException {
-                                       ElementSelectionResource ES = ElementSelectionResource.getInstance(graph);
-                                       Layer0 L0 = Layer0.getInstance(graph);
-                                       
-                                       Resource r = graph.newResource();
-                                       graph.claim(r, L0.InstanceOf, ES.RouteCondition);
-                                       graph.claim(r, ES.RouteCondition_HasRoute, route);
-                                       return r;
-                               }
-                       });
-               }
-       
-               private Resource createRegionCondition() throws DatabaseException {
-                       return Simantics.getSession().syncRequest(new WriteResult<Resource>() {
-                               @Override
-                               public Resource perform(WriteGraph graph) throws DatabaseException {
-                                       ElementSelectionResource ES = ElementSelectionResource.getInstance(graph);
-                                       Layer0 L0 = Layer0.getInstance(graph);
-                                       
-                                       Resource r = graph.newResource();
-                                       graph.claim(r, L0.InstanceOf, ES.RegionCondition);
-                                       graph.claim(r, ES.RegionCondition_HasRegion, region);
-                                       return r;
-                               }
-                       });
-               }
-
-               private void updateStack() {
-                       typeIndex = typeField.getSelectionIndex();
-                       switch (typeIndex) {
-                       case 0: stack.topControl = propertyPanel; break;
-                       case 1: stack.topControl = regionPanel; break;
-                       case 2: stack.topControl = routePanel; break;
-                       case 3: stack.topControl = aggregatePanel; break;
-                       }
-                       
-                       stackPanel.layout();
-               }
-       }
-       */
        
        static List<Resource> findComponentTypes(ReadGraph graph) throws DatabaseException {
                DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);