X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.district.selection.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fselection%2Fui%2Fparts%2FEditSelectorDialog.java;h=b708d8e978695dc18919f05a80a824409d2b1564;hb=refs%2Fchanges%2F50%2F4050%2F1;hp=24df3cc0732c1329c0fe72729858cc56fc0c204b;hpb=cc256964c0755f7b0eef3b821b320a6926fd635e;p=simantics%2Fdistrict.git diff --git a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/EditSelectorDialog.java b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/EditSelectorDialog.java index 24df3cc0..b708d8e9 100644 --- a/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/EditSelectorDialog.java +++ b/org.simantics.district.selection.ui/src/org/simantics/district/selection/ui/parts/EditSelectorDialog.java @@ -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; @@ -51,7 +49,6 @@ import org.simantics.db.layer0.request.ActiveModels; import org.simantics.db.layer0.request.PropertyInfo; import org.simantics.db.layer0.request.PropertyInfoRequest; import org.simantics.db.layer0.util.Layer0Utils; -import org.simantics.db.request.Read; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.district.region.ontology.DiagramRegionsResource; @@ -143,10 +140,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 -> {}; @@ -186,71 +191,6 @@ public class EditSelectorDialog extends Dialog { diagramNames.add(e.getValue()); }); - final Map regions = new HashMap<>(); - final Map routes = new HashMap<>(); - - try { - Simantics.getSession().syncRequest(new Read() { - @Override - public Void perform(ReadGraph graph) throws DatabaseException { - Resource model = ActiveModels.getPossibleActiveModel(graph, Simantics.getProjectResource()); - List regionCollection = QueryIndexUtils.searchByType(graph, model, DiagramRegionsResource.getInstance(graph).Region); - for (Resource r : regionCollection) { - String name = graph.getRelatedValue(r, Layer0.getInstance(graph).HasName); - regions.put(r, name); - } - - List routeCollection = QueryIndexUtils.searchByType(graph, model, RouteResource.getInstance(graph).Route); - for (Resource r : routeCollection) { - String name = graph.getRelatedValue(r, Layer0.getInstance(graph).HasName); - routes.put(r, name); - } - return null; - } - }); - } catch (DatabaseException e) { - LOGGER.error("Failed to read routes and/or regions in the model", e); - } - - regionNames = regions.values().toArray(new String[regions.size()]); - regionResources = regions.keySet().toArray(new Resource[regions.size()]); - - routeNames = routes.values().toArray(new String[routes.size()]); - routeResources = routes.keySet().toArray(new Resource[routes.size()]); - - try { - Simantics.getSession().syncRequest(new ReadRequest() { - @Override - public void run(ReadGraph graph) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - List types = findComponentTypes(graph); - - componentTypes = new ArrayList<>(types.size() + 1); - componentTypeNames = new ArrayList<>(types.size() + 1); - - componentTypes.add(null); - componentTypeNames.add("Any type"); - componentTypes.addAll(types); - for (Resource t : types) { - componentTypeNames.add(graph.getValue2(t, L0.HasName)); - } - } - }); - } catch (DatabaseException e) { - LOGGER.error("Failed to read district component types", e); - } - - componentType = elementSelector.getSelector().componentType; - - propertyNames = new ArrayList<>(); - propertyLabels = new ArrayList<>(); - - try { - updatePropertyList(); - } catch (DatabaseException e) { - LOGGER.error("Failed to read district component properties", e); - } - name = elementSelector != null ? elementSelector.getName() : ""; propertyName = ""; numberOfItems = 1; @@ -290,11 +230,107 @@ public class EditSelectorDialog extends Dialog { } condition = elementSelector.getCondition(); + + componentType = elementSelector.getSelector().componentType; + } + + readRegions(diagram); + readRoutes(); + readComponentTypes(); + updatePropertyList(); + } + + private void readComponentTypes() { + try { + Simantics.getSession().syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + List types = findComponentTypes(graph); + + componentTypes = new ArrayList<>(types.size() + 1); + componentTypeNames = new ArrayList<>(types.size() + 1); + + componentTypes.add(null); + componentTypeNames.add("Any type"); + componentTypes.addAll(types); + for (Resource t : types) { + componentTypeNames.add(graph.getValue2(t, L0.HasName)); + } + } + }); + } catch (DatabaseException e) { + LOGGER.error("Failed to read district component types", e); + } + } + + private void readRoutes() { + final Map routes = new HashMap<>(); + + try { + Simantics.getSession().syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + RouteResource ROUTE = RouteResource.getInstance(graph); + + Resource model = ActiveModels.getPossibleActiveModel(graph, Simantics.getProjectResource()); + List routeCollection = QueryIndexUtils.searchByType(graph, model, ROUTE.Route); + for (Resource r : routeCollection) { + String name = graph.getRelatedValue(r, L0.HasLabel); + routes.put(r, name); + } + } + }); + } catch (DatabaseException e) { + LOGGER.error("Failed to read routes in the model", e); + } + + routeNames = routes.values().toArray(new String[routes.size()]); + routeResources = routes.keySet().toArray(new Resource[routes.size()]); + } + + private void readRegions(Resource diagram) { + final Map regions = new HashMap<>(); + + try { + Simantics.getSession().syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + ModelingResources MOD = ModelingResources.getInstance(graph); + DiagramRegionsResource DR = DiagramRegionsResource.getInstance(graph); + + // If a specific diagram is given, use that + Collection ds = diagram != null ? Collections.singleton(diagram) : diagrams; + + for (Resource composite : ds) { + Resource diagram = graph.getSingleObject(composite, MOD.CompositeToDiagram); + for (Resource r : graph.getObjects(diagram, DR.hasRegion)) { + if (!graph.isInstanceOf(r, DR.Region)) + continue; + String name = graph.getRelatedValue(r, L0.HasLabel); + regions.put(r, name); + } + } + } + }); + } catch (DatabaseException e) { + LOGGER.error("Failed to read regions in the model", e); } + + regionNames = regions.values().toArray(new String[regions.size()]); + regionResources = regions.keySet().toArray(new Resource[regions.size()]); } 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 +339,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 +520,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); @@ -485,6 +536,19 @@ public class EditSelectorDialog extends Dialog { componentTypeField.select(index >= 0 ? index : 0); } + // Update property selection controls when component type changes + componentTypeField.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + int index = componentTypeField.getSelectionIndex(); + componentType = index >= 0 ? componentTypes.get(index) : null; + updatePropertyList(); + propertyField.setItems(propertyLabels.toArray(new String[] {})); + + updateDialog(); + } + }); + new Label(selectorComposite, SWT.NONE).setText("with"); selectorField = new Combo(selectorComposite, SWT.BORDER | SWT.READ_ONLY); @@ -493,7 +557,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 +588,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 +596,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()); @@ -554,6 +618,11 @@ public class EditSelectorDialog extends Dialog { diagramField.clearSelection(); } diagramField.setEnabled(enabled); + + // Refresh list of regions for current diagram + diagram = enabled ? (diagramIndex >= 0 ? diagrams.get(diagramIndex) : null) : null; + readRegions(diagram); + updateDialog(); } }); @@ -586,7 +655,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 +670,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 +690,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 +764,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 +814,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 +825,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 +839,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 +850,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 +863,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 +880,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 +892,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 +903,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 +916,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; } @@ -871,49 +950,56 @@ public class EditSelectorDialog extends Dialog { return QueryIndexUtils.searchByType(graph, model, DN.Mapping_Base); } - void updatePropertyList() throws DatabaseException { + void updatePropertyList() { + propertyNames = new ArrayList<>(); + propertyLabels = new ArrayList<>(); + Collection types = componentType != null ? Collections.singleton(componentType) : componentTypes; Set> properties = new HashSet<>(); - Simantics.getSession().syncRequest(new ReadRequest() { - @Override - public void run(ReadGraph graph) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - - for (Resource type : types) { - if (type == null) - continue; - - Resource ct = graph.getPossibleObject(type, DistrictNetworkResource.getInstance(graph).Mapping_ComponentType); - if (ct == null) - continue; - - if (graph.isInstanceOf(ct, L0.String)) { - Resource indexRoot = graph.syncRequest(new IndexRoot(type)); - String name = graph.getValue(ct); - ct = GraphUtils.getPossibleChild(graph, indexRoot, name); - if (ct == null) - continue; - } + try { + Simantics.getSession().syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); - for (Resource prop : graph.getObjects(ct, L0.DomainOf)) { - if (!graph.isInstanceOf(prop, StructuralResource2.getInstance(graph).Property)) + for (Resource type : types) { + if (type == null) continue; - // Filter only numeric properties - PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(prop)); - if (info != null && info.requiredValueType != null && !isNumericValueType(info.requiredValueType)) + Resource ct = graph.getPossibleObject(type, DistrictNetworkResource.getInstance(graph).Mapping_ComponentType); + if (ct == null) continue; - String name = graph.getRelatedValue2(prop, L0.HasName); - String label = graph.getPossibleRelatedValue2(prop, L0.HasLabel); - if (label == null) label = name; + if (graph.isInstanceOf(ct, L0.String)) { + Resource indexRoot = graph.syncRequest(new IndexRoot(type)); + String name = graph.getValue(ct); + ct = GraphUtils.getPossibleChild(graph, indexRoot, name); + if (ct == null) + continue; + } - properties.add(Pair.make(label, name)); + for (Resource prop : graph.getObjects(ct, L0.DomainOf)) { + if (!graph.isInstanceOf(prop, StructuralResource2.getInstance(graph).Property)) + continue; + + // Filter only numeric properties + PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(prop)); + if (info != null && info.requiredValueType != null && !isNumericValueType(info.requiredValueType)) + continue; + + String name = graph.getRelatedValue2(prop, L0.HasName); + String label = graph.getPossibleRelatedValue2(prop, L0.HasLabel); + if (label == null) label = name; + + properties.add(Pair.make(label, name)); + } } } - } - }); + }); + } catch (DatabaseException e) { + LOGGER.error("Failed to read district component properties", e); + } propertyNames.clear(); propertyLabels.clear();