X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.district.network.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fnetwork%2Fui%2Ffunction%2FFunctions.java;fp=org.simantics.district.network.ui%2Fsrc%2Forg%2Fsimantics%2Fdistrict%2Fnetwork%2Fui%2Ffunction%2FFunctions.java;h=016a1420dba6a4a8b5588c4e8e4a7735633f2ae2;hb=16ee01dc5a40981c58fd5b478b89552e5814e8bb;hp=0000000000000000000000000000000000000000;hpb=9dace20146d19dd0541480a80fd289de45b6cfc8;p=simantics%2Fdistrict.git diff --git a/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java new file mode 100644 index 00000000..016a1420 --- /dev/null +++ b/org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java @@ -0,0 +1,329 @@ +package org.simantics.district.network.ui.function; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.SelectionStatusDialog; +import org.simantics.NameLabelUtil; +import org.simantics.Simantics; +import org.simantics.browsing.ui.common.modifiers.EnumeratedValue; +import org.simantics.browsing.ui.common.modifiers.Enumeration; +import org.simantics.browsing.ui.graph.impl.GraphEnumerationModifier; +import org.simantics.databoard.Bindings; +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.IndexRoot; +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.variable.Variable; +import org.simantics.db.layer0.variable.Variables.Role; +import org.simantics.db.procedure.Procedure; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.district.network.ontology.DistrictNetworkResource; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.ModelingUtils; +import org.simantics.modeling.adapters.NewCompositeActionFactory; +import org.simantics.modeling.typicals.TypicalUtil; +import org.simantics.scl.reflection.annotations.SCLValue; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.ui.workbench.action.DefaultActions; +import org.simantics.utils.ui.SWTUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Functions { + + private static final Logger LOGGER = LoggerFactory.getLogger(Functions.class); + + private Functions() { + } + + private static class HasMappingEnumerationModifier extends GraphEnumerationModifier { + + public HasMappingEnumerationModifier(Session session, Resource subject, Resource relation, Enumeration enumeration, Resource value) { + super(session, subject, relation, enumeration, value); + } + + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> b") + public static Object defaultEdgeMappingModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException { + Resource diagram = resolveElement(graph, context); + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + return baseMappingModifier(graph, diagram, DN.EdgeDefaultMapping, DN.Mapping_EdgeMapping, context); + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> b") + public static Object defaultVertexMappingModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException { + System.out.println(graph.getURI(resource)); + System.out.println(context.getURI(graph)); + + Resource diagram = resolveElement(graph, context); + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + return baseMappingModifier(graph, diagram, DN.VertexDefaultMapping, DN.Mapping_VertexMapping, context); + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> b") + public static Object mappingModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException { + + Resource element = resolveElement(graph, context); + Resource mappingType = resolveMappingType(graph, element); + return baseMappingModifier(graph, element, DistrictNetworkResource.getInstance(graph).HasMapping, mappingType, context); + } + + public static Map getVertexMappings(ReadGraph graph, Resource resource) throws DatabaseException { + return getNetworkMappingsByType(graph, resource , DistrictNetworkResource.getInstance(graph).Mapping_VertexMapping); + } + + public static Map getEdgeMappings(ReadGraph graph, Resource resource) throws DatabaseException { + return getNetworkMappingsByType(graph, resource , DistrictNetworkResource.getInstance(graph).Mapping_EdgeMapping); + } + + public static Map getNetworkMappingsByType(ReadGraph graph, Resource element, Resource mappingType) throws DatabaseException { + Resource indexRoot = graph.sync(new IndexRoot(element)); + List mappings = ModelingUtils.searchByType(graph, indexRoot, mappingType); + Map result = new HashMap<>(mappings.size()); + Layer0 L0 = Layer0.getInstance(graph); + mappings.forEach(mapping -> { + try { + String name = graph.getRelatedValue2(mapping, L0.HasName); + result.put(name, mapping); + } catch (DatabaseException e) { + e.printStackTrace(); + } + }); + return result; + } + + private static Object baseMappingModifier(ReadGraph graph, Resource element, Resource property, Resource mappingType, Variable context) throws DatabaseException { + Resource indexRoot = graph.sync(new IndexRoot(element)); + List mappings = ModelingUtils.searchByType(graph, indexRoot, mappingType); + Enumeration enums = Enumeration + .make(mappings.stream().map(m -> createEnumeratedValue(graph, m)).collect(Collectors.toList())); + + Resource currentMapping = graph.getSingleObject(element, property); + + return new HasMappingEnumerationModifier(Simantics.getSession(), element, property, enums, currentMapping); + } + + private static Resource resolveMappingType(ReadGraph graph, Resource element) throws DatabaseException { + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + if (graph.isInstanceOf(element, DN.Edge)) + return DN.Mapping_EdgeMapping; + else if (graph.isInstanceOf(element, DN.Vertex)) + return DN.Mapping_VertexMapping; + throw new IllegalStateException("No mapping type found for element " + element + " : " + graph.getPossibleURI(element)); + } + + private static Resource resolveElement(ReadGraph graph, Variable variable) throws DatabaseException { + Role role = variable.getPossibleRole(graph); + if (role.equals(Role.PROPERTY)) + return resolveElement(graph, variable.getParent(graph)); + else + return variable.getRepresents(graph); + } + + private static EnumeratedValue createEnumeratedValue(ReadGraph graph, Resource resource) { + try { + String label = NameLabelUtil.modalName(graph, resource); + return new EnumeratedValue(label, resource); + } catch (DatabaseException e) { + throw new RuntimeDatabaseException(e); + } + } + + @SCLValue(type = "ReadGraph -> Resource -> a -> b") + public static Object enumerationValues(ReadGraph graph, Resource resource, Object context) throws DatabaseException { + Variable var = (Variable) context; + System.out.println(graph.getURI(resource)); + System.out.println(var.getURI(graph)); + return Collections.emptyList(); + } + + @SCLValue(type = "ReadGraph -> Resource -> a -> b") + public static Object convertToValue(ReadGraph graph, Resource resource, Object context) throws DatabaseException { + return graph.getRelatedValue2(resource, Layer0.getInstance(graph).HasName, Bindings.STRING); +// return null; + } + + + @SCLValue(type = "Resource -> String -> Resource -> Resource") + public static Resource compositeInstantiator(final Resource compositeType, final String defaultName, final Resource target) throws DatabaseException { + + return TypicalUtil.syncExec(procedure -> { + if (!SWTUtils.asyncExec(PlatformUI.getWorkbench().getDisplay(), () -> { + try { + queryInitialValuesAndCreateComposite(compositeType, target, defaultName, procedure); + } catch (Throwable t) { + procedure.exception(t); + } + })) { + procedure.execute(null); + } + }); + } + + private static class DefaultMappingsDialog extends SelectionStatusDialog { + + private Combo vertexMappingCombo; + private Combo edgeMappingCombo; + private Combo crsCombo; + private Composite composite; + + private Resource configuration; + private Map vertexMappings = new HashMap<>(); + private Map edgeMappings = new HashMap<>(); + + private Resource defaultVertexMapping; + private Resource defaultEdgeMapping; + + protected DefaultMappingsDialog(Shell parentShell, Resource configuration) { + super(parentShell); + this.configuration = configuration; + setTitle("Select mappings for new DN diagram"); + } + + public Resource getDefaultVertexMapping() { + return defaultVertexMapping; + } + + public Resource getDefaultEdgeMapping() { + return defaultEdgeMapping; + } + + @Override + protected Control createDialogArea(Composite parent) { + composite = (Composite) super.createDialogArea(parent); + + createMappingsGroup(composite); + createCRSSettingsGroup(composite); + + // compute default values + Simantics.getSession().asyncRequest(new ReadRequest() { + + @Override + public void run(ReadGraph graph) throws DatabaseException { + + vertexMappings = getVertexMappings(graph, configuration); + edgeMappings = getEdgeMappings(graph, configuration); + + composite.getDisplay().asyncExec(() -> { + + vertexMappingCombo.setItems(vertexMappings.keySet().toArray(new String[vertexMappings.size()])); + edgeMappingCombo.setItems(edgeMappings.keySet().toArray(new String[edgeMappings.size()])); + vertexMappingCombo.select(0); + edgeMappingCombo.select(0); + }); + + } + }); + return composite; + } + + private void createMappingsGroup(Composite parent) { + Group group= new Group(parent, SWT.NONE); + group.setFont(parent.getFont()); + group.setText("Default mappings"); + GridDataFactory.fillDefaults().grab(true, false).applyTo(group); + group.setLayout(new GridLayout(1, false)); + + Composite cmposite = new Composite(group, SWT.NONE); + cmposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + cmposite.setLayout(new GridLayout(2, false)); + + Label vertexMappingLabel = new Label(cmposite, SWT.NONE); + vertexMappingLabel.setText("Default vertex mapping"); + + vertexMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(vertexMappingCombo); + + Label edgeMappingLabel = new Label(cmposite, SWT.NONE); + edgeMappingLabel.setText("Default edge mapping"); + + edgeMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER); + GridDataFactory.fillDefaults().grab(true, false).applyTo(edgeMappingCombo); + } + + private void createCRSSettingsGroup(Composite parent) { + Group group= new Group(parent, SWT.NONE); + group.setFont(parent.getFont()); + group.setText("CRS settings"); + GridDataFactory.fillDefaults().grab(true, false).applyTo(group); + group.setLayout(new GridLayout(1, false)); + + Composite cmposite = new Composite(group, SWT.NONE); + cmposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); + cmposite.setLayout(new GridLayout(2, false)); + + Label vertexMappingLabel = new Label(cmposite, SWT.NONE); + vertexMappingLabel.setText("Default CRS"); + + crsCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER); + GridData textData = new GridData(SWT.FILL, SWT.CENTER, true, false); + crsCombo.setLayoutData(textData); + } + + + @Override + protected void computeResult() { + defaultVertexMapping = vertexMappings.get(vertexMappingCombo.getItem(vertexMappingCombo.getSelectionIndex())); + defaultEdgeMapping = edgeMappings.get(edgeMappingCombo.getItem(edgeMappingCombo.getSelectionIndex())); + } + + } + + private static void queryInitialValuesAndCreateComposite(final Resource compositeType, final Resource target, + String defaultName, final Procedure procedure) { + DefaultMappingsDialog dialog = new DefaultMappingsDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), target); + + if (dialog.open() != Dialog.OK) { + procedure.execute(null); + return; + } + Simantics.getSession().asyncRequest( + NewCompositeActionFactory.createCompositeRequest(target, defaultName, compositeType), + new Procedure() { + @Override + public void execute(Resource composite) { + Simantics.getSession().asyncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + Resource diagram = graph.getSingleObject(composite, ModelingResources.getInstance(graph).CompositeToDiagram); + graph.claim(diagram, DN.EdgeDefaultMapping, dialog.getDefaultEdgeMapping()); + graph.claim(diagram, DN.VertexDefaultMapping, dialog.getDefaultVertexMapping()); + } + }); + DefaultActions.asyncPerformDefaultAction(Simantics.getSession(), composite, false, false, true); + procedure.execute(composite); + } + + @Override + public void exception(Throwable t) { + LOGGER.error("Failed to create composite, see exception for details.", t); + procedure.exception(t); + } + }); + } +}