X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2FdiagramEditor%2Fhandlers%2Fe4%2FStructuralBrowsingHandler.java;fp=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2FdiagramEditor%2Fhandlers%2Fe4%2FStructuralBrowsingHandler.java;h=769f656b6bd2ab3ee9bb0a7aac95f4e3358821e6;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/handlers/e4/StructuralBrowsingHandler.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/handlers/e4/StructuralBrowsingHandler.java new file mode 100644 index 000000000..769f656b6 --- /dev/null +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/handlers/e4/StructuralBrowsingHandler.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2007, 2014 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - support SHIFT+left double click browsing outside of model configuration + *******************************************************************************/ +package org.simantics.modeling.ui.diagramEditor.handlers.e4; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.eclipse.e4.ui.model.application.ui.basic.MPart; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.ui.PlatformUI; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.PossibleIndexRoot; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.RVI; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; +import org.simantics.db.management.ISessionContext; +import org.simantics.diagram.flag.FlagUtil; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.diagram.ui.DiagramModelHints; +import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency; +import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.element.ElementHints; +import org.simantics.g2d.element.IElement; +import org.simantics.layer0.utils.operations.IOperation; +import org.simantics.modeling.ModelingOperationConstants; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.actions.NavigateToTarget; +import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; +import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent; +import org.simantics.structural.stubs.StructuralResource2; +import org.simantics.ui.workbench.IResourceEditorInput2; +import org.simantics.ui.workbench.e4.E4ResourceEditorConstants; +import org.simantics.ui.workbench.e4.E4WorkbenchUtils; +import org.simantics.utils.datastructures.persistent.ContextMap; +import org.simantics.utils.ui.ErrorLogger; + +/** + * StructuralBrowsingHandler supports visual browsing into subcomponents through + * mouse events. + * + * @author Tuukka Lehtonen + */ +public class StructuralBrowsingHandler extends AbstractDiagramParticipant { + + @Dependency + Selection selection; + MPart part; + ISessionContext sessionContext; + IResourceEditorInput2 input; + + public StructuralBrowsingHandler(ISessionContext sessionContext, MPart part, IResourceEditorInput2 input) { + this.sessionContext = sessionContext; + this.part = part; + this.input = input; + } + + @EventHandler(priority = 0) + public boolean handleDoubleClick(MouseDoubleClickedEvent me) { + if (sessionContext == null || diagram == null) + return false; + + Set sel = selection.getSelection(0); + if (sel.size() == 1) { + IElement e = sel.iterator().next(); + Object data = e.getHint(ElementHints.KEY_OBJECT); + final Resource runtime = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE); + if (data instanceof Resource) { + final Resource element = (Resource) data; + final int stateMask = me.stateMask; + try { + return sessionContext.getSession().syncRequest(new UniqueRead() { + @Override + public Boolean perform(ReadGraph graph) throws DatabaseException { + return browse(graph, element, runtime, stateMask); + } + }); + } catch (DatabaseException e1) { + ErrorLogger.defaultLogError(e1); + } + } + } + + return false; + } + + private boolean browse(ReadGraph graph, Resource element, Resource runtimeDiagram, int stateMask) throws DatabaseException { + DiagramResource DIA = DiagramResource.getInstance(graph); + ModelingResources mr = ModelingResources.getInstance(graph); + DiagramResource dr = DiagramResource.getInstance(graph); + StructuralResource2 sr = StructuralResource2.getInstance(graph); + + if (graph.isInstanceOf(element, dr.Flag)) { + ContextMap parameters = new ContextMap(); + parameters.put(ModelingOperationConstants.WORKBENCH_WINDOW, part.getContext().get(MWindow.class)); + parameters.put(ModelingOperationConstants.WORKBENCH_PART, part); + parameters.put(IOperation.SUBJECT, element); + new NavigateToTarget().exec(graph.getSession(), parameters); + // Return true only if the flag is joined somewhere and navigation is possible. + return FlagUtil.isJoined(graph, element); + } + + if((stateMask & MouseDoubleClickedEvent.SHIFT_MASK) == 0) + return false; + + if(runtimeDiagram == null || !graph.isInstanceOf(runtimeDiagram, DIA.RuntimeDiagram)) + return false; + + final Resource component = graph.getPossibleObject(element, mr.ElementToComponent); + if (component == null) + return false; + + Resource type = graph.getPossibleType(component, sr.Component); + if (type == null) + return false; + if(graph.hasStatement(type, sr.ComponentType_Locked)) + return false; + + Resource definedBy = graph.getPossibleObject(type, sr.IsDefinedBy); + if (definedBy == null) + return false; + + final Resource diagram = graph.getPossibleObject(definedBy, mr.CompositeToDiagram); + if (diagram == null) + return false; + + Resource model = input.getModel(graph); + RVI subprocessRVI = null; + + String rvis = (String) graph.getPossibleRelatedValue(runtimeDiagram, DIA.RuntimeDiagram_HasRVI); + if (rvis != null) { + RVI rvi = RVI.fromResourceFormat(graph, rvis); + Variable base = Variables.getConfigurationContext(graph, model); + Variable current = rvi.resolve(graph, base); + Variable subprocess = current.browse(graph, component); + subprocessRVI = subprocess.getRVI(graph); + } else { + // Not in a model configuration context. + // Probably in a component type configuration. + // Use the index root of the diagram to be opened as model[0] + // and leave subprocessRVI[0] as null. + model = graph.syncRequest(new PossibleIndexRoot(definedBy)); + } + + PlatformUI.getWorkbench().getDisplay().asyncExec(navigateToSubstructure(diagram, model, subprocessRVI)); + return true; + } + + private Runnable navigateToSubstructure(final Resource diagram, final Resource model, final RVI subprocessRVI) { + return new Runnable() { + @Override + public void run() { + String inputId = Long.toString(diagram.getResourceId()); + Map inputMap = new HashMap<>(); + inputMap.put(E4ResourceEditorConstants.KEY_RESOURCE, diagram); + inputMap.put(E4ResourceEditorConstants.KEY_MODEL, model); + inputMap.put(E4ResourceEditorConstants.KEY_RVI, subprocessRVI); + E4WorkbenchUtils.openEditor(part.getElementId(), "", "", inputId, inputMap); + } + }; + } + +}