1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.modeling.ui.diagramEditor.handlers.e4;
14 import java.awt.Shape;
15 import java.awt.geom.AffineTransform;
16 import java.awt.geom.Rectangle2D;
17 import java.util.Collection;
18 import java.util.HashSet;
20 import java.util.function.Consumer;
22 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
23 import org.simantics.db.ReadGraph;
24 import org.simantics.db.Resource;
25 import org.simantics.db.common.ResourceArray;
26 import org.simantics.db.common.request.ReadRequest;
27 import org.simantics.db.common.utils.OrderedSetUtils;
28 import org.simantics.db.exception.DatabaseException;
29 import org.simantics.db.management.ISessionContext;
30 import org.simantics.diagram.stubs.DiagramResource;
31 import org.simantics.g2d.canvas.ICanvasContext;
32 import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
33 import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
34 import org.simantics.g2d.diagram.DiagramHints;
35 import org.simantics.g2d.diagram.IDiagram;
36 import org.simantics.g2d.diagram.handler.DataElementMap;
37 import org.simantics.g2d.diagram.participant.Selection;
38 import org.simantics.g2d.element.ElementHints;
39 import org.simantics.g2d.element.ElementUtils;
40 import org.simantics.g2d.element.IElement;
41 import org.simantics.g2d.participant.CanvasBoundsParticipant;
42 import org.simantics.g2d.participant.TransformUtil;
43 import org.simantics.g2d.utils.GeometryUtils;
44 import org.simantics.modeling.ModelingResources;
45 import org.simantics.modeling.ui.diagramEditor.e4.DiagramViewer;
46 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
47 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent;
48 import org.simantics.structural.stubs.StructuralResource2;
49 import org.simantics.ui.workbench.e4.E4WorkbenchUtils;
50 import org.simantics.utils.page.MarginUtils;
51 import org.simantics.utils.threads.ThreadUtils;
52 import org.simantics.utils.ui.ErrorLogger;
55 * StructuralBrowsingHandler supports visual browsing into subcomponents through
58 * @author Tuukka Lehtonen
60 public class LinkBrowsingHandler extends AbstractCanvasParticipant {
63 CanvasBoundsParticipant canvasBounds;
68 ISessionContext sessionContext;
70 public LinkBrowsingHandler(DiagramViewer viewer, ISessionContext context) {
72 // System.out.println("LinkBrowsingHandler " + viewer + " " + viewer.structuralPath);
75 this.sessionContext = context;
79 public static Runnable editorActivator(final MPart part, final ResourceArray input, final Consumer<MPart> successCallback) {
80 String sourcePartId = part.getElementId();
81 return editorActivator(sourcePartId, input, successCallback);
84 public Runnable elementSelectorZoomer(final ICanvasContext canvas, final Collection<Object> elementObjects, final boolean keepZoom) {
85 return new Runnable() {
88 IDiagram diagram = canvas.getHintStack().getHint(DiagramHints.KEY_DIAGRAM);
89 assert diagram != null;
90 if (!zoomToSelection(canvas, diagram, selectElement(canvas, diagram, elementObjects), keepZoom)) {
91 // Reschedule for later.
92 ThreadUtils.asyncExec(canvas.getThreadAccess(), this);
98 public static Set<IElement> selectElement(final ICanvasContext canvas, final IDiagram diagram, final Collection<Object> elementObjects) {
100 Set<IElement> selection = new HashSet<IElement>();
101 DataElementMap dataMap = diagram.getDiagramClass().getSingleItem(DataElementMap.class);
102 for (Object obj : elementObjects) {
103 IElement element = dataMap.getElement(diagram, obj);
104 if (element == null) {
105 ErrorLogger.defaultLogWarning("No element to select for object " + obj, new Exception());
107 selection.add(element);
110 for (Selection s : canvas.getItemsByClass(Selection.class)) {
111 s.setSelection(0, selection);
116 public boolean zoomToSelection(final ICanvasContext canvas, final IDiagram diagram, Set<IElement> selection, boolean keepZoom) {
117 TransformUtil util = canvas.getSingleItem(TransformUtil.class);
118 Rectangle2D controlBounds = canvasBounds.getControlBounds();
119 if (controlBounds == null)
122 Shape shp = ElementUtils.getElementBoundsOnDiagram(selection);
126 Rectangle2D diagramRect = shp.getBounds2D();
128 double scaleFactor = GeometryUtils.getScale(util.getTransform());
129 double cwh = controlBounds.getWidth() / (scaleFactor*2);
130 double chh = controlBounds.getHeight() / (scaleFactor*2);
132 AffineTransform view = new AffineTransform();
133 view.scale(scaleFactor, scaleFactor);
134 view.translate(-diagramRect.getCenterX()+cwh, -diagramRect.getCenterY()+chh);
136 util.setTransform(view);
138 MarginUtils.Margin margin = MarginUtils.marginOf(40, 0, 0);
139 MarginUtils.Margins margins = new MarginUtils.Margins(margin, margin, margin, margin);
140 util.fitArea(controlBounds, diagramRect, margins);
145 public static Runnable editorActivator(final String editorPartId, final ResourceArray input, final Consumer<MPart> successCallback) {
146 return new Runnable() {
149 // open and activate new editor
150 MPart part = E4WorkbenchUtils.openEditor(editorPartId, "", "", input.get(0));
151 E4WorkbenchUtils.activatePart(part);
152 successCallback.accept(part);
157 public static Resource getOwnerList(ReadGraph g, Resource listElement) throws DatabaseException {
158 return OrderedSetUtils.getSingleOwnerList(g, listElement, DiagramResource.getInstance(g).Composite);
161 @EventHandler(priority = 0)
162 public boolean handleDoubleClick(MouseDoubleClickedEvent me) {
164 //System.out.println("LinkBrowsingHandler");
166 if (sessionContext == null)
169 Set<IElement> sel = selection.getSelection(0);
171 if (sel.size() == 1) {
172 IElement e = sel.iterator().next();
173 Object data = e.getHint(ElementHints.KEY_OBJECT);
174 if (data instanceof Resource) {
175 final Resource element = (Resource) data;
176 sessionContext.getSession().asyncRequest(new ReadRequest() {
178 public void run(ReadGraph graph) throws DatabaseException {
180 //System.out.println("LinkBrowsingHandler0");
182 ModelingResources mr = ModelingResources.getInstance(graph);
183 DiagramResource dr = DiagramResource.getInstance(graph);
184 StructuralResource2 sr = StructuralResource2.getInstance(graph);
186 if (graph.isInstanceOf(element, dr.UpwardLink)) {
188 // Resource component = viewer.structuralPath.resources[0];
189 // Resource element = graph.getPossibleObject(component, mr.ComponentToElement);
190 // Resource diagram = getOwnerList(graph, element);
192 // IEditorPart thisEditor = (IEditorPart) site.getPart();
193 // site.getWorkbenchWindow().getShell().getDisplay().asyncExec(
194 // editorActivator(thisEditor, viewer.structuralPath.removeFromBeginning(1).prepended(diagram), new Callback<IEditorPart>() {
196 // public void run(IEditorPart part) {
200 } else if (graph.isInstanceOf(element, dr.Link)) {
202 //System.out.println("LinkBrowsingHandler2");
204 // ContextMap parameters = new ContextMap();
205 // parameters.put(ModelingOperationConstants.WORKBENCH_WINDOW, site.getWorkbenchWindow());
206 // parameters.put(ModelingOperationConstants.WORKBENCH_PART, site.getPart());
207 // parameters.put(IOperation.SUBJECT, element);
209 Resource thisDiagram = getOwnerList(graph, element);
210 if (thisDiagram == null) return;
212 final Resource target = graph.getPossibleObject(element, dr.HasLinkTarget);
213 if (target == null) return;
215 final Resource otherDiagram = getOwnerList(graph, target);
216 if (otherDiagram == null)
219 final Resource component = graph.getPossibleObject(target, mr.ElementToComponent);
220 if (component == null)
223 Resource type = graph.getSingleType(component, sr.Component);
227 Resource definedBy = graph.getPossibleObject(type, sr.IsDefinedBy);
228 if (definedBy == null)
231 final Resource diagram = graph.getPossibleObject(definedBy, mr.CompositeToDiagram);
235 // PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
237 // public void run() {
239 // WorkbenchUtils.openEditor(site.getId(), new ResourceEditorInput(site.getId(), parentStructuralPath.prepended(diagram, component)));
240 // } catch (PartInitException e) {
241 // // TODO Auto-generated catch block
242 // e.printStackTrace();
247 // IEditorPart thisEditor = (IEditorPart) site.getPart();
248 // ResourceArray input = viewer.structuralPath.prepended(diagram, component);
249 // System.out.println("Browsing link " + input);
250 // site.getWorkbenchWindow().getShell().getDisplay().asyncExec(
251 // editorActivator(thisEditor, input, new Callback<IEditorPart>() {
253 // public void run(IEditorPart part) {
254 //// final ICanvasContext openedCanvas = (ICanvasContext) part.getAdapter(ICanvasContext.class);
255 //// assert openedCanvas != null;
256 //// IDiagram diagram = (IDiagram) part.getAdapter(IDiagram.class);
257 //// assert diagram != null;
258 // // Disable automatic-zoom-to-fit
259 //// diagram.removeHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT);
260 //// ThreadUtils.asyncExec(openedCanvas.getThreadAccess(),
261 //// elementSelectorZoomer(openedCanvas, Collections.singleton((Object) target), false));
267 // System.out.println("LinkBrowsingHandler3");
269 // if (!thisDiagram.equals(otherDiagram)) {
271 // System.out.println("LinkBrowsingHandler4");
273 // // Find the structural path
274 // Resource ownerComposite = graph.getPossibleObject(otherDiagram, mr.DiagramToComposite);
275 // if (ownerComposite == null)
278 // Collection<ResourceArray> inputs = ComponentUtils.formInputs(graph, ownerComposite);
281 // for (final ResourceArray input : inputs) {