-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.diagram.handler;\r
-\r
-import java.awt.geom.Point2D;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.Iterator;\r
-import java.util.Set;\r
-\r
-import org.eclipse.jface.action.Action;\r
-import org.eclipse.jface.action.ActionContributionItem;\r
-import org.eclipse.jface.action.IContributionItem;\r
-import org.eclipse.swt.widgets.Menu;\r
-import org.eclipse.ui.IWorkbenchPart;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.request.IndexRoot;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.common.utils.OrderedSetUtils;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.diagram.content.ConnectionUtil;\r
-import org.simantics.diagram.content.EdgeResource;\r
-import org.simantics.diagram.flag.FlagUtil;\r
-import org.simantics.diagram.flag.Splitter;\r
-import org.simantics.diagram.internal.Activator;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.diagram.DiagramHints;\r
-import org.simantics.g2d.diagram.participant.Selection;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.scl.commands.Command;\r
-import org.simantics.scl.commands.Commands;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-import org.simantics.ui.contribution.DynamicMenuContribution;\r
-import org.simantics.utils.threads.ThreadUtils;\r
-import org.simantics.utils.ui.AdaptionUtils;\r
-import org.simantics.utils.ui.ExceptionUtils;\r
-import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
-\r
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-public class ConnectionSplitAndJoin extends DynamicMenuContribution {\r
-\r
- private static final IContributionItem[] NONE = {};\r
-\r
- private ICanvasContext canvas;\r
-\r
- @Override\r
- public void fill(Menu menu, int index) {\r
- // Need to grab active part here, we're still in the SWT thread.\r
- IWorkbenchPart activePart = WorkbenchUtils.getActiveWorkbenchPart();\r
- if (activePart == null)\r
- return;\r
- ICanvasContext ctx = (ICanvasContext) activePart.getAdapter(ICanvasContext.class);\r
- if (ctx == null)\r
- return;\r
-\r
- this.canvas = ctx;\r
- try {\r
- super.fill(menu, index);\r
- } finally {\r
- this.canvas = null;\r
- }\r
- }\r
-\r
- @Override\r
- protected IContributionItem[] getContributionItems(ReadGraph graph, Object[] selection) throws DatabaseException {\r
- // If selection contains:\r
- // a) only diagram-locally connected flags, that each are connected to something, allow joining of those flag into connections\r
- // b) a single connection edge element, allow splitting into a connected flag pair\r
-\r
- Collection<Resource> localConnectedFlags = Collections.emptyList();\r
- Resource routeGraphConnection = null;\r
- EdgeResource edge = null;\r
- if (selection.length == 1) {\r
- routeGraphConnection = getRouteGraphConnection(graph, selection[0]);\r
- if (routeGraphConnection == null) {\r
- edge = getEdge(graph, selection[0]);\r
- if (edge == null)\r
- localConnectedFlags = getLocalConnectedFlags(graph, selection);\r
- }\r
- } else {\r
- localConnectedFlags = getLocalConnectedFlags(graph, selection);\r
- }\r
-\r
- if (!localConnectedFlags.isEmpty()) {\r
- return new IContributionItem[] {\r
- new ActionContributionItem(new Join(graph.getSession(), canvas, localConnectedFlags))\r
- };\r
- } else if (edge != null) {\r
- Selection sel = canvas.getAtMostOneItemOfClass(Selection.class);\r
- if (sel == null)\r
- return NONE;\r
- Set<IElement> elems = sel.getSelection(0);\r
- if (elems.size() != 1)\r
- return NONE;\r
- IElement edgeElement = ConnectionUtil.getSingleEdge(elems.iterator().next());\r
- if (edgeElement == null)\r
- return NONE;\r
- Point2D canvasPosition = canvas.getHintStack().getHint(DiagramHints.POPUP_MENU_CANVAS_POSITION);\r
- if (canvasPosition == null)\r
- return NONE;\r
-\r
- return new IContributionItem[] {\r
- new ActionContributionItem(new Split(graph.getSession(), canvas, canvasPosition, edgeElement, edge))\r
- };\r
- } else if (routeGraphConnection != null) {\r
- Selection sel = canvas.getAtMostOneItemOfClass(Selection.class);\r
- if (sel == null)\r
- return NONE;\r
- Set<IElement> elems = sel.getSelection(0);\r
- if (elems.size() != 1)\r
- return NONE;\r
- Point2D canvasPosition = canvas.getHintStack().getHint(DiagramHints.POPUP_MENU_CANVAS_POSITION);\r
- if (canvasPosition == null)\r
- return NONE;\r
-\r
- return new IContributionItem[] {\r
- new ActionContributionItem(new SplitRouteGraph(graph.getSession(), canvas, canvasPosition, routeGraphConnection))\r
- };\r
- }\r
- return NONE;\r
- }\r
-\r
- private Resource getRouteGraphConnection(ReadGraph graph, Object object) throws DatabaseException {\r
- DiagramResource DIA = DiagramResource.getInstance(graph);\r
- Resource connection = AdaptionUtils.adaptToSingle(object, Resource.class);\r
- if (connection != null && graph.isInstanceOf(connection, DIA.RouteGraphConnection))\r
- return connection;\r
- return null;\r
- }\r
-\r
- private Collection<Resource> getLocalConnectedFlags(ReadGraph graph, Object[] selection) throws DatabaseException {\r
- DiagramResource DIA = DiagramResource.getInstance(graph);\r
- ArrayList<Resource> result = new ArrayList<Resource>(4);\r
- for (Object s : selection) {\r
- Resource r = AdaptionUtils.adaptToSingle(s, Resource.class);\r
- if (r == null || !graph.isInstanceOf(r, DIA.Flag))\r
- return Collections.emptyList();\r
- if (!isConnectedToSomething(graph, r))\r
- return Collections.emptyList();\r
- Collection<Resource> counterparts = FlagUtil.getCounterparts(graph, r);\r
- if (counterparts.isEmpty())\r
- return Collections.emptyList();\r
- Collection<Resource> flagDiagrams = OrderedSetUtils.getOwnerLists(graph, r, DIA.Diagram);\r
- for (Resource counterpart : counterparts) {\r
- boolean joinedWithinSingleDiagram = !Collections.disjoint(flagDiagrams,\r
- OrderedSetUtils.getOwnerLists(graph, counterpart, DIA.Diagram));\r
- if (!joinedWithinSingleDiagram)\r
- return Collections.emptyList();\r
- if (!isConnectedToSomething(graph, counterpart))\r
- return Collections.emptyList();\r
- }\r
- result.add(r);\r
- }\r
- return result;\r
- }\r
-\r
- private boolean isConnectedToSomething(ReadGraph graph, Resource flag) throws DatabaseException {\r
- DiagramResource DIA = DiagramResource.getInstance(graph);\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- for (Resource connector : graph.getObjects(flag, STR.IsConnectedTo)) {\r
- Resource cntr = graph.getPossibleObject(connector, DIA.AreConnected);\r
- Resource conn = ConnectionUtil.getConnection(graph, cntr);\r
- if (cntr == null || conn == null)\r
- return false;\r
- return true;\r
- }\r
- return false;\r
- }\r
-\r
- private EdgeResource getEdge(ReadGraph graph, Object object) throws DatabaseException {\r
- DiagramResource DIA = DiagramResource.getInstance(graph);\r
-\r
- Resource connection = null;\r
- EdgeResource edge = AdaptionUtils.adaptToSingle(object, EdgeResource.class);\r
- if (edge != null)\r
- //connection = ConnectionUtil.getConnection(graph, edge);\r
- return edge;\r
- else {\r
- connection = AdaptionUtils.adaptToSingle(object, Resource.class);\r
- }\r
-\r
- if (connection != null && graph.isInstanceOf(connection, DiagramResource.getInstance(graph).Connection)) {\r
- Collection<Resource> connectors = graph.getObjects(connection, DIA.HasConnector);\r
- Collection<Resource> branchPoints = graph.getObjects(connection, DIA.HasBranchPoint);\r
- if (branchPoints.isEmpty() && connectors.size() == 2) {\r
- Iterator<Resource> it = connectors.iterator();\r
- Resource connector1 = it.next();\r
- Resource connector2 = it.next();\r
- return new EdgeResource(connector1, connector2);\r
- }\r
- }\r
-\r
- return null;\r
- }\r
-\r
- public static abstract class Helper extends Action {\r
-\r
- protected final Session session;\r
- protected final ICanvasContext context;\r
-\r
- public Helper(String label, Session session, ICanvasContext context) {\r
- super(label);\r
- this.session = session;\r
- this.context = context;\r
- }\r
-\r
- @Override\r
- public void run() {\r
- try {\r
- session.syncRequest(new WriteRequest() {\r
- @Override\r
- public void perform(WriteGraph graph) throws DatabaseException {\r
- graph.markUndoPoint();\r
- performAction(graph);\r
- }\r
- });\r
- ThreadUtils.asyncExec(context.getThreadAccess(), new Runnable() {\r
- @Override\r
- public void run() {\r
- if (context.isDisposed())\r
- return;\r
- Selection selection = context.getAtMostOneItemOfClass(Selection.class);\r
- if (selection != null) {\r
- // This prevents workbench selection from being left over.\r
- // Also prevents scene graph crap from being left on the screen.\r
- selection.clear(0);\r
- }\r
- }\r
- });\r
- } catch (DatabaseException e) {\r
- ExceptionUtils.logError(e);\r
- }\r
- }\r
-\r
- /**\r
- * @param graph\r
- */\r
- protected abstract void performAction(WriteGraph graph) throws DatabaseException;\r
-\r
- }\r
-\r
- public static class Split extends Helper {\r
- private final Point2D splitCanvasPos;\r
- private final IElement edgeElement;\r
- private final EdgeResource edge;\r
-\r
- public Split(Session session, ICanvasContext context, Point2D splitCanvasPos, IElement edgeElement, EdgeResource edge) {\r
- super("Split Connection", session, context);\r
- setImageDescriptor(Activator.LINK_BREAK_ICON);\r
- this.splitCanvasPos = splitCanvasPos;\r
- this.edgeElement = edgeElement;\r
- this.edge = edge;\r
- }\r
-\r
- @Override\r
- protected void performAction(WriteGraph graph) throws DatabaseException {\r
- new Splitter(graph).split(graph, edgeElement, edge, splitCanvasPos);\r
- }\r
- }\r
-\r
- public static class SplitRouteGraph extends Helper {\r
- private final Point2D splitCanvasPos;\r
- private final Resource connection;\r
-\r
- public SplitRouteGraph(Session session, ICanvasContext context, Point2D splitCanvasPos, Resource connection) {\r
- super("Split Connection", session, context);\r
- setImageDescriptor(Activator.LINK_BREAK_ICON);\r
- this.splitCanvasPos = splitCanvasPos;\r
- this.connection = connection;\r
- }\r
-\r
- @Override\r
- protected void performAction(WriteGraph graph) throws DatabaseException {\r
- Command command = Commands.get(graph, "Simantics/Diagram/splitConnection");\r
- command.execute(graph, graph.syncRequest(new IndexRoot(connection)),\r
- connection, splitCanvasPos.getX(), splitCanvasPos.getY());\r
- }\r
- }\r
-\r
- public static class Join extends Helper {\r
- private final Collection<Resource> flags;\r
-\r
- public Join(Session session, ICanvasContext context, Collection<Resource> flags) {\r
- super("Join Flags", session, context);\r
- setImageDescriptor(Activator.LINK_ICON);\r
- this.flags = flags;\r
- }\r
-\r
- @Override\r
- protected void performAction(WriteGraph graph) throws DatabaseException {\r
- Command command = Commands.get(graph, "Simantics/Diagram/joinFlagsLocal");\r
- command.execute(graph, graph.syncRequest(new IndexRoot(flags.iterator().next())), flags);\r
- }\r
- }\r
-\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.diagram.handler;
+
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.ui.IWorkbenchPart;
+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.WriteRequest;
+import org.simantics.db.common.utils.OrderedSetUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.diagram.content.ConnectionUtil;
+import org.simantics.diagram.content.EdgeResource;
+import org.simantics.diagram.flag.FlagUtil;
+import org.simantics.diagram.flag.Splitter;
+import org.simantics.diagram.internal.Activator;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.diagram.DiagramHints;
+import org.simantics.g2d.diagram.participant.Selection;
+import org.simantics.g2d.element.IElement;
+import org.simantics.scl.commands.Command;
+import org.simantics.scl.commands.Commands;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.ui.contribution.DynamicMenuContribution;
+import org.simantics.utils.threads.ThreadUtils;
+import org.simantics.utils.ui.AdaptionUtils;
+import org.simantics.utils.ui.ExceptionUtils;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class ConnectionSplitAndJoin extends DynamicMenuContribution {
+
+ private static final IContributionItem[] NONE = {};
+
+ private ICanvasContext canvas;
+
+ @Override
+ public void fill(Menu menu, int index) {
+ // Need to grab active part here, we're still in the SWT thread.
+ IWorkbenchPart activePart = WorkbenchUtils.getActiveWorkbenchPart();
+ if (activePart == null)
+ return;
+ ICanvasContext ctx = (ICanvasContext) activePart.getAdapter(ICanvasContext.class);
+ if (ctx == null)
+ return;
+
+ this.canvas = ctx;
+ try {
+ super.fill(menu, index);
+ } finally {
+ this.canvas = null;
+ }
+ }
+
+ @Override
+ protected IContributionItem[] getContributionItems(ReadGraph graph, Object[] selection) throws DatabaseException {
+ // If selection contains:
+ // a) only diagram-locally connected flags, that each are connected to something, allow joining of those flag into connections
+ // b) a single connection edge element, allow splitting into a connected flag pair
+
+ Collection<Resource> localConnectedFlags = Collections.emptyList();
+ Resource routeGraphConnection = null;
+ EdgeResource edge = null;
+ if (selection.length == 1) {
+ routeGraphConnection = getRouteGraphConnection(graph, selection[0]);
+ if (routeGraphConnection == null) {
+ edge = getEdge(graph, selection[0]);
+ if (edge == null)
+ localConnectedFlags = getLocalConnectedFlags(graph, selection);
+ }
+ } else {
+ localConnectedFlags = getLocalConnectedFlags(graph, selection);
+ }
+
+ if (!localConnectedFlags.isEmpty()) {
+ return new IContributionItem[] {
+ new ActionContributionItem(new Join(graph.getSession(), canvas, localConnectedFlags))
+ };
+ } else if (edge != null) {
+ Selection sel = canvas.getAtMostOneItemOfClass(Selection.class);
+ if (sel == null)
+ return NONE;
+ Set<IElement> elems = sel.getSelection(0);
+ if (elems.size() != 1)
+ return NONE;
+ IElement edgeElement = ConnectionUtil.getSingleEdge(elems.iterator().next());
+ if (edgeElement == null)
+ return NONE;
+ Point2D canvasPosition = canvas.getHintStack().getHint(DiagramHints.POPUP_MENU_CANVAS_POSITION);
+ if (canvasPosition == null)
+ return NONE;
+
+ return new IContributionItem[] {
+ new ActionContributionItem(new Split(graph.getSession(), canvas, canvasPosition, edgeElement, edge))
+ };
+ } else if (routeGraphConnection != null) {
+ Selection sel = canvas.getAtMostOneItemOfClass(Selection.class);
+ if (sel == null)
+ return NONE;
+ Set<IElement> elems = sel.getSelection(0);
+ if (elems.size() != 1)
+ return NONE;
+ Point2D canvasPosition = canvas.getHintStack().getHint(DiagramHints.POPUP_MENU_CANVAS_POSITION);
+ if (canvasPosition == null)
+ return NONE;
+
+ return new IContributionItem[] {
+ new ActionContributionItem(new SplitRouteGraph(graph.getSession(), canvas, canvasPosition, routeGraphConnection))
+ };
+ }
+ return NONE;
+ }
+
+ private Resource getRouteGraphConnection(ReadGraph graph, Object object) throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ Resource connection = AdaptionUtils.adaptToSingle(object, Resource.class);
+ if (connection != null && graph.isInstanceOf(connection, DIA.RouteGraphConnection))
+ return connection;
+ return null;
+ }
+
+ private Collection<Resource> getLocalConnectedFlags(ReadGraph graph, Object[] selection) throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ ArrayList<Resource> result = new ArrayList<Resource>(4);
+ for (Object s : selection) {
+ Resource r = AdaptionUtils.adaptToSingle(s, Resource.class);
+ if (r == null || !graph.isInstanceOf(r, DIA.Flag))
+ return Collections.emptyList();
+ if (!isConnectedToSomething(graph, r))
+ return Collections.emptyList();
+ Collection<Resource> counterparts = FlagUtil.getCounterparts(graph, r);
+ if (counterparts.isEmpty())
+ return Collections.emptyList();
+ Collection<Resource> flagDiagrams = OrderedSetUtils.getOwnerLists(graph, r, DIA.Diagram);
+ for (Resource counterpart : counterparts) {
+ boolean joinedWithinSingleDiagram = !Collections.disjoint(flagDiagrams,
+ OrderedSetUtils.getOwnerLists(graph, counterpart, DIA.Diagram));
+ if (!joinedWithinSingleDiagram)
+ return Collections.emptyList();
+ if (!isConnectedToSomething(graph, counterpart))
+ return Collections.emptyList();
+ }
+ result.add(r);
+ }
+ return result;
+ }
+
+ private boolean isConnectedToSomething(ReadGraph graph, Resource flag) throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ for (Resource connector : graph.getObjects(flag, STR.IsConnectedTo)) {
+ Resource cntr = graph.getPossibleObject(connector, DIA.AreConnected);
+ Resource conn = ConnectionUtil.getConnection(graph, cntr);
+ if (cntr == null || conn == null)
+ return false;
+ return true;
+ }
+ return false;
+ }
+
+ private EdgeResource getEdge(ReadGraph graph, Object object) throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+
+ Resource connection = null;
+ EdgeResource edge = AdaptionUtils.adaptToSingle(object, EdgeResource.class);
+ if (edge != null)
+ //connection = ConnectionUtil.getConnection(graph, edge);
+ return edge;
+ else {
+ connection = AdaptionUtils.adaptToSingle(object, Resource.class);
+ }
+
+ if (connection != null && graph.isInstanceOf(connection, DiagramResource.getInstance(graph).Connection)) {
+ Collection<Resource> connectors = graph.getObjects(connection, DIA.HasConnector);
+ Collection<Resource> branchPoints = graph.getObjects(connection, DIA.HasBranchPoint);
+ if (branchPoints.isEmpty() && connectors.size() == 2) {
+ Iterator<Resource> it = connectors.iterator();
+ Resource connector1 = it.next();
+ Resource connector2 = it.next();
+ return new EdgeResource(connector1, connector2);
+ }
+ }
+
+ return null;
+ }
+
+ public static abstract class Helper extends Action {
+
+ protected final Session session;
+ protected final ICanvasContext context;
+
+ public Helper(String label, Session session, ICanvasContext context) {
+ super(label);
+ this.session = session;
+ this.context = context;
+ }
+
+ @Override
+ public void run() {
+ try {
+ session.syncRequest(new WriteRequest() {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ graph.markUndoPoint();
+ performAction(graph);
+ }
+ });
+ ThreadUtils.asyncExec(context.getThreadAccess(), new Runnable() {
+ @Override
+ public void run() {
+ if (context.isDisposed())
+ return;
+ Selection selection = context.getAtMostOneItemOfClass(Selection.class);
+ if (selection != null) {
+ // This prevents workbench selection from being left over.
+ // Also prevents scene graph crap from being left on the screen.
+ selection.clear(0);
+ }
+ }
+ });
+ } catch (DatabaseException e) {
+ ExceptionUtils.logError(e);
+ }
+ }
+
+ /**
+ * @param graph
+ */
+ protected abstract void performAction(WriteGraph graph) throws DatabaseException;
+
+ }
+
+ public static class Split extends Helper {
+ private final Point2D splitCanvasPos;
+ private final IElement edgeElement;
+ private final EdgeResource edge;
+
+ public Split(Session session, ICanvasContext context, Point2D splitCanvasPos, IElement edgeElement, EdgeResource edge) {
+ super("Split Connection", session, context);
+ setImageDescriptor(Activator.LINK_BREAK_ICON);
+ this.splitCanvasPos = splitCanvasPos;
+ this.edgeElement = edgeElement;
+ this.edge = edge;
+ }
+
+ @Override
+ protected void performAction(WriteGraph graph) throws DatabaseException {
+ new Splitter(graph).split(graph, edgeElement, edge, splitCanvasPos);
+ }
+ }
+
+ public static class SplitRouteGraph extends Helper {
+ private final Point2D splitCanvasPos;
+ private final Resource connection;
+
+ public SplitRouteGraph(Session session, ICanvasContext context, Point2D splitCanvasPos, Resource connection) {
+ super("Split Connection", session, context);
+ setImageDescriptor(Activator.LINK_BREAK_ICON);
+ this.splitCanvasPos = splitCanvasPos;
+ this.connection = connection;
+ }
+
+ @Override
+ protected void performAction(WriteGraph graph) throws DatabaseException {
+ Command command = Commands.get(graph, "Simantics/Diagram/splitConnection");
+ command.execute(graph, graph.syncRequest(new IndexRoot(connection)),
+ connection, splitCanvasPos.getX(), splitCanvasPos.getY());
+ }
+ }
+
+ public static class Join extends Helper {
+ private final Collection<Resource> flags;
+
+ public Join(Session session, ICanvasContext context, Collection<Resource> flags) {
+ super("Join Flags", session, context);
+ setImageDescriptor(Activator.LINK_ICON);
+ this.flags = flags;
+ }
+
+ @Override
+ protected void performAction(WriteGraph graph) throws DatabaseException {
+ Command command = Commands.get(graph, "Simantics/Diagram/joinFlagsLocal");
+ command.execute(graph, graph.syncRequest(new IndexRoot(flags.iterator().next())), flags);
+ }
+ }
+
}
\ No newline at end of file