]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram/src/org/simantics/diagram/handler/ConnectionRoutingMenuContribution.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / handler / ConnectionRoutingMenuContribution.java
index ce2dbbb1959f10e49e24e8a145176a10581f80a1..7f98894edd4b71be512e2e200e3770877ba5f2d9 100644 (file)
-/*******************************************************************************\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.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.Comparator;\r
-import java.util.List;\r
-\r
-import org.eclipse.jface.action.Action;\r
-import org.eclipse.jface.action.ContributionItem;\r
-import org.eclipse.jface.action.IAction;\r
-import org.eclipse.jface.action.IContributionItem;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.events.SelectionEvent;\r
-import org.eclipse.swt.events.SelectionListener;\r
-import org.eclipse.swt.widgets.Menu;\r
-import org.eclipse.swt.widgets.MenuItem;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.Statement;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.CommentMetadata;\r
-import org.simantics.db.common.request.IndexRoot;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.diagram.content.ConnectionUtil;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.modeling.ModelingResources;\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.datastructures.Callback;\r
-import org.simantics.utils.ui.AdaptionUtils;\r
-import org.simantics.utils.ui.ExceptionUtils;\r
-\r
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-public class ConnectionRoutingMenuContribution extends DynamicMenuContribution {\r
-       \r
-\r
-    private static final IContributionItem[] NONE = {};\r
-\r
-    @Override\r
-    protected IContributionItem[] getContributionItems(ReadGraph graph, Object[] selection) throws DatabaseException {\r
-        ArrayList<IContributionItem> result = new ArrayList<IContributionItem>(4);\r
-\r
-        result.addAll(getConnectionRoutingItems(graph, selection));\r
-        result.addAll(getAttachedConnectionRoutingItems(graph, selection));\r
-\r
-        return result.toArray(NONE);\r
-    }\r
-\r
-    public static Collection<IContributionItem> getConnectionRoutingItems(ReadGraph graph, Object[] selection) throws DatabaseException {\r
-        Layer0 l0 = Layer0.getInstance(graph);\r
-        DiagramResource dr = DiagramResource.getInstance(graph);\r
-\r
-        final Collection<Resource> routings = graph.getObjects(dr.Routing, l0.SuperrelationOf);\r
-        if (routings.size() == 0)\r
-            return Collections.emptyList();\r
-\r
-        final List<Resource> connections = new ArrayList<Resource>();\r
-        for (Object s : selection) {\r
-            Resource connection = AdaptionUtils.adaptToSingle(s, Resource.class);\r
-            if (connection == null)\r
-                return Collections.emptyList();\r
-            if (!graph.isInstanceOf(connection, dr.Connection))\r
-                return Collections.emptyList();\r
-            // Route graph connection routing is not selected per-connection, but per-terminal.\r
-            if (graph.isInstanceOf(connection, dr.RouteGraphConnection))\r
-                return Collections.emptyList();\r
-            connections.add(connection);\r
-        }\r
-        if (connections.isEmpty())\r
-            return Collections.emptyList();\r
-\r
-        // See if all connections have a common routing.\r
-        Resource currentRoute = null;\r
-        for (Resource connection : connections) {\r
-            Statement currentRouting = graph.getPossibleStatement(connection, dr.Routing);\r
-            if (currentRouting != null) {\r
-                Resource route = currentRouting.getPredicate();\r
-                if (currentRoute == null)\r
-                    currentRoute = route;\r
-                else if (!currentRoute.equals(route)) {\r
-                    currentRoute = null;\r
-                    break;\r
-                }\r
-            }\r
-        }\r
-\r
-        final List<SetRoutingAction> actions = new ArrayList<SetRoutingAction>();\r
-        for (Resource routing : routings) {\r
-            String text = graph.adapt(routing, String.class);\r
-            SetRoutingAction action = new SetRoutingAction(graph.getSession(), connections, routing, text);\r
-            if (routing.equals(currentRoute))\r
-                action.setChecked(true);\r
-            actions.add(action);\r
-        }\r
-\r
-\r
-        sort(actions);\r
-\r
-        return Collections.<IContributionItem>singleton(\r
-                new ContributionItem() {\r
-                    @Override\r
-                    public void fill(Menu menu, int index) {\r
-                        MenuItem openWith = new MenuItem(menu, SWT.CASCADE, index);\r
-                        openWith.setText("Connection Routing");\r
-                        Menu subMenu = new Menu(menu);\r
-                        openWith.setMenu(subMenu);\r
-\r
-                        for (SetRoutingAction a : actions) {\r
-                            MenuItem item = new MenuItem(subMenu, SWT.CHECK);\r
-                            item.setText(a.getText());\r
-                            item.addSelectionListener(a);\r
-                            item.setSelection(a.isChecked());\r
-                        }\r
-                    }\r
-                }\r
-        );\r
-    }\r
-\r
-    public static Collection<IContributionItem> getAttachedConnectionRoutingItems(ReadGraph graph, Object[] selection) throws DatabaseException {\r
-        Layer0 l0 = Layer0.getInstance(graph);\r
-        DiagramResource dr = DiagramResource.getInstance(graph);\r
-        StructuralResource2 sr = StructuralResource2.getInstance(graph);\r
-        ModelingResources MOD = ModelingResources.getInstance(graph);\r
-        // HACK\r
-        Resource ReferenceProvider = graph.getPossibleResource("http://www.apros.fi/Apros-6.1/ReferenceProvider");\r
-        // Just continuing to do stupid things as above ;)\r
-        Resource connectionType = graph.getPossibleResource("http://www.simantics.org/Kcleco-5.0/FlowConnection");\r
-      \r
-\r
-        final Collection<Resource> routings = graph.getObjects(dr.Routing, l0.SuperrelationOf);\r
-        if (routings.size() == 0)\r
-            return Collections.emptyList();\r
-\r
-        final List<Resource> connections = new ArrayList<Resource>();\r
-\r
-        // For route graph connections\r
-        final List<Resource> connectors = new ArrayList<Resource>();\r
-        boolean directRoutings = false;\r
-        boolean straightRoutings = false;\r
-\r
-        ArrayList<Resource> elements = new ArrayList<Resource>(); \r
-        for (Object s : selection) {\r
-            Resource element = AdaptionUtils.adaptToSingle(s, Resource.class);\r
-            if (element == null)\r
-                return Collections.emptyList();\r
-            if (!graph.isInstanceOf(element, dr.Element) || graph.isInstanceOf(element, dr.Connection))\r
-                return Collections.emptyList();\r
-\r
-            elements.add(element);\r
-            \r
-            for(Statement stat : graph.getStatements(element, sr.IsConnectedTo)) {\r
-                Resource diagramRelation = stat.getPredicate();\r
-                Resource connectionRelation = graph.getPossibleObject(diagramRelation, MOD.DiagramConnectionRelationToConnectionRelation);\r
-                if(connectionRelation == null)\r
-                    continue;\r
-                // FIXME HACK\r
-                if(ReferenceProvider != null && !graph.isInstanceOf(connectionRelation, ReferenceProvider))\r
-                    continue;\r
-                Resource connector = stat.getObject();\r
-\r
-                Resource connection = ConnectionUtil.tryGetConnection(graph, connector);\r
-                if (connection != null) {\r
-                    if (graph.isInstanceOf(connection, dr.RouteGraphConnection)) {\r
-                       if (connectionType != null && graph.isInstanceOf(connection, connectionType))   \r
-                            continue;\r
-                        connectors.add(connector);\r
-                        boolean direct = Boolean.TRUE.equals( graph.getPossibleRelatedValue2(connector, dr.Connector_straight, Bindings.BOOLEAN) );\r
-                        directRoutings |= direct;\r
-                        straightRoutings |= !direct;\r
-                    } else {\r
-                        connections.add(connection);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        if (connectors.isEmpty() && connections.isEmpty())\r
-            return Collections.emptyList();\r
-\r
-        // See if all connections have a common routing.\r
-        Resource currentRoute = null;\r
-        for (Resource connection : connections) {\r
-            Statement currentRouting = graph.getPossibleStatement(connection, dr.Routing);\r
-            if (currentRouting != null) {\r
-                Resource route = currentRouting.getPredicate();\r
-                if (currentRoute == null)\r
-                    currentRoute = route;\r
-                else if (!currentRoute.equals(route)) {\r
-                    currentRoute = null;\r
-                    break;\r
-                }\r
-            }\r
-        }\r
-\r
-        final List<SelectionListenerAction> actions = new ArrayList<SelectionListenerAction>();\r
-\r
-        if (!connections.isEmpty()) {\r
-            // Handle old style connections and their routing\r
-            for (Resource routing : routings) {\r
-                String text = graph.adapt(routing, String.class);\r
-                SetRoutingAction action = new SetRoutingAction(graph.getSession(), connections, routing, text);\r
-                if (routing.equals(currentRoute)) {\r
-                    action.setChecked(true);\r
-                }\r
-                actions.add(action);\r
-            }\r
-        }\r
-        if (!connectors.isEmpty()) {\r
-            // Handle route graph connections\r
-            SelectionListenerAction direct = new SetAttachedRouteGraphRoutingAction(graph.getSession(), elements, true, "Direct");\r
-            SelectionListenerAction straight = new SetAttachedRouteGraphRoutingAction(graph.getSession(), elements, false, "Straight-angled");\r
-            direct.setChecked(directRoutings);\r
-            straight.setChecked(straightRoutings);\r
-            actions.add(direct);\r
-            actions.add(straight);\r
-        }\r
-\r
-        sort(actions);\r
-\r
-        return Collections.<IContributionItem>singleton(\r
-                new ContributionItem() {\r
-                    @Override\r
-                    public void fill(Menu menu, int index) {\r
-                        MenuItem openWith = new MenuItem(menu, SWT.CASCADE, index);\r
-                        openWith.setText("Attached Connection Routing");\r
-                        Menu subMenu = new Menu(menu);\r
-                        openWith.setMenu(subMenu);\r
-\r
-                        for (SelectionListenerAction a : actions) {\r
-                            MenuItem item = new MenuItem(subMenu, SWT.CHECK);\r
-                            item.setText(a.getText());\r
-                            item.addSelectionListener(a);\r
-                            item.setSelection(a.isChecked());\r
-                        }\r
-                    }\r
-                }\r
-        );\r
-    }\r
-\r
-    private static void sort(List<? extends IAction> actions) {\r
-        // Sort the open with actions in string order.\r
-        Collections.sort(actions, new Comparator<IAction>() {\r
-            @Override\r
-            public int compare(IAction o1, IAction o2) {\r
-                return o1.getText().compareToIgnoreCase(o2.getText());\r
-            }\r
-        });\r
-    }\r
-\r
-    static abstract class SelectionListenerAction extends Action implements SelectionListener {\r
-        public SelectionListenerAction(String text) {\r
-            super(text);\r
-        }\r
-    }\r
-\r
-    static class SetRoutingAction extends SelectionListenerAction {\r
-\r
-        Session session;\r
-        Collection<Resource> connections;\r
-        Resource routingTag;\r
-\r
-        public SetRoutingAction(Session session, Collection<Resource> connections, Resource routingTag, String text) {\r
-            super(text);\r
-            this.session = session;\r
-            this.connections = connections;\r
-            this.routingTag = routingTag;\r
-        }\r
-\r
-        @Override\r
-        public void run() {\r
-            session.asyncRequest(new WriteRequest() {\r
-                @Override\r
-                public void perform(WriteGraph graph) throws DatabaseException {\r
-                    DiagramResource dr = DiagramResource.getInstance(graph);\r
-                    for (Resource connection : connections) {\r
-                        graph.deny(connection, dr.Routing);\r
-                        graph.claim(connection, routingTag, connection);\r
-                    }\r
-                }\r
-            }, new Callback<DatabaseException>() {\r
-                @Override\r
-                public void run(DatabaseException parameter) {\r
-                    if (parameter != null)\r
-                        ExceptionUtils.logError(parameter);\r
-                }\r
-            });\r
-        }\r
-\r
-        @Override\r
-        public void widgetDefaultSelected(SelectionEvent e) {\r
-            widgetSelected(e);\r
-        }\r
-\r
-        @Override\r
-        public void widgetSelected(SelectionEvent e) {\r
-            run();\r
-        }\r
-\r
-    }\r
-\r
-    static class SetAttachedRouteGraphRoutingAction extends SelectionListenerAction {\r
-\r
-        Session session;\r
-        Collection<Resource> elements;\r
-        boolean straight;\r
-\r
-        public SetAttachedRouteGraphRoutingAction(Session session, Collection<Resource> elements, boolean straight, String text) {\r
-            super(text);\r
-            this.session = session;\r
-            this.elements = elements;\r
-            this.straight = straight;\r
-        }\r
-\r
-        @Override\r
-        public void run() {\r
-            session.asyncRequest(new WriteRequest() {\r
-                @Override\r
-                public void perform(WriteGraph graph) throws DatabaseException {\r
-                    Command command = Commands.get(graph, "Simantics/Diagram/setStraightConnectionLines");\r
-                    for(Resource element : elements)\r
-                        command.execute(graph,\r
-                                graph.syncRequest(new IndexRoot(element)),\r
-                                element, straight);\r
-                    \r
-                    CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
-                    graph.addMetadata(cm.add("Set routing for an element."));\r
-                }\r
-            }, new Callback<DatabaseException>() {\r
-                @Override\r
-                public void run(DatabaseException parameter) {\r
-                    if (parameter != null)\r
-                        ExceptionUtils.logError(parameter);\r
-                }\r
-            });\r
-        }\r
-\r
-        @Override\r
-        public void widgetDefaultSelected(SelectionEvent e) {\r
-            widgetSelected(e);\r
-        }\r
-\r
-        @Override\r
-        public void widgetSelected(SelectionEvent e) {\r
-            run();\r
-        }\r
-\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.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.Statement;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.CommentMetadata;
+import org.simantics.db.common.request.IndexRoot;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.diagram.content.ConnectionUtil;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+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.datastructures.Callback;
+import org.simantics.utils.ui.AdaptionUtils;
+import org.simantics.utils.ui.ExceptionUtils;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class ConnectionRoutingMenuContribution extends DynamicMenuContribution {
+       
+
+    private static final IContributionItem[] NONE = {};
+
+    @Override
+    protected IContributionItem[] getContributionItems(ReadGraph graph, Object[] selection) throws DatabaseException {
+        ArrayList<IContributionItem> result = new ArrayList<IContributionItem>(4);
+
+        result.addAll(getConnectionRoutingItems(graph, selection));
+        result.addAll(getAttachedConnectionRoutingItems(graph, selection));
+
+        return result.toArray(NONE);
+    }
+
+    public static Collection<IContributionItem> getConnectionRoutingItems(ReadGraph graph, Object[] selection) throws DatabaseException {
+        Layer0 l0 = Layer0.getInstance(graph);
+        DiagramResource dr = DiagramResource.getInstance(graph);
+
+        final Collection<Resource> routings = graph.getObjects(dr.Routing, l0.SuperrelationOf);
+        if (routings.size() == 0)
+            return Collections.emptyList();
+
+        final List<Resource> connections = new ArrayList<Resource>();
+        for (Object s : selection) {
+            Resource connection = AdaptionUtils.adaptToSingle(s, Resource.class);
+            if (connection == null)
+                return Collections.emptyList();
+            if (!graph.isInstanceOf(connection, dr.Connection))
+                return Collections.emptyList();
+            // Route graph connection routing is not selected per-connection, but per-terminal.
+            if (graph.isInstanceOf(connection, dr.RouteGraphConnection))
+                return Collections.emptyList();
+            connections.add(connection);
+        }
+        if (connections.isEmpty())
+            return Collections.emptyList();
+
+        // See if all connections have a common routing.
+        Resource currentRoute = null;
+        for (Resource connection : connections) {
+            Statement currentRouting = graph.getPossibleStatement(connection, dr.Routing);
+            if (currentRouting != null) {
+                Resource route = currentRouting.getPredicate();
+                if (currentRoute == null)
+                    currentRoute = route;
+                else if (!currentRoute.equals(route)) {
+                    currentRoute = null;
+                    break;
+                }
+            }
+        }
+
+        final List<SetRoutingAction> actions = new ArrayList<SetRoutingAction>();
+        for (Resource routing : routings) {
+            String text = graph.adapt(routing, String.class);
+            SetRoutingAction action = new SetRoutingAction(graph.getSession(), connections, routing, text);
+            if (routing.equals(currentRoute))
+                action.setChecked(true);
+            actions.add(action);
+        }
+
+
+        sort(actions);
+
+        return Collections.<IContributionItem>singleton(
+                new ContributionItem() {
+                    @Override
+                    public void fill(Menu menu, int index) {
+                        MenuItem openWith = new MenuItem(menu, SWT.CASCADE, index);
+                        openWith.setText("Connection Routing");
+                        Menu subMenu = new Menu(menu);
+                        openWith.setMenu(subMenu);
+
+                        for (SetRoutingAction a : actions) {
+                            MenuItem item = new MenuItem(subMenu, SWT.CHECK);
+                            item.setText(a.getText());
+                            item.addSelectionListener(a);
+                            item.setSelection(a.isChecked());
+                        }
+                    }
+                }
+        );
+    }
+
+    public static Collection<IContributionItem> getAttachedConnectionRoutingItems(ReadGraph graph, Object[] selection) throws DatabaseException {
+        Layer0 l0 = Layer0.getInstance(graph);
+        DiagramResource dr = DiagramResource.getInstance(graph);
+        StructuralResource2 sr = StructuralResource2.getInstance(graph);
+        ModelingResources MOD = ModelingResources.getInstance(graph);
+        // HACK
+        Resource ReferenceProvider = graph.getPossibleResource("http://www.apros.fi/Apros-6.1/ReferenceProvider");
+        // Just continuing to do stupid things as above ;)
+        Resource connectionType = graph.getPossibleResource("http://www.simantics.org/Kcleco-5.0/FlowConnection");
+      
+
+        final Collection<Resource> routings = graph.getObjects(dr.Routing, l0.SuperrelationOf);
+        if (routings.size() == 0)
+            return Collections.emptyList();
+
+        final List<Resource> connections = new ArrayList<Resource>();
+
+        // For route graph connections
+        final List<Resource> connectors = new ArrayList<Resource>();
+        boolean directRoutings = false;
+        boolean straightRoutings = false;
+
+        ArrayList<Resource> elements = new ArrayList<Resource>(); 
+        for (Object s : selection) {
+            Resource element = AdaptionUtils.adaptToSingle(s, Resource.class);
+            if (element == null)
+                return Collections.emptyList();
+            if (!graph.isInstanceOf(element, dr.Element) || graph.isInstanceOf(element, dr.Connection))
+                return Collections.emptyList();
+
+            elements.add(element);
+            
+            for(Statement stat : graph.getStatements(element, sr.IsConnectedTo)) {
+                Resource diagramRelation = stat.getPredicate();
+                Resource connectionRelation = graph.getPossibleObject(diagramRelation, MOD.DiagramConnectionRelationToConnectionRelation);
+                if(connectionRelation == null)
+                    continue;
+                // FIXME HACK
+                if(ReferenceProvider != null && !graph.isInstanceOf(connectionRelation, ReferenceProvider))
+                    continue;
+                Resource connector = stat.getObject();
+
+                Resource connection = ConnectionUtil.tryGetConnection(graph, connector);
+                if (connection != null) {
+                    if (graph.isInstanceOf(connection, dr.RouteGraphConnection)) {
+                       if (connectionType != null && graph.isInstanceOf(connection, connectionType))   
+                            continue;
+                        connectors.add(connector);
+                        boolean direct = Boolean.TRUE.equals( graph.getPossibleRelatedValue2(connector, dr.Connector_straight, Bindings.BOOLEAN) );
+                        directRoutings |= direct;
+                        straightRoutings |= !direct;
+                    } else {
+                        connections.add(connection);
+                    }
+                }
+            }
+        }
+        if (connectors.isEmpty() && connections.isEmpty())
+            return Collections.emptyList();
+
+        // See if all connections have a common routing.
+        Resource currentRoute = null;
+        for (Resource connection : connections) {
+            Statement currentRouting = graph.getPossibleStatement(connection, dr.Routing);
+            if (currentRouting != null) {
+                Resource route = currentRouting.getPredicate();
+                if (currentRoute == null)
+                    currentRoute = route;
+                else if (!currentRoute.equals(route)) {
+                    currentRoute = null;
+                    break;
+                }
+            }
+        }
+
+        final List<SelectionListenerAction> actions = new ArrayList<SelectionListenerAction>();
+
+        if (!connections.isEmpty()) {
+            // Handle old style connections and their routing
+            for (Resource routing : routings) {
+                String text = graph.adapt(routing, String.class);
+                SetRoutingAction action = new SetRoutingAction(graph.getSession(), connections, routing, text);
+                if (routing.equals(currentRoute)) {
+                    action.setChecked(true);
+                }
+                actions.add(action);
+            }
+        }
+        if (!connectors.isEmpty()) {
+            // Handle route graph connections
+            SelectionListenerAction direct = new SetAttachedRouteGraphRoutingAction(graph.getSession(), elements, true, "Direct");
+            SelectionListenerAction straight = new SetAttachedRouteGraphRoutingAction(graph.getSession(), elements, false, "Straight-angled");
+            direct.setChecked(directRoutings);
+            straight.setChecked(straightRoutings);
+            actions.add(direct);
+            actions.add(straight);
+        }
+
+        sort(actions);
+
+        return Collections.<IContributionItem>singleton(
+                new ContributionItem() {
+                    @Override
+                    public void fill(Menu menu, int index) {
+                        MenuItem openWith = new MenuItem(menu, SWT.CASCADE, index);
+                        openWith.setText("Attached Connection Routing");
+                        Menu subMenu = new Menu(menu);
+                        openWith.setMenu(subMenu);
+
+                        for (SelectionListenerAction a : actions) {
+                            MenuItem item = new MenuItem(subMenu, SWT.CHECK);
+                            item.setText(a.getText());
+                            item.addSelectionListener(a);
+                            item.setSelection(a.isChecked());
+                        }
+                    }
+                }
+        );
+    }
+
+    private static void sort(List<? extends IAction> actions) {
+        // Sort the open with actions in string order.
+        Collections.sort(actions, new Comparator<IAction>() {
+            @Override
+            public int compare(IAction o1, IAction o2) {
+                return o1.getText().compareToIgnoreCase(o2.getText());
+            }
+        });
+    }
+
+    static abstract class SelectionListenerAction extends Action implements SelectionListener {
+        public SelectionListenerAction(String text) {
+            super(text);
+        }
+    }
+
+    static class SetRoutingAction extends SelectionListenerAction {
+
+        Session session;
+        Collection<Resource> connections;
+        Resource routingTag;
+
+        public SetRoutingAction(Session session, Collection<Resource> connections, Resource routingTag, String text) {
+            super(text);
+            this.session = session;
+            this.connections = connections;
+            this.routingTag = routingTag;
+        }
+
+        @Override
+        public void run() {
+            session.asyncRequest(new WriteRequest() {
+                @Override
+                public void perform(WriteGraph graph) throws DatabaseException {
+                    DiagramResource dr = DiagramResource.getInstance(graph);
+                    for (Resource connection : connections) {
+                        graph.deny(connection, dr.Routing);
+                        graph.claim(connection, routingTag, connection);
+                    }
+                }
+            }, new Callback<DatabaseException>() {
+                @Override
+                public void run(DatabaseException parameter) {
+                    if (parameter != null)
+                        ExceptionUtils.logError(parameter);
+                }
+            });
+        }
+
+        @Override
+        public void widgetDefaultSelected(SelectionEvent e) {
+            widgetSelected(e);
+        }
+
+        @Override
+        public void widgetSelected(SelectionEvent e) {
+            run();
+        }
+
+    }
+
+    static class SetAttachedRouteGraphRoutingAction extends SelectionListenerAction {
+
+        Session session;
+        Collection<Resource> elements;
+        boolean straight;
+
+        public SetAttachedRouteGraphRoutingAction(Session session, Collection<Resource> elements, boolean straight, String text) {
+            super(text);
+            this.session = session;
+            this.elements = elements;
+            this.straight = straight;
+        }
+
+        @Override
+        public void run() {
+            session.asyncRequest(new WriteRequest() {
+                @Override
+                public void perform(WriteGraph graph) throws DatabaseException {
+                    Command command = Commands.get(graph, "Simantics/Diagram/setStraightConnectionLines");
+                    for(Resource element : elements)
+                        command.execute(graph,
+                                graph.syncRequest(new IndexRoot(element)),
+                                element, straight);
+                    
+                    CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
+                    graph.addMetadata(cm.add("Set routing for an element."));
+                }
+            }, new Callback<DatabaseException>() {
+                @Override
+                public void run(DatabaseException parameter) {
+                    if (parameter != null)
+                        ExceptionUtils.logError(parameter);
+                }
+            });
+        }
+
+        @Override
+        public void widgetDefaultSelected(SelectionEvent e) {
+            widgetSelected(e);
+        }
+
+        @Override
+        public void widgetSelected(SelectionEvent e) {
+            run();
+        }
+
+    }
+
+}