package org.simantics.district.selection.ui.parts; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; 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.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.layout.RowLayoutFactory; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.WriteGraph; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.RuntimeDatabaseException; import org.simantics.db.layer0.QueryIndexUtils; import org.simantics.db.layer0.request.ActiveModels; import org.simantics.db.layer0.util.Layer0Utils; import org.simantics.db.request.Read; import org.simantics.db.request.WriteResult; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.district.region.ontology.DiagramRegionsResource; import org.simantics.district.route.ontology.RouteResource; import org.simantics.district.selection.ElementSelectionResource; import org.simantics.district.selection.ElementSelectionUtils; import org.simantics.district.selection.ElementSelector; import org.simantics.district.selection.ElementSelector.AggregateCondition; import org.simantics.district.selection.ElementSelector.AggregateCondition.Type; import org.simantics.district.selection.ElementSelector.All; import org.simantics.district.selection.ElementSelector.Condition; import org.simantics.district.selection.ElementSelector.DiagramGenerator; import org.simantics.district.selection.ElementSelector.ExplicitGenerator; import org.simantics.district.selection.ElementSelector.Generator; import org.simantics.district.selection.ElementSelector.ModelGenerator; import org.simantics.district.selection.ElementSelector.PropertyCondition; import org.simantics.district.selection.ElementSelector.PropertySelector; import org.simantics.district.selection.ElementSelector.RegionCondition; import org.simantics.district.selection.ElementSelector.RouteCondition; import org.simantics.district.selection.ElementSelector.Selector; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; import org.simantics.utils.datastructures.Arrays; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class EditSelectorDialog extends Dialog { private static Logger LOGGER = LoggerFactory.getLogger(EditSelectorDialog.class); private ElementSelector elementSelector; // Currently selected elements Collection currentSelection; // Data for comboboxes Map diagrams; private String[] regionNames; private Resource[] regionResources; private String[] routeNames; private Resource[] routeResources; // Dialog fields private int generatorIndex; private Combo sourceField; private String name; private Text nameField; private Resource diagram; private Combo diagramField; private int selectorIndex; private Combo selectorField; private String propertyName; private Text propertyField; private int numberOfItems; private Text nField; private Condition condition; private Button removeConditionButton; private Text conditionLabel; // Dialog area component private Composite content; @Inject public EditSelectorDialog(Shell shell, ElementSelector elementSelector, Collection currentSelection) { super(shell); this.elementSelector = elementSelector; if (elementSelector != null) { try { Simantics.getSession().sync(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { elementSelector.buildSelection(graph); } }); } catch (DatabaseException e1) { LOGGER.error("Failed to read element selector resource " + elementSelector.getResource(), e1); throw new RuntimeDatabaseException(e1); } } this.currentSelection = currentSelection; 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()]); name = elementSelector != null ? elementSelector.getName() : ""; propertyName = ""; numberOfItems = 1; generatorIndex = 0; selectorIndex = 0; diagram = null; condition = null; if (elementSelector != null) { Generator generator = elementSelector.getGenerator(); if (generator instanceof ModelGenerator) { generatorIndex = 0; } else if (generator instanceof DiagramGenerator) { generatorIndex = 1; diagram = ((DiagramGenerator)generator).diagram; } else if (generator instanceof ExplicitGenerator) { generatorIndex = 2; // TODO: Management of explicit lists of elements } else { throw new IllegalStateException("Unknown generator type " + generator.getClass().getName()); } Selector selector = elementSelector.getSelector(); if (selector instanceof All) { selectorIndex = 0; } else if (selector instanceof PropertySelector) { PropertySelector propertySelector = (PropertySelector)selector; selectorIndex = propertySelector.smallest ? 1 : 2; propertyName = propertySelector.propertyName; numberOfItems = propertySelector.resultCount; } else { throw new IllegalStateException("Unknwon selector type " + selector.getClass().getName()); } condition = elementSelector.getCondition(); } } @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; } diagram = new ArrayList(diagrams.keySet()).get(selectionIndex); } name = nameField.getText(); selectorIndex = selectorField.getSelectionIndex(); propertyName = propertyField.getText(); String text = nField.getText(); numberOfItems = "".equals(text) ? 0 : Integer.parseInt(text); super.okPressed(); } public void writeSelection() throws DatabaseException { Simantics.getSession().syncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); ElementSelectionResource ES = ElementSelectionResource.getInstance(graph); ModelingResources MOD = ModelingResources.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); graph.markUndoPoint(); Layer0Utils.addCommentMetadata(graph, "Created new element selection"); Resource lib = ElementSelectionUtils.ensureSelectionLibrary(graph); // Selection Resource selection; if (elementSelector != null) { selection = elementSelector.getResource(); graph.deny(selection); } else { selection = graph.newResource(); } graph.claim(selection, L0.InstanceOf, ES.Selection); graph.claimLiteral(selection, L0.HasName, L0.String, UUID.randomUUID().toString()); graph.claimLiteral(selection, L0.HasLabel, L0.String, name); graph.claim(selection, L0.PartOf, lib); // Generator Resource generator = graph.newResource(); Resource generatorType; switch (generatorIndex) { case 0: generatorType = ES.Generator_Model; break; case 1: generatorType = ES.Generator_Diagram; Resource composite = graph.getPossibleObject(diagram, MOD.DiagramToComposite); graph.claim(generator, ES.Generator_HasDiagram, composite != null ? composite : diagram); break; case 2: generatorType = ES.Generator_Explicit; for (Resource r : currentSelection) { // No connections if (graph.isInstanceOf(r, DIA.Connection)) continue; if (!graph.isInstanceOf(r, DIA.Element)) { if (!graph.hasStatement(r, MOD.ComponentToElement)) continue; r = graph.getPossibleObject(r, MOD.ComponentToElement); if (r == null) continue; } graph.claim(generator, ES.Generator_HasSelectedElement, r); } break; default: throw new IllegalStateException("Invalid source index " + generatorIndex); } graph.claim(generator, L0.InstanceOf, generatorType); graph.claim(selection, ES.Selection_HasGenerator, generator); // Selector Resource selector = graph.newResource(); Resource selectorType; switch (selectorIndex) { case 0: selectorType = ES.Selector_All; break; case 1: selectorType = ES.Selector_NLowest; break; case 2: selectorType = ES.Selector_NHighest; break; default: throw new IllegalStateException("Invalid selector index " + selectorIndex); } graph.claim(selector, L0.InstanceOf, selectorType); graph.claim(selection, ES.Selection_HasSelector, selector); if (selectorIndex > 0) { graph.claimLiteral(selector, ES.PropertySelector_HasSelectionPropertyName, L0.String, propertyName); graph.claimLiteral(selector, ES.PropertySelector_HasResultCount, L0.Integer, numberOfItems); } // Condition if (condition != null) { graph.claim(selection, ES.Selection_HasCondition, condition.resource); } } }); } @Override protected Control createDialogArea(Composite parent) { // Set dialog title getShell().setText("Edit element selector"); content = new Composite(parent, SWT.NONE); GridLayoutFactory.swtDefaults().numColumns(3).applyTo(content); // Name Label nameLabel = new Label(content, SWT.NONE); nameLabel.setText("Name"); GridDataFactory.swtDefaults().applyTo(nameLabel); nameField = new Text(content, SWT.BORDER); nameField.setEditable(true); nameField.setText(name); GridDataFactory.swtDefaults().span(2, 1).hint(200, SWT.DEFAULT).applyTo(nameField); // Source Label sourceLabel = new Label(content, SWT.NONE); sourceLabel.setText("Source"); GridDataFactory.swtDefaults().applyTo(sourceLabel); sourceField = new Combo(content, SWT.BORDER | SWT.READ_ONLY); sourceField.setItems("Model", "Diagram", "Current selection"); sourceField.select(generatorIndex); GridDataFactory.swtDefaults().span(1, 1).applyTo(sourceField); diagramField = new Combo(content, SWT.BORDER | SWT.READ_ONLY); GridDataFactory.swtDefaults().span(1, 1).applyTo(diagramField); diagrams = ElementSelector.findDiagrams(); diagramField.setItems(diagrams.values().toArray(new String[diagrams.size()])); int diagramIndex = diagram != null ? new ArrayList<>(diagrams.keySet()).indexOf(diagram) : -1; diagramField.select(diagramIndex); sourceField.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { generatorIndex = sourceField.getSelectionIndex(); diagramField.setVisible(isDiagramFieldVisible()); } }); sourceField.select(generatorIndex); diagramField.setVisible(isDiagramFieldVisible()); // Selector Label selectorLabel = new Label(content, SWT.NONE); selectorLabel.setText("Select"); GridDataFactory.swtDefaults().span(1, 1).applyTo(selectorLabel); selectorField = new Combo(content, SWT.BORDER | SWT.READ_ONLY); selectorField.setItems("All", "N lowest", "N highest"); selectorField.select(selectorIndex); GridDataFactory.swtDefaults().span(1, 1).applyTo(selectorField); Composite selectorComposite = new Composite(content, SWT.NONE); GridDataFactory.swtDefaults().span(1, 1).applyTo(selectorComposite); GridLayoutFactory.swtDefaults().numColumns(2).applyTo(selectorComposite); Label propertyLabel = new Label(selectorComposite, SWT.NONE); propertyLabel.setText("Property name"); GridDataFactory.swtDefaults().applyTo(propertyLabel); propertyField = new Text(selectorComposite, SWT.BORDER); propertyField.setText(propertyName); GridDataFactory.swtDefaults().hint(80, SWT.DEFAULT).applyTo(propertyField); Label nLabel = new Label(selectorComposite, SWT.NONE); nLabel.setText("Number of elements"); GridDataFactory.swtDefaults().applyTo(nLabel); nField = new Text(selectorComposite, SWT.BORDER); nField.setText(Integer.toString(numberOfItems)); GridDataFactory.swtDefaults().hint(40, SWT.DEFAULT).applyTo(nField); selectorField.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { selectorIndex = selectorField.getSelectionIndex(); selectorComposite.setVisible(isSelectorCompositeVisible()); } }); selectorField.select(selectorIndex); selectorComposite.setVisible(isSelectorCompositeVisible()); // Condition new Label(content, SWT.NONE).setText("Condition"); conditionLabel = new Text(content, SWT.READ_ONLY); GridDataFactory.swtDefaults().span(2, 1).applyTo(conditionLabel); new Label(content, SWT.NONE); Composite conditionPanel = new Composite(content, SWT.NONE); GridDataFactory.swtDefaults().span(2, 1).applyTo(conditionPanel); GridLayoutFactory.swtDefaults().margins(0, 0).numColumns(2).applyTo(conditionPanel); Button conditionButton = new Button(conditionPanel, SWT.PUSH); conditionButton.setText("Edit..."); GridDataFactory.swtDefaults().span(1, 1).applyTo(conditionButton); removeConditionButton = new Button(conditionPanel, SWT.PUSH); removeConditionButton.setText("Remove"); GridDataFactory.swtDefaults().span(1, 1).applyTo(removeConditionButton); updateCondition(); conditionButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { ConditionDialog dialog = new ConditionDialog(getShell(), condition); if (dialog.open() == Window.OK) { try { condition = dialog.createCondition(); } catch (DatabaseException e1) { LOGGER.error("Creating a condition object failed", e1); } updateCondition(); } } }); removeConditionButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { condition = null; updateCondition(); } }); return content; } private void updateCondition() { if (condition != null) { removeConditionButton.setEnabled(true); try { conditionLabel.setText(ElementSelector.getExpression(Simantics.getSession(), condition.resource)); } catch (DatabaseException e) { LOGGER.error("Error getting expression string for " + condition.resource); } } else { conditionLabel.setText("No condition"); removeConditionButton.setEnabled(false); } content.layout(); } private boolean isDiagramFieldVisible() { return generatorIndex == 1; } private boolean isSelectorCompositeVisible() { return selectorIndex != 0; } 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 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 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(""); } } 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(""); } } 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, ""); } } 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(); // Create a negation Resource resource = Simantics.getSession().syncRequest(new WriteResult() { @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()); } } private Resource createCondition0() throws DatabaseException { switch (typeIndex) { case 0: return createPropertyCondition(); case 1: return createRegionCondition(); case 2: return createRouteCondition(); case 3: return createAggregateCondition(); default: throw new IllegalStateException("Invalid condition type code " + typeIndex); } } private Resource createPropertyCondition() throws DatabaseException { return Simantics.getSession().syncRequest(new WriteResult() { @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() { @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() { @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() { @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(); } } }