61e81194e33d8fa2c0b880bc1c00f59f22b798ab
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / actions / SwitchComponentTypeContribution.java
1 package org.simantics.modeling.ui.actions;
2
3
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.List;
7
8 import org.eclipse.jface.action.ContributionItem;
9 import org.eclipse.swt.SWT;
10 import org.eclipse.swt.events.SelectionAdapter;
11 import org.eclipse.swt.events.SelectionEvent;
12 import org.eclipse.swt.widgets.Menu;
13 import org.eclipse.swt.widgets.MenuItem;
14 import org.simantics.Simantics;
15 import org.simantics.db.ReadGraph;
16 import org.simantics.db.Resource;
17 import org.simantics.db.WriteGraph;
18 import org.simantics.db.common.request.UnaryRead;
19 import org.simantics.db.common.request.WriteRequest;
20 import org.simantics.db.exception.DatabaseException;
21 import org.simantics.layer0.Layer0;
22 import org.simantics.modeling.MigrateModel;
23 import org.simantics.modeling.ModelingResources;
24 import org.simantics.structural.stubs.StructuralResource2;
25 import org.simantics.ui.utils.ResourceAdaptionUtils;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 public class SwitchComponentTypeContribution extends ContributionItem {
30     private static final Logger LOGGER = LoggerFactory.getLogger(SwitchComponentTypeContribution.class);
31     
32     private static class SwitchGroup implements Comparable<SwitchGroup> {
33         final String label;
34         final ArrayList<Alternative> alternatives = new ArrayList<Alternative>();
35         
36         public SwitchGroup(String label) {
37             this.label = label;
38         }
39
40         @Override
41         public int compareTo(SwitchGroup o) {
42             return label.compareTo(o.label);
43         }
44     }
45     
46     private static class Alternative implements Comparable<Alternative> {
47         final String label;
48         final Resource componentType;
49         final boolean isCurrent;
50         
51         public Alternative(String label, Resource componentType, boolean isCurrent) {
52             this.label = label;
53             this.componentType = componentType;
54             this.isCurrent = isCurrent;
55         }
56         
57         @Override
58         public int compareTo(Alternative o) {
59             return label.compareTo(o.label);
60         }
61     }
62     
63     @Override
64     public void fill(Menu menu, int index) {
65         Resource resource = ResourceAdaptionUtils.toSingleWorkbenchResource();
66         if(resource == null)
67             return;
68         
69         List<SwitchGroup> groups;
70         try {
71             groups = Simantics.getSession().syncRequest(new ComponentSwitchGroupQuery(resource));
72         } catch (DatabaseException e) {
73             LOGGER.error("Retrieval of switch groups failed.", e);
74             return;
75         }
76         
77         if(!groups.isEmpty()) {
78             SelectionAdapter switchAction = new SelectionAdapter() {
79                 @Override
80                 public void widgetSelected(SelectionEvent e) {
81                     Resource newComponentType = (Resource)e.widget.getData();
82                     Simantics.getSession().asyncRequest(new WriteRequest() {
83                         @Override
84                         public void perform(WriteGraph graph) throws DatabaseException {
85                             MigrateModel.changeComponentType(graph, elementToComponent(graph, resource), newComponentType);
86                         }
87                     });
88                 }
89             };
90             for(SwitchGroup group : groups) {
91                 MenuItem item = new MenuItem(menu, SWT.CASCADE);
92                 item.setText(group.label);
93
94                 Menu subMenu = new Menu(menu);
95                 item.setMenu(subMenu);
96
97                 for(Alternative alternative : group.alternatives) {
98                     MenuItem subItem = new MenuItem(subMenu, SWT.PUSH);
99                     subItem.setText(alternative.label);
100                     subItem.setData(alternative.componentType);
101                     if(alternative.isCurrent)
102                         subItem.setEnabled(false);
103                     else
104                         subItem.addSelectionListener(switchAction);
105                 }
106             }
107         }
108     }
109     
110     private static class ComponentSwitchGroupQuery extends UnaryRead<Resource, List<SwitchGroup>> {
111         public ComponentSwitchGroupQuery(Resource parameter) {
112             super(parameter);
113         }
114
115         @Override
116         public List<SwitchGroup> perform(ReadGraph graph) throws DatabaseException {
117             StructuralResource2 STR = StructuralResource2.getInstance(graph);
118             ModelingResources MOD = ModelingResources.getInstance(graph);
119             Resource component = elementToComponent(graph, parameter);
120             
121             Resource componentType = graph.getPossibleType(component, STR.Component);
122             if(componentType == null)
123                 return Collections.emptyList();
124             
125             Layer0 L0 = Layer0.getInstance(graph);
126             ArrayList<SwitchGroup> result = new ArrayList<SwitchGroup>();
127             for(Resource myAlt : graph.getObjects(componentType, MOD.BelongsToComponentSwitchGroup)) {
128                 Resource group = graph.getSingleObject(myAlt, MOD.ComponentSwitchGroup_alternative_Inverse);
129                 
130                 SwitchGroup groupObj;
131                 {
132                     String label = graph.getPossibleRelatedValue(group, L0.HasLabel);
133                     if(label == null) {
134                         label = graph.getPossibleRelatedValue(group, L0.HasName);
135                         if(label == null)
136                             label = "Alternative types";
137                     }
138                     groupObj = new SwitchGroup(label);
139                 }
140                 
141                 for(Resource alt : graph.getObjects(group, MOD.ComponentSwitchGroup_alternative)) {
142                     Resource altComponentType = graph.getSingleObject(alt, MOD.ComponentSwitchAlternative_componentType);
143                     String label = graph.getPossibleRelatedValue(alt, L0.HasLabel);
144                     if(label == null) {
145                         label = graph.getPossibleRelatedValue(alt, L0.HasName);
146                         if(label == null) {
147                             label = graph.getPossibleRelatedValue(altComponentType, L0.HasLabel);
148                             if(label == null)
149                                 label = graph.getRelatedValue(altComponentType, L0.HasName);
150                         }
151                     }
152                     groupObj.alternatives.add(new Alternative(label, altComponentType, altComponentType.equals(componentType)));
153                 }
154                 Collections.sort(groupObj.alternatives);
155                 result.add(groupObj);
156             }
157             Collections.sort(result);
158             return result;
159         }
160     }
161
162     private static Resource elementToComponent(ReadGraph graph, Resource element) throws DatabaseException {
163         ModelingResources MOD = ModelingResources.getInstance(graph);
164         Resource component = graph.getPossibleObject(element, MOD.ElementToComponent);
165         if(component != null)
166             return component;
167         else
168             return element;
169     }
170     
171 }