]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/SwitchComponentTypeContribution.java
(refs #7453) Switch component type of the component
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / actions / SwitchComponentTypeContribution.java
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/SwitchComponentTypeContribution.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/actions/SwitchComponentTypeContribution.java
new file mode 100644 (file)
index 0000000..61e8119
--- /dev/null
@@ -0,0 +1,171 @@
+package org.simantics.modeling.ui.actions;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jface.action.ContributionItem;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.MigrateModel;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.ui.utils.ResourceAdaptionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SwitchComponentTypeContribution extends ContributionItem {
+    private static final Logger LOGGER = LoggerFactory.getLogger(SwitchComponentTypeContribution.class);
+    
+    private static class SwitchGroup implements Comparable<SwitchGroup> {
+        final String label;
+        final ArrayList<Alternative> alternatives = new ArrayList<Alternative>();
+        
+        public SwitchGroup(String label) {
+            this.label = label;
+        }
+
+        @Override
+        public int compareTo(SwitchGroup o) {
+            return label.compareTo(o.label);
+        }
+    }
+    
+    private static class Alternative implements Comparable<Alternative> {
+        final String label;
+        final Resource componentType;
+        final boolean isCurrent;
+        
+        public Alternative(String label, Resource componentType, boolean isCurrent) {
+            this.label = label;
+            this.componentType = componentType;
+            this.isCurrent = isCurrent;
+        }
+        
+        @Override
+        public int compareTo(Alternative o) {
+            return label.compareTo(o.label);
+        }
+    }
+    
+    @Override
+    public void fill(Menu menu, int index) {
+        Resource resource = ResourceAdaptionUtils.toSingleWorkbenchResource();
+        if(resource == null)
+            return;
+        
+        List<SwitchGroup> groups;
+        try {
+            groups = Simantics.getSession().syncRequest(new ComponentSwitchGroupQuery(resource));
+        } catch (DatabaseException e) {
+            LOGGER.error("Retrieval of switch groups failed.", e);
+            return;
+        }
+        
+        if(!groups.isEmpty()) {
+            SelectionAdapter switchAction = new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    Resource newComponentType = (Resource)e.widget.getData();
+                    Simantics.getSession().asyncRequest(new WriteRequest() {
+                        @Override
+                        public void perform(WriteGraph graph) throws DatabaseException {
+                            MigrateModel.changeComponentType(graph, elementToComponent(graph, resource), newComponentType);
+                        }
+                    });
+                }
+            };
+            for(SwitchGroup group : groups) {
+                MenuItem item = new MenuItem(menu, SWT.CASCADE);
+                item.setText(group.label);
+
+                Menu subMenu = new Menu(menu);
+                item.setMenu(subMenu);
+
+                for(Alternative alternative : group.alternatives) {
+                    MenuItem subItem = new MenuItem(subMenu, SWT.PUSH);
+                    subItem.setText(alternative.label);
+                    subItem.setData(alternative.componentType);
+                    if(alternative.isCurrent)
+                        subItem.setEnabled(false);
+                    else
+                        subItem.addSelectionListener(switchAction);
+                }
+            }
+        }
+    }
+    
+    private static class ComponentSwitchGroupQuery extends UnaryRead<Resource, List<SwitchGroup>> {
+        public ComponentSwitchGroupQuery(Resource parameter) {
+            super(parameter);
+        }
+
+        @Override
+        public List<SwitchGroup> perform(ReadGraph graph) throws DatabaseException {
+            StructuralResource2 STR = StructuralResource2.getInstance(graph);
+            ModelingResources MOD = ModelingResources.getInstance(graph);
+            Resource component = elementToComponent(graph, parameter);
+            
+            Resource componentType = graph.getPossibleType(component, STR.Component);
+            if(componentType == null)
+                return Collections.emptyList();
+            
+            Layer0 L0 = Layer0.getInstance(graph);
+            ArrayList<SwitchGroup> result = new ArrayList<SwitchGroup>();
+            for(Resource myAlt : graph.getObjects(componentType, MOD.BelongsToComponentSwitchGroup)) {
+                Resource group = graph.getSingleObject(myAlt, MOD.ComponentSwitchGroup_alternative_Inverse);
+                
+                SwitchGroup groupObj;
+                {
+                    String label = graph.getPossibleRelatedValue(group, L0.HasLabel);
+                    if(label == null) {
+                        label = graph.getPossibleRelatedValue(group, L0.HasName);
+                        if(label == null)
+                            label = "Alternative types";
+                    }
+                    groupObj = new SwitchGroup(label);
+                }
+                
+                for(Resource alt : graph.getObjects(group, MOD.ComponentSwitchGroup_alternative)) {
+                    Resource altComponentType = graph.getSingleObject(alt, MOD.ComponentSwitchAlternative_componentType);
+                    String label = graph.getPossibleRelatedValue(alt, L0.HasLabel);
+                    if(label == null) {
+                        label = graph.getPossibleRelatedValue(alt, L0.HasName);
+                        if(label == null) {
+                            label = graph.getPossibleRelatedValue(altComponentType, L0.HasLabel);
+                            if(label == null)
+                                label = graph.getRelatedValue(altComponentType, L0.HasName);
+                        }
+                    }
+                    groupObj.alternatives.add(new Alternative(label, altComponentType, altComponentType.equals(componentType)));
+                }
+                Collections.sort(groupObj.alternatives);
+                result.add(groupObj);
+            }
+            Collections.sort(result);
+            return result;
+        }
+    }
+
+    private static Resource elementToComponent(ReadGraph graph, Resource element) throws DatabaseException {
+        ModelingResources MOD = ModelingResources.getInstance(graph);
+        Resource component = graph.getPossibleObject(element, MOD.ElementToComponent);
+        if(component != null)
+            return component;
+        else
+            return element;
+    }
+    
+}