1 /*******************************************************************************
2 * Copyright (c) 2017 Association for Decentralized Information Management in
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Semantum Oy - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.modeling.ui.actions;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.List;
18 import org.eclipse.jface.action.ContributionItem;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.SelectionAdapter;
21 import org.eclipse.swt.events.SelectionEvent;
22 import org.eclipse.swt.widgets.Menu;
23 import org.eclipse.swt.widgets.MenuItem;
24 import org.simantics.Simantics;
25 import org.simantics.db.ReadGraph;
26 import org.simantics.db.Resource;
27 import org.simantics.db.WriteGraph;
28 import org.simantics.db.common.request.UnaryRead;
29 import org.simantics.db.common.request.WriteRequest;
30 import org.simantics.db.exception.DatabaseException;
31 import org.simantics.layer0.Layer0;
32 import org.simantics.modeling.MigrateModel;
33 import org.simantics.modeling.ModelingResources;
34 import org.simantics.modeling.ui.diagramEditor.DiagramEditor;
35 import org.simantics.structural.stubs.StructuralResource2;
36 import org.simantics.ui.utils.ResourceAdaptionUtils;
37 import org.simantics.utils.ui.SWTUtils;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
42 * @author Hannu Niemistö
45 public class SwitchComponentTypeContribution extends ContributionItem {
46 private static final Logger LOGGER = LoggerFactory.getLogger(SwitchComponentTypeContribution.class);
48 private static class SwitchGroup implements Comparable<SwitchGroup> {
50 final ArrayList<Alternative> alternatives = new ArrayList<Alternative>();
52 public SwitchGroup(String label) {
57 public int compareTo(SwitchGroup o) {
58 return label.compareTo(o.label);
62 private static class Alternative implements Comparable<Alternative> {
64 final Resource componentType;
65 final boolean isCurrent;
67 public Alternative(String label, Resource componentType, boolean isCurrent) {
69 this.componentType = componentType;
70 this.isCurrent = isCurrent;
74 public int compareTo(Alternative o) {
75 return label.compareTo(o.label);
80 public void fill(Menu menu, int index) {
81 Resource resource = ResourceAdaptionUtils.toSingleWorkbenchResource();
85 List<SwitchGroup> groups;
87 groups = Simantics.getSession().syncRequest(new ComponentSwitchGroupQuery(resource));
88 } catch (DatabaseException e) {
89 LOGGER.error("Retrieval of switch groups failed.", e);
93 if(!groups.isEmpty()) {
94 SelectionAdapter switchAction = new SelectionAdapter() {
96 public void widgetSelected(SelectionEvent e) {
97 Resource newComponentType = (Resource)e.widget.getData();
98 Simantics.getSession().asyncRequest(new WriteRequest() {
100 public void perform(WriteGraph graph) throws DatabaseException {
101 Resource component = elementToComponent(graph, resource);
102 MigrateModel.changeComponentType(graph, component, newComponentType);
104 Layer0 L0 = Layer0.getInstance(graph);
105 Resource composite = graph.getPossibleObject(component, L0.PartOf);
106 if (composite == null)
108 ModelingResources MOD = ModelingResources.getInstance(graph);
109 Resource diagram = graph.getPossibleObject(composite, MOD.CompositeToDiagram);
112 SWTUtils.asyncExec(menu, () -> DiagramEditor.reinitializeDiagram(diagram));
117 for(SwitchGroup group : groups) {
118 MenuItem item = new MenuItem(menu, SWT.CASCADE);
119 item.setText(group.label);
121 Menu subMenu = new Menu(menu);
122 item.setMenu(subMenu);
124 for(Alternative alternative : group.alternatives) {
125 MenuItem subItem = new MenuItem(subMenu, SWT.PUSH);
126 subItem.setText(alternative.label);
127 subItem.setData(alternative.componentType);
128 if(alternative.isCurrent)
129 subItem.setEnabled(false);
131 subItem.addSelectionListener(switchAction);
137 private static class ComponentSwitchGroupQuery extends UnaryRead<Resource, List<SwitchGroup>> {
138 public ComponentSwitchGroupQuery(Resource parameter) {
143 public List<SwitchGroup> perform(ReadGraph graph) throws DatabaseException {
144 StructuralResource2 STR = StructuralResource2.getInstance(graph);
145 ModelingResources MOD = ModelingResources.getInstance(graph);
146 Resource component = elementToComponent(graph, parameter);
148 Resource componentType = graph.getPossibleType(component, STR.Component);
149 if(componentType == null)
150 return Collections.emptyList();
152 Layer0 L0 = Layer0.getInstance(graph);
153 ArrayList<SwitchGroup> result = new ArrayList<SwitchGroup>();
154 for(Resource myAlt : graph.getObjects(componentType, MOD.BelongsToComponentSwitchGroup)) {
155 Resource group = graph.getSingleObject(myAlt, MOD.ComponentSwitchGroup_alternative_Inverse);
157 SwitchGroup groupObj;
159 String label = graph.getPossibleRelatedValue(group, L0.HasLabel);
161 label = graph.getPossibleRelatedValue(group, L0.HasName);
163 label = "Alternative types";
165 groupObj = new SwitchGroup(label);
168 for(Resource alt : graph.getObjects(group, MOD.ComponentSwitchGroup_alternative)) {
169 Resource altComponentType = graph.getSingleObject(alt, MOD.ComponentSwitchAlternative_componentType);
170 String label = graph.getPossibleRelatedValue(alt, L0.HasLabel);
172 label = graph.getPossibleRelatedValue(alt, L0.HasName);
174 label = graph.getPossibleRelatedValue(altComponentType, L0.HasLabel);
176 label = graph.getRelatedValue(altComponentType, L0.HasName);
179 groupObj.alternatives.add(new Alternative(label, altComponentType, altComponentType.equals(componentType)));
181 Collections.sort(groupObj.alternatives);
182 result.add(groupObj);
184 Collections.sort(result);
189 private static Resource elementToComponent(ReadGraph graph, Resource element) throws DatabaseException {
190 ModelingResources MOD = ModelingResources.getInstance(graph);
191 Resource component = graph.getPossibleObject(element, MOD.ElementToComponent);
192 if(component != null)