]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/OpenDiagramFromConfigurationAdapter.java
Support opening multiple selected objects from same diagram
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / diagramEditor / OpenDiagramFromConfigurationAdapter.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.modeling.ui.diagramEditor;
13
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.HashSet;
17 import java.util.Set;
18
19 import org.eclipse.ui.PlatformUI;
20 import org.simantics.Simantics;
21 import org.simantics.db.ReadGraph;
22 import org.simantics.db.Resource;
23 import org.simantics.db.common.request.PossibleIndexRoot;
24 import org.simantics.db.common.request.PossibleTypedParent;
25 import org.simantics.db.common.request.ReadRequest;
26 import org.simantics.db.exception.DatabaseException;
27 import org.simantics.db.layer0.variable.RVI;
28 import org.simantics.db.layer0.variable.Variable;
29 import org.simantics.db.layer0.variable.Variables;
30 import org.simantics.diagram.stubs.DiagramResource;
31 import org.simantics.g2d.canvas.ICanvasContext;
32 import org.simantics.g2d.diagram.DiagramHints;
33 import org.simantics.layer0.Layer0;
34 import org.simantics.modeling.ComponentUtils;
35 import org.simantics.modeling.actions.NavigateToTarget;
36 import org.simantics.modeling.ui.Activator;
37 import org.simantics.structural.stubs.StructuralResource2;
38 import org.simantics.ui.workbench.editor.AbstractResourceEditorAdapter;
39 import org.simantics.utils.datastructures.Pair;
40 import org.simantics.utils.threads.ThreadUtils;
41
42 /**
43  * @author Tuukka Lehtonen
44  */
45 public class OpenDiagramFromConfigurationAdapter extends AbstractResourceEditorAdapter {
46
47     private static final String EDITOR_ID = "org.simantics.modeling.ui.diagramEditor"; //$NON-NLS-1$
48
49     public OpenDiagramFromConfigurationAdapter() {
50         super(Messages.OpenDiagramFromConfigurationAdapter_DiagramEditor, Activator.COMPOSITE_ICON);
51     }
52
53     protected String getEditorId() {
54         return EDITOR_ID;
55     }
56
57     @Override
58     public boolean canHandle(ReadGraph g, Resource r) throws DatabaseException {
59         Resource diagram = getDiagram(g, r, Collections.emptySet());
60         if(diagram == null)
61             return false;
62         
63         // Check if the diagram is locked, because of the locked component type
64         return !isLocked(g, diagram);
65         
66 //        return ComponentUtils.compositeHasDiagram(g, r) /*|| ComponentUtils.componentHasDiagram(g, r)*/;
67     }
68     
69     public static boolean isLocked(ReadGraph g, Resource diagram) throws DatabaseException {
70         StructuralResource2 STR = StructuralResource2.getInstance(g);
71         Resource componentType = g.syncRequest(new PossibleTypedParent(diagram, STR.ComponentType));
72         if(componentType == null)
73             return false; // Not part of a component type
74         
75         return g.hasStatement(componentType, STR.ComponentType_Locked);
76     }
77
78     @Override
79     public void openEditor(final Resource r) throws Exception {
80         Simantics.getSession().asyncRequest(new ReadRequest() {
81             @Override
82             public void run(ReadGraph g) throws DatabaseException {
83                 openEditor(g, r, getEditorId());
84             }
85         });
86     }
87
88     /**
89      * @param g
90      * @param configurationComposite
91      * @param editorId
92      * @throws DatabaseException
93      */
94     public static boolean openEditor(ReadGraph g, Resource configurationComposite, final String editorId) throws DatabaseException {
95         return openEditor(g, configurationComposite, editorId, Collections.emptySet());
96     }
97
98     protected static Resource getDiagram(ReadGraph graph, Resource r, final Collection<Object> selectedObjects) throws DatabaseException {
99
100         Layer0 L0 = Layer0.getInstance(graph);
101         DiagramResource DIA = DiagramResource.getInstance(graph);
102         
103         if(graph.isInstanceOf(r, DIA.Diagram)) return r;
104         
105         Resource diagram = ComponentUtils.getPossibleCompositeDiagram(graph, r);
106         if(diagram != null) return diagram;
107         
108         // TODO: what if the selected objects are from different diagrams?
109         if (selectedObjects.size() > 0) {
110             Set<Resource> diagrams = new HashSet<>();
111             for (Object o : selectedObjects) {
112                 if (o instanceof Resource) {
113                     Resource res = (Resource)o;
114                     if (graph.isInstanceOf(res, DIA.Element)) {
115                         diagrams.add(graph.getPossibleObject(res, L0.PartOf));
116                     }
117                 }
118             }
119             if (diagrams.size() == 1) {
120                 return diagrams.iterator().next();
121             }
122         }
123         return null;
124
125     }
126
127     public static Pair<Resource, RVI> getModelAndRVI(ReadGraph graph, Resource configurationComposite) throws DatabaseException {
128         Variable compositeVariable = Variables.getPossibleVariable(graph, configurationComposite);
129         if (compositeVariable == null)
130             return null;
131
132         Layer0 L0 = Layer0.getInstance(graph);
133         StructuralResource2 STR = StructuralResource2.getInstance(graph);
134         boolean isComponentType = graph.hasStatement(configurationComposite, STR.Defines);
135         Resource rviContext = graph.syncRequest(new PossibleTypedParent(configurationComposite, L0.RVIContext));
136
137         if (isComponentType || rviContext == null) {
138             Resource indexRoot = graph.sync(new PossibleIndexRoot(configurationComposite));
139             if (indexRoot == null)
140                 return null;
141
142             return Pair.make(indexRoot, null);
143         }
144
145         final Resource model = Variables.getPossibleModel(graph, compositeVariable);
146         if (model == null)
147             return null;
148         final RVI rvi = compositeVariable.getPossibleRVI(graph);
149
150         return Pair.make(model, rvi);
151     }
152
153     /**
154      * @param g
155      * @param configurationComposite
156      * @param editorId
157      * @param selectedObjects
158      * @throws DatabaseException
159      */
160     public static boolean openEditor(ReadGraph g, Resource r, String editorId, Collection<Object> selectedObjects) throws DatabaseException {
161         Resource diagram = getDiagram(g, r, selectedObjects);
162         Resource configurationComposite = diagram != null ? ComponentUtils.getPossibleDiagramComposite(g, diagram) : null;
163         Pair<Resource, RVI> modelAndRVI = configurationComposite != null ? getModelAndRVI(g, configurationComposite) : null;
164         //System.out.println("modelAndRVI: " + modelAndRVI);
165         if (modelAndRVI == null)
166             return false;
167         scheduleOpenEditor(editorId, diagram, modelAndRVI.first, modelAndRVI.second, selectedObjects);
168         return true;
169     }
170
171     /**
172      * @param g
173      * @param configurationComposite
174      * @param editorId
175      * @param selectedObjects
176      * @throws DatabaseException
177      */
178     public static boolean openEditor(ReadGraph g, Resource r, String editorId, Collection<Object> selectedObjects, Resource model, RVI rvi) throws DatabaseException {
179         Resource diagram = getDiagram(g, r, selectedObjects);
180         if (diagram == null)
181             return false;
182         scheduleOpenEditor(editorId, diagram, model, rvi, selectedObjects);
183         return true;
184     }
185
186     /**
187      * @param g
188      * @param configurationComposite
189      * @param editorId
190      * @param selectedObjects
191      * @throws DatabaseException
192      */
193     private static void scheduleOpenEditor(String editorId, Resource diagram, Resource model, RVI rvi, Collection<Object> selectedObjects) throws DatabaseException {
194         Runnable editorActivator = NavigateToTarget.editorActivator(editorId, diagram, model, rvi, part -> {
195             if (selectedObjects.isEmpty())
196                 return;
197             ICanvasContext openedCanvas = (ICanvasContext) part.getAdapter(ICanvasContext.class);
198             assert openedCanvas != null;
199             // CanvasContext-wide denial of initial zoom-to-fit on diagram open.
200             openedCanvas.getDefaultHintContext().setHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT, Boolean.FALSE);
201             ThreadUtils.asyncExec(openedCanvas.getThreadAccess(),
202                     NavigateToTarget.elementSelectorZoomer(openedCanvas, selectedObjects, false));
203         });
204         PlatformUI.getWorkbench().getDisplay().asyncExec(editorActivator);
205     }
206
207 }