--- /dev/null
+package org.simantics.district.network.ui;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.function.Consumer;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IEditorPart;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.request.PossibleModel;
+import org.simantics.db.layer0.variable.RVI;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.diagram.DiagramHints;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.modeling.actions.NavigateToTarget;
+import org.simantics.scl.runtime.tuple.Tuple4;
+import org.simantics.ui.selection.WorkbenchSelectionUtils;
+import org.simantics.utils.threads.ThreadUtils;
+import org.simantics.utils.ui.ISelectionUtils;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.35.0
+ */
+public class DistrictNetworkUIUtil {
+
+ public static Resource getInputResource(ReadGraph graph, Object input) throws DatabaseException {
+ if (input instanceof Resource) {
+ return (Resource) input;
+ } else if (input instanceof Variable) {
+ return ((Variable) input).getPossibleRepresents(graph);
+ } else if (input instanceof ISelection) {
+ return ISelectionUtils.filterSingleSelection((ISelection) input, Resource.class);
+ } else {
+ return WorkbenchSelectionUtils.getPossibleResource(graph, input);
+ }
+ }
+
+ public static class GetInputResource extends UnaryRead<Object, Resource> {
+
+ public GetInputResource(Object input) {
+ super(input);
+ }
+
+ @Override
+ public Resource perform(ReadGraph graph) throws DatabaseException {
+ return getInputResource(graph, parameter);
+ }
+
+ }
+
+ public static class Input extends Tuple4 {
+ public Input(Resource model, Resource diagram, Resource element, RVI diagramCompositeRvi) {
+ super(model, diagram, element, diagramCompositeRvi);
+ }
+ public Resource model() {
+ return (Resource) get(0);
+ }
+ public Resource diagram() {
+ return (Resource) get(1);
+ }
+ public Resource element() {
+ return (Resource) get(2);
+ }
+ public RVI rvi() {
+ return (RVI) get(3);
+ }
+ }
+
+ public static class FindMappedDNElement extends UnaryRead<Object, Input> {
+
+ public FindMappedDNElement(Object parameter) {
+ super(parameter);
+ }
+
+ @Override
+ public Input perform(ReadGraph graph) throws DatabaseException {
+ Resource e = DistrictNetworkUtil.getMappedDNElement(graph,
+ DistrictNetworkUtil.getDiagramElement(graph,
+ getInputResource(graph, parameter)));
+ return e != null ? graph.syncRequest(new ElementToInput(e)) : null;
+ }
+
+ }
+
+ public static class FindMappedComponent extends UnaryRead<Object, Input> {
+
+ public FindMappedComponent(Object parameter) {
+ super(parameter);
+ }
+
+ @Override
+ public Input perform(ReadGraph graph) throws DatabaseException {
+ Resource e = DistrictNetworkUtil.getMappedElement(graph,
+ getInputResource(graph, parameter));
+ return e != null ? graph.syncRequest(new ElementToInput(e)) : null;
+ }
+
+ }
+
+ public static class ElementToInput extends UnaryRead<Resource, Input> {
+
+ public ElementToInput(Resource element) {
+ super(element);
+ }
+
+ @Override
+ public Input perform(ReadGraph graph) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ Resource diagram = graph.getPossibleObject(parameter, L0.PartOf);
+ if (diagram == null)
+ return null;
+
+ Resource model = graph.syncRequest(new PossibleModel(diagram));
+ if (model == null)
+ return null;
+
+ RVI rvi = getDiagramCompositeRvi(graph, diagram);
+ if (rvi == null)
+ return null;
+
+ return new Input(model, diagram, parameter, rvi);
+ }
+
+ private static RVI getDiagramCompositeRvi(ReadGraph graph, Resource diagram) throws DatabaseException {
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ Resource composite = graph.getPossibleObject(diagram, MOD.DiagramToComposite);
+ if (composite == null)
+ return null;
+ Variable v = Variables.getPossibleVariable(graph, composite);
+ return v != null ? v.getPossibleRVI(graph) : null;
+ }
+
+ }
+
+ public static Consumer<IEditorPart> editorActivationCallback(final Collection<? extends Object> selectedObjects) {
+ return part -> {
+ final ICanvasContext openedCanvas = (ICanvasContext) part.getAdapter(ICanvasContext.class);
+ assert openedCanvas != null;
+ // CanvasContext-wide denial of initial zoom-to-fit on diagram open.
+ openedCanvas.getDefaultHintContext().setHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT, Boolean.FALSE);
+ ThreadUtils.asyncExec(openedCanvas.getThreadAccess(),
+ NavigateToTarget.elementSelectorZoomer(openedCanvas, selectedObjects, false));
+ };
+ }
+
+ public static void openEditorWithSelection(String editorId, Input input, Object... selection) {
+ NavigateToTarget.editorActivator(
+ editorId,
+ input.diagram(),
+ input.model(),
+ input.rvi(),
+ DistrictNetworkUIUtil.editorActivationCallback(Arrays.asList(selection)))
+ .run();
+ }
+
+ public static void openDNDiagramEditorWithSelection(Input input, Object... selection) {
+ openEditorWithSelection(DistrictDiagramEditor.ID, input, selection);
+ }
+
+}