1 package org.simantics.district.selection.ui.parts;
3 import java.util.ArrayList;
4 import java.util.HashMap;
9 import javax.inject.Inject;
11 import org.eclipse.core.runtime.IStatus;
12 import org.eclipse.core.runtime.Status;
13 import org.eclipse.jface.dialogs.Dialog;
14 import org.eclipse.jface.dialogs.ErrorDialog;
15 import org.eclipse.jface.layout.GridDataFactory;
16 import org.eclipse.jface.layout.GridLayoutFactory;
17 import org.eclipse.jface.layout.RowLayoutFactory;
18 import org.eclipse.jface.window.Window;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.custom.StackLayout;
21 import org.eclipse.swt.events.SelectionAdapter;
22 import org.eclipse.swt.events.SelectionEvent;
23 import org.eclipse.swt.widgets.Button;
24 import org.eclipse.swt.widgets.Combo;
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Control;
27 import org.eclipse.swt.widgets.Label;
28 import org.eclipse.swt.widgets.Shell;
29 import org.eclipse.swt.widgets.Text;
30 import org.simantics.Simantics;
31 import org.simantics.db.ReadGraph;
32 import org.simantics.db.Resource;
33 import org.simantics.db.Session;
34 import org.simantics.db.WriteGraph;
35 import org.simantics.db.common.request.ReadRequest;
36 import org.simantics.db.common.request.WriteRequest;
37 import org.simantics.db.exception.DatabaseException;
38 import org.simantics.db.exception.RuntimeDatabaseException;
39 import org.simantics.db.layer0.QueryIndexUtils;
40 import org.simantics.db.layer0.request.ActiveModels;
41 import org.simantics.db.request.Read;
42 import org.simantics.db.request.WriteResult;
43 import org.simantics.district.region.ontology.DiagramRegionsResource;
44 import org.simantics.district.route.ontology.RouteResource;
45 import org.simantics.district.selection.ElementSelectionResource;
46 import org.simantics.district.selection.ElementSelectionUtils;
47 import org.simantics.district.selection.ElementSelector;
48 import org.simantics.district.selection.ElementSelector.AggregateCondition;
49 import org.simantics.district.selection.ElementSelector.AggregateCondition.Type;
50 import org.simantics.district.selection.ElementSelector.All;
51 import org.simantics.district.selection.ElementSelector.Condition;
52 import org.simantics.district.selection.ElementSelector.DiagramGenerator;
53 import org.simantics.district.selection.ElementSelector.ExplicitGenerator;
54 import org.simantics.district.selection.ElementSelector.Generator;
55 import org.simantics.district.selection.ElementSelector.ModelGenerator;
56 import org.simantics.district.selection.ElementSelector.PropertyCondition;
57 import org.simantics.district.selection.ElementSelector.PropertySelector;
58 import org.simantics.district.selection.ElementSelector.RegionCondition;
59 import org.simantics.district.selection.ElementSelector.RouteCondition;
60 import org.simantics.district.selection.ElementSelector.Selector;
61 import org.simantics.layer0.Layer0;
62 import org.simantics.modeling.ModelingResources;
63 import org.simantics.utils.datastructures.Arrays;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
67 public class EditSelectorDialog extends Dialog {
69 private static Logger LOGGER = LoggerFactory.getLogger(EditSelectorDialog.class);
71 private ElementSelector elementSelector;
73 // Data for comboboxes
74 Map<Resource, String> diagrams;
76 private String[] regionNames;
77 private Resource[] regionResources;
79 private String[] routeNames;
80 private Resource[] routeResources;
83 private int generatorIndex;
84 private Combo sourceField;
87 private Text nameField;
89 private Resource diagram;
90 private Combo diagramField;
92 private int selectorIndex;
93 private Combo selectorField;
95 private String propertyName;
96 private Text propertyField;
98 private int numberOfItems;
101 private Condition condition;
102 private Button removeConditionButton;
103 private Text conditionLabel;
105 // Dialog area component
106 private Composite content;
109 public EditSelectorDialog(Shell shell, ElementSelector elementSelector) {
112 this.elementSelector = elementSelector;
113 if (elementSelector != null) {
115 Simantics.getSession().sync(new ReadRequest() {
117 public void run(ReadGraph graph) throws DatabaseException {
118 elementSelector.buildSelection(graph);
121 } catch (DatabaseException e1) {
122 LOGGER.error("Failed to read element selector resource " + elementSelector.getResource(), e1);
123 throw new RuntimeDatabaseException(e1);
127 final Map<Resource, String> regions = new HashMap<>();
128 final Map<Resource, String> routes = new HashMap<>();
131 Simantics.getSession().syncRequest(new Read<Void>() {
133 public Void perform(ReadGraph graph) throws DatabaseException {
134 Resource model = ActiveModels.getPossibleActiveModel(graph, Simantics.getProjectResource());
135 List<Resource> regionCollection = QueryIndexUtils.searchByType(graph, model, DiagramRegionsResource.getInstance(graph).Region);
136 for (Resource r : regionCollection) {
137 String name = graph.getRelatedValue(r, Layer0.getInstance(graph).HasName);
138 regions.put(r, name);
141 List<Resource> routeCollection = QueryIndexUtils.searchByType(graph, model, RouteResource.getInstance(graph).Route);
142 for (Resource r : routeCollection) {
143 String name = graph.getRelatedValue(r, Layer0.getInstance(graph).HasName);
149 } catch (DatabaseException e) {
150 LOGGER.error("Failed to read routes and/or regions in the model", e);
153 regionNames = regions.values().toArray(new String[regions.size()]);
154 regionResources = regions.keySet().toArray(new Resource[regions.size()]);
156 routeNames = routes.values().toArray(new String[routes.size()]);
157 routeResources = routes.keySet().toArray(new Resource[routes.size()]);
159 name = elementSelector != null ? elementSelector.getName() : "";
167 if (elementSelector != null) {
168 Generator generator = elementSelector.getGenerator();
169 if (generator instanceof ModelGenerator) {
172 else if (generator instanceof DiagramGenerator) {
174 diagram = ((DiagramGenerator)generator).diagram;
176 else if (generator instanceof ExplicitGenerator) {
178 // TODO: Management of explicit lists of elements
181 throw new IllegalStateException("Unknown generator type " + generator.getClass().getName());
184 Selector selector = elementSelector.getSelector();
185 if (selector instanceof All) {
188 else if (selector instanceof PropertySelector) {
189 PropertySelector propertySelector = (PropertySelector)selector;
190 selectorIndex = propertySelector.smallest ? 1 : 2;
191 propertyName = propertySelector.propertyName;
192 numberOfItems = propertySelector.resultCount;
195 throw new IllegalStateException("Unknwon selector type " + selector.getClass().getName());
198 condition = elementSelector.getCondition();
203 protected void okPressed() {
204 generatorIndex = sourceField.getSelectionIndex();
205 if (generatorIndex == 1) {
206 int selectionIndex = diagramField.getSelectionIndex();
207 if (selectionIndex < 0) {
208 ErrorDialog.openError(getShell(), "Error", "Please select a diagram", new Status(IStatus.ERROR, "org.simantics.district.selection.ui", "No diagram selected"));
212 diagram = new ArrayList<Resource>(diagrams.keySet()).get(selectionIndex);
215 name = nameField.getText();
217 selectorIndex = selectorField.getSelectionIndex();
219 propertyName = propertyField.getText();
220 String text = nField.getText();
221 numberOfItems = "".equals(text) ? 0 : Integer.parseInt(text);
226 public void writeSelection() throws DatabaseException {
227 Simantics.getSession().syncRequest(new WriteRequest() {
229 public void perform(WriteGraph graph) throws DatabaseException {
230 Layer0 L0 = Layer0.getInstance(graph);
231 ElementSelectionResource ES = ElementSelectionResource.getInstance(graph);
233 graph.markUndoPoint();
235 Resource lib = ElementSelectionUtils.ensureSelectionLibrary(graph);
239 if (elementSelector != null) {
240 selection = elementSelector.getResource();
241 graph.deny(selection);
244 selection = graph.newResource();
247 graph.claim(selection, L0.InstanceOf, ES.Selection);
248 graph.claimLiteral(selection, L0.HasName, L0.String, UUID.randomUUID().toString());
249 graph.claimLiteral(selection, L0.HasLabel, L0.String, name);
250 graph.claim(selection, L0.PartOf, lib);
253 Resource generator = graph.newResource();
254 Resource generatorType;
255 switch (generatorIndex) {
257 generatorType = ES.Generator_Model;
260 generatorType = ES.Generator_Diagram;
261 Resource composite = graph.getPossibleObject(diagram, ModelingResources.getInstance(graph).DiagramToComposite);
262 graph.claim(generator, ES.Generator_HasDiagram, composite != null ? composite : diagram);
265 generatorType = ES.Generator_Explicit;
266 // TODO: Claim relations to current selection elements
268 default: throw new IllegalStateException("Invalid source index " + generatorIndex);
270 graph.claim(generator, L0.InstanceOf, generatorType);
271 graph.claim(selection, ES.Selection_HasGenerator, generator);
274 Resource selector = graph.newResource();
275 Resource selectorType;
276 switch (selectorIndex) {
277 case 0: selectorType = ES.Selector_All; break;
278 case 1: selectorType = ES.Selector_NLowest; break;
279 case 2: selectorType = ES.Selector_NHighest; break;
280 default: throw new IllegalStateException("Invalid selector index " + selectorIndex);
282 graph.claim(selector, L0.InstanceOf, selectorType);
283 graph.claim(selection, ES.Selection_HasSelector, selector);
285 if (selectorIndex > 0) {
286 graph.claimLiteral(selector, ES.PropertySelector_HasSelectionPropertyName, L0.String, propertyName);
287 graph.claimLiteral(selector, ES.PropertySelector_HasResultCount, L0.Integer, numberOfItems);
291 if (condition != null) {
292 graph.claim(selection, ES.Selection_HasCondition, condition.resource);
299 protected Control createDialogArea(Composite parent) {
301 getShell().setText("Edit element selector");
303 content = new Composite(parent, SWT.NONE);
304 GridLayoutFactory.swtDefaults().numColumns(3).applyTo(content);
307 Label nameLabel = new Label(content, SWT.NONE);
308 nameLabel.setText("Name");
309 GridDataFactory.swtDefaults().applyTo(nameLabel);
311 nameField = new Text(content, SWT.BORDER);
312 nameField.setEditable(true);
313 nameField.setText(name);
314 GridDataFactory.swtDefaults().span(2, 1).hint(200, SWT.DEFAULT).applyTo(nameField);
317 Label sourceLabel = new Label(content, SWT.NONE);
318 sourceLabel.setText("Source");
319 GridDataFactory.swtDefaults().applyTo(sourceLabel);
321 sourceField = new Combo(content, SWT.BORDER | SWT.READ_ONLY);
322 sourceField.setItems("Model", "Diagram", "Current selection");
323 sourceField.select(generatorIndex);
324 GridDataFactory.swtDefaults().span(1, 1).applyTo(sourceField);
326 diagramField = new Combo(content, SWT.BORDER | SWT.READ_ONLY);
327 GridDataFactory.swtDefaults().span(1, 1).applyTo(diagramField);
328 diagrams = ElementSelector.findDiagrams();
329 diagramField.setItems(diagrams.values().toArray(new String[diagrams.size()]));
331 int diagramIndex = diagram != null ? new ArrayList<>(diagrams.keySet()).indexOf(diagram) : -1;
332 diagramField.select(diagramIndex);
334 sourceField.addSelectionListener(new SelectionAdapter() {
336 public void widgetSelected(SelectionEvent e) {
337 generatorIndex = sourceField.getSelectionIndex();
338 diagramField.setVisible(isDiagramFieldVisible());
342 sourceField.select(generatorIndex);
343 diagramField.setVisible(isDiagramFieldVisible());
346 Label selectorLabel = new Label(content, SWT.NONE);
347 selectorLabel.setText("Select");
348 GridDataFactory.swtDefaults().span(1, 1).applyTo(selectorLabel);
350 selectorField = new Combo(content, SWT.BORDER | SWT.READ_ONLY);
351 selectorField.setItems("All", "N lowest", "N highest");
352 selectorField.select(selectorIndex);
353 GridDataFactory.swtDefaults().span(1, 1).applyTo(selectorField);
355 Composite selectorComposite = new Composite(content, SWT.NONE);
356 GridDataFactory.swtDefaults().span(1, 1).applyTo(selectorComposite);
357 GridLayoutFactory.swtDefaults().numColumns(2).applyTo(selectorComposite);
359 Label propertyLabel = new Label(selectorComposite, SWT.NONE);
360 propertyLabel.setText("Property name");
361 GridDataFactory.swtDefaults().applyTo(propertyLabel);
363 propertyField = new Text(selectorComposite, SWT.BORDER);
364 propertyField.setText(propertyName);
365 GridDataFactory.swtDefaults().hint(80, SWT.DEFAULT).applyTo(propertyField);
367 Label nLabel = new Label(selectorComposite, SWT.NONE);
368 nLabel.setText("Number of elements");
369 GridDataFactory.swtDefaults().applyTo(nLabel);
371 nField = new Text(selectorComposite, SWT.BORDER);
372 nField.setText(Integer.toString(numberOfItems));
373 GridDataFactory.swtDefaults().hint(40, SWT.DEFAULT).applyTo(nField);
375 selectorField.addSelectionListener(new SelectionAdapter() {
377 public void widgetSelected(SelectionEvent e) {
378 selectorIndex = selectorField.getSelectionIndex();
379 selectorComposite.setVisible(isSelectorCompositeVisible());
383 selectorField.select(selectorIndex);
384 selectorComposite.setVisible(isSelectorCompositeVisible());
387 new Label(content, SWT.NONE).setText("Condition");
388 conditionLabel = new Text(content, SWT.READ_ONLY);
389 GridDataFactory.swtDefaults().span(2, 1).applyTo(conditionLabel);
391 new Label(content, SWT.NONE);
392 Composite conditionPanel = new Composite(content, SWT.NONE);
393 GridDataFactory.swtDefaults().span(2, 1).applyTo(conditionPanel);
394 GridLayoutFactory.swtDefaults().margins(0, 0).numColumns(2).applyTo(conditionPanel);
395 Button conditionButton = new Button(conditionPanel, SWT.PUSH);
396 conditionButton.setText("Edit...");
397 GridDataFactory.swtDefaults().span(1, 1).applyTo(conditionButton);
398 removeConditionButton = new Button(conditionPanel, SWT.PUSH);
399 removeConditionButton.setText("Remove");
400 GridDataFactory.swtDefaults().span(1, 1).applyTo(removeConditionButton);
404 conditionButton.addSelectionListener(new SelectionAdapter() {
406 public void widgetSelected(SelectionEvent e) {
407 ConditionDialog dialog = new ConditionDialog(getShell(), condition);
408 if (dialog.open() == Window.OK) {
410 condition = dialog.createCondition();
411 } catch (DatabaseException e1) {
412 LOGGER.error("Creating a condition object failed", e1);
420 removeConditionButton.addSelectionListener(new SelectionAdapter() {
422 public void widgetSelected(SelectionEvent e) {
431 private void updateCondition() {
432 if (condition != null) {
433 removeConditionButton.setEnabled(true);
435 conditionLabel.setText(ElementSelector.getExpression(Simantics.getSession(), condition.resource));
436 } catch (DatabaseException e) {
437 LOGGER.error("Error getting expression string for " + condition.resource);
441 conditionLabel.setText("No condition");
442 removeConditionButton.setEnabled(false);
448 private boolean isDiagramFieldVisible() {
449 return generatorIndex == 1;
452 private boolean isSelectorCompositeVisible() {
453 return selectorIndex != 0;
456 class ConditionDialog extends Dialog {
457 // Resource of the edited condition
458 private Resource existingResource;
460 // Inverse condition button
461 private boolean isInverse;
462 private Button inverseField;
465 private int typeIndex;
466 private Combo typeField;
468 // Type-specific control panels under a stack layout
469 private Composite stackPanel;
470 private StackLayout stack;
472 private Composite propertyPanel;
473 private Composite regionPanel;
474 private Composite routePanel;
475 private Composite aggregatePanel;
477 // Property condition
478 private Double lowerLimit;
479 private Double upperLimit;
480 private String propertyName;
482 private Text propertyNameField;
483 private Text lowerLimitField;
484 private Text upperLimitField;
487 private Resource region;
488 private Combo regionField;
491 private Resource route;
492 private Combo routeField;
494 // Aggregate condition
495 private List<Condition> subConditions;
496 private boolean isConjunction;
498 private org.eclipse.swt.widgets.List subConditionField;
499 private Combo operatorField;
501 public ConditionDialog(Shell shell, Condition condition) {
509 subConditions = new ArrayList<>();
511 existingResource = condition != null ? condition.resource : null;
513 if (condition != null) {
514 if (condition instanceof PropertyCondition) {
516 PropertyCondition propertyCondition = (PropertyCondition)condition;
517 propertyName = propertyCondition.propertyName;
518 upperLimit = propertyCondition.upperLimit;
519 lowerLimit = propertyCondition.lowerLimit;
521 else if (condition instanceof RegionCondition) {
523 region = ((RegionCondition)condition).regionResource;
525 else if (condition instanceof RouteCondition) {
527 route = ((RouteCondition)condition).routeResource;
529 else if (condition instanceof AggregateCondition) {
531 subConditions = new ArrayList<>(((AggregateCondition)condition).conditions);
532 isConjunction = ((AggregateCondition)condition).type == Type.CONJUNCTION;
533 isInverse = ((AggregateCondition)condition).type == Type.NEGATION;
539 protected Control createDialogArea(Composite parent) {
540 getShell().setText("Edit selector condition");
542 Composite content = (Composite)super.createDialogArea(parent);
543 GridLayoutFactory.swtDefaults().numColumns(1).applyTo(content);
545 GridDataFactory defaultWidth = GridDataFactory.swtDefaults().hint(200, SWT.DEFAULT);
548 inverseField = new Button(content, SWT.CHECK);
549 inverseField.setText("Is inverse");
550 inverseField.setSelection(isInverse);
553 typeField = new Combo(content, SWT.BORDER | SWT.READ_ONLY);
554 typeField.setItems("Property value", "In region", "On route", "Combination");
555 typeField.select(typeIndex);
557 // Type-dependent stacked panels
558 stackPanel = new Composite(content, SWT.NONE);
559 stack = new StackLayout();
560 stackPanel.setLayout(stack);
562 // Property condition panel
563 propertyPanel = new Composite(stackPanel, SWT.NONE);
564 GridLayoutFactory.swtDefaults().numColumns(2).applyTo(propertyPanel);
566 new Label(propertyPanel, SWT.NONE).setText("Property name");
567 propertyNameField = new Text(propertyPanel, SWT.BORDER);
568 propertyNameField.setText(propertyName);
569 defaultWidth.applyTo(propertyNameField);
571 new Label(propertyPanel, SWT.NONE).setText("Lower limit");
572 lowerLimitField = new Text(propertyPanel, SWT.BORDER);
573 defaultWidth.applyTo(lowerLimitField);
574 if (lowerLimit != null) lowerLimitField.setText(lowerLimit.toString());
576 new Label(propertyPanel, SWT.NONE).setText("Upper limit");
577 upperLimitField = new Text(propertyPanel, SWT.BORDER);
578 defaultWidth.applyTo(upperLimitField);
579 if (upperLimit != null) upperLimitField.setText(upperLimit.toString());
581 // Region condition panel
582 regionPanel = new Composite(stackPanel, SWT.NONE);
583 GridLayoutFactory.swtDefaults().numColumns(2).applyTo(regionPanel);
585 new Label(regionPanel, SWT.NONE).setText("Region");
586 regionField = new Combo(regionPanel, SWT.BORDER | SWT.READ_ONLY);
587 regionField.setItems(regionNames);
588 defaultWidth.applyTo(regionField);
590 if (region != null) {
591 int regionIndex = Arrays.indexOf(regionResources, region);
592 regionField.select(regionIndex);
595 regionField.select(0);
598 // Route condition panel
599 routePanel = new Composite(stackPanel, SWT.NONE);
600 GridLayoutFactory.swtDefaults().numColumns(2).applyTo(routePanel);
602 new Label(routePanel, SWT.NONE).setText("Route");
603 routeField = new Combo(routePanel, SWT.BORDER | SWT.READ_ONLY);
604 routeField.setItems(routeNames);
605 defaultWidth.applyTo(routeField);
608 int routeIndex = Arrays.indexOf(routeResources, route);
609 routeField.select(routeIndex);
612 routeField.select(0);
615 // Aggregate condition panel
616 aggregatePanel = new Composite(stackPanel, SWT.NONE);
617 GridLayoutFactory.swtDefaults().numColumns(2).applyTo(aggregatePanel);
619 new Label(aggregatePanel, SWT.NONE).setText("Operator");
620 operatorField = new Combo(aggregatePanel, SWT.READ_ONLY);
621 operatorField.setItems("And", "Or");
622 operatorField.select(isConjunction ? 0 : 1);
624 new Label(aggregatePanel, SWT.NONE).setText("Sub-conditions");
625 Composite buttons = new Composite(aggregatePanel, SWT.NONE);
626 RowLayoutFactory.swtDefaults().justify(true).fill(true).extendedMargins(0, 0, 0, 0).type(SWT.HORIZONTAL).applyTo(buttons);
628 Button addButton = new Button(buttons, SWT.PUSH);
629 addButton.setText("Add");
630 Button removeButton = new Button(buttons, SWT.PUSH);
631 removeButton.setText("Remove");
632 Button editButton = new Button(buttons, SWT.PUSH);
633 editButton.setText("Edit");
635 new Label(aggregatePanel, SWT.NONE);
636 subConditionField = new org.eclipse.swt.widgets.List(aggregatePanel, SWT.BORDER);
637 GridDataFactory.swtDefaults().hint(200, 150).applyTo(subConditionField);
638 if (subConditions != null) {
639 Session session = Simantics.getSession();
640 List<String> items = new ArrayList<>();
641 for (Condition c : subConditions) {
643 items.add(ElementSelector.getExpression(session, c.resource));
644 } catch (DatabaseException e1) {
645 LOGGER.error("Condition expression read failed", e1);
646 items.add("<Unknown expression>");
650 subConditionField.setItems(items.toArray(new String[items.size()]));
653 addButton.addSelectionListener(new SelectionAdapter() {
655 public void widgetSelected(SelectionEvent e) {
656 ConditionDialog conditionDialog = new ConditionDialog(getShell(), null);
657 if (conditionDialog.open() == Window.OK) {
660 condition = conditionDialog.createCondition();
661 subConditions.add(condition);
664 subConditionField.add(ElementSelector.getExpression(Simantics.getSession(), condition.resource));
665 } catch (DatabaseException e1) {
666 LOGGER.error("Condition expression read failed", e1);
667 subConditionField.add("<Unknown expression>");
669 } catch (DatabaseException e2) {
670 LOGGER.error("Create condition failed", e2);
676 removeButton.addSelectionListener(new SelectionAdapter() {
678 public void widgetSelected(SelectionEvent e) {
679 int index = subConditionField.getSelectionIndex();
681 subConditionField.deselectAll();
682 subConditionField.remove(index);
683 subConditions.remove(index);
685 if (index < subConditions.size())
686 subConditionField.setSelection(index);
689 boolean selected = subConditionField.getSelectionIndex() >= 0;
690 removeButton.setEnabled(selected);
691 editButton.setEnabled(selected);
695 editButton.addSelectionListener(new SelectionAdapter() {
697 public void widgetSelected(SelectionEvent e) {
698 int index = subConditionField.getSelectionIndex();
700 Condition condition = subConditions.get(index);
701 ConditionDialog conditionDialog = new ConditionDialog(getShell(), condition);
702 if (conditionDialog.open() == Window.OK) {
704 condition = conditionDialog.createCondition();
705 subConditions.set(index, condition);
708 subConditionField.setItem(index, ElementSelector.getExpression(Simantics.getSession(), condition.resource));
709 } catch (DatabaseException e1) {
710 LOGGER.error("Condition expression read failed", e1);
711 subConditionField.setItem(index, "<Unknown expression>");
713 } catch (DatabaseException e2) {
714 LOGGER.error("Create condition failed", e2);
721 subConditionField.addSelectionListener(new SelectionAdapter() {
723 public void widgetSelected(SelectionEvent e) {
724 boolean selected = subConditionField.getSelectionIndex() >= 0;
725 removeButton.setEnabled(selected);
726 editButton.setEnabled(selected);
730 // Stack layout update
731 typeField.addSelectionListener(new SelectionAdapter() {
733 public void widgetSelected(SelectionEvent e) {
744 protected void okPressed() {
745 isInverse = inverseField.getSelection();
748 case 0: // Property condition
749 propertyName = propertyNameField.getText();
751 String lowerLimitText = lowerLimitField.getText();
752 lowerLimit = lowerLimitText.equals("") ? null : Double.valueOf(lowerLimitText);
753 String upperLimitText = upperLimitField.getText();
754 upperLimit = upperLimitText.equals("") ? null : Double.valueOf(upperLimitText);
756 catch (NumberFormatException e) {
757 ErrorDialog.openError(getShell(), "Error", "Invalid numeric value: " + e.getMessage(), new Status(OK, "org.simantics.district.selection.ui", e.getMessage()));
761 case 1: { // Region condition
762 int selectionIndex = regionField.getSelectionIndex();
763 if (selectionIndex < 0) {
764 ErrorDialog.openError(getShell(), "Error", "Please select a region", new Status(OK, "org.simantics.district.selection.ui", "No region selection"));
767 region = regionResources[selectionIndex];
770 case 2: // Route condition
771 route = routeResources[routeField.getSelectionIndex()];
773 case 3: // Aggregate condition
774 isConjunction = operatorField.getSelectionIndex() == 0;
781 protected Condition createCondition() throws DatabaseException {
782 if (isInverse && !(typeIndex == 3 && !isConjunction)) {
783 Resource resource0 = createCondition0();
786 Resource resource = Simantics.getSession().syncRequest(new WriteResult<Resource>() {
788 public Resource perform(WriteGraph graph) throws DatabaseException {
789 ElementSelectionResource ES = ElementSelectionResource.getInstance(graph);
790 Layer0 L0 = Layer0.getInstance(graph);
792 Resource r = graph.newResource();
793 graph.claim(r, L0.InstanceOf, ES.Negation);
794 graph.claim(r, ES.HasSubcondition, resource0);
799 return ElementSelector.getCondition(Simantics.getSession(), resource);
802 return ElementSelector.getCondition(Simantics.getSession(), createCondition0());
806 private Resource createCondition0() throws DatabaseException {
808 case 0: return createPropertyCondition();
809 case 1: return createRegionCondition();
810 case 2: return createRouteCondition();
811 case 3: return createAggregateCondition();
812 default: throw new IllegalStateException("Invalid condition type code " + typeIndex);
816 private Resource createPropertyCondition() throws DatabaseException {
817 return Simantics.getSession().syncRequest(new WriteResult<Resource>() {
819 public Resource perform(WriteGraph graph) throws DatabaseException {
820 ElementSelectionResource ES = ElementSelectionResource.getInstance(graph);
821 Layer0 L0 = Layer0.getInstance(graph);
823 Resource r = graph.newResource();
824 graph.claim(r, L0.InstanceOf, ES.PropertyCondition);
825 graph.claimLiteral(r, ES.PropertyCondition_HasPropertyName, propertyName);
826 if (lowerLimit != null)
827 graph.claimLiteral(r, ES.PropertyCondition_HasLowerLimit, L0.Double, lowerLimit);
828 if (upperLimit != null)
829 graph.claimLiteral(r, ES.PropertyCondition_HasUpperLimit, L0.Double, upperLimit);
836 private Resource createAggregateCondition() throws DatabaseException {
837 return Simantics.getSession().syncRequest(new WriteResult<Resource>() {
839 public Resource perform(WriteGraph graph) throws DatabaseException {
840 ElementSelectionResource ES = ElementSelectionResource.getInstance(graph);
841 Layer0 L0 = Layer0.getInstance(graph);
844 if (existingResource != null) {
845 // Reuse existing resource
846 r = existingResource;
847 // Clear any previous statements
848 graph.deny(existingResource);
851 r = graph.newResource();
855 type = isConjunction ? ES.Conjunction : isInverse ? ES.Negation : ES.Disjunction;
857 graph.claim(r, L0.InstanceOf, type);
858 for (Condition c : subConditions) {
859 graph.claim(r, ES.HasSubcondition, c.resource);
867 private Resource createRouteCondition() throws DatabaseException {
868 return Simantics.getSession().syncRequest(new WriteResult<Resource>() {
870 public Resource perform(WriteGraph graph) throws DatabaseException {
871 ElementSelectionResource ES = ElementSelectionResource.getInstance(graph);
872 Layer0 L0 = Layer0.getInstance(graph);
874 Resource r = graph.newResource();
875 graph.claim(r, L0.InstanceOf, ES.RouteCondition);
876 graph.claim(r, ES.RouteCondition_HasRoute, route);
882 private Resource createRegionCondition() throws DatabaseException {
883 return Simantics.getSession().syncRequest(new WriteResult<Resource>() {
885 public Resource perform(WriteGraph graph) throws DatabaseException {
886 ElementSelectionResource ES = ElementSelectionResource.getInstance(graph);
887 Layer0 L0 = Layer0.getInstance(graph);
889 Resource r = graph.newResource();
890 graph.claim(r, L0.InstanceOf, ES.RegionCondition);
891 graph.claim(r, ES.RegionCondition_HasRegion, region);
897 private void updateStack() {
898 typeIndex = typeField.getSelectionIndex();
900 case 0: stack.topControl = propertyPanel; break;
901 case 1: stack.topControl = regionPanel; break;
902 case 2: stack.topControl = routePanel; break;
903 case 3: stack.topControl = aggregatePanel; break;