/******************************************************************************* * Copyright (c) 2007, 2010 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 *******************************************************************************/ package org.simantics.modeling.ui.diagramEditor; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.eclipse.ui.PlatformUI; import org.simantics.Simantics; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.PossibleIndexRoot; import org.simantics.db.common.request.PossibleTypedParent; import org.simantics.db.common.request.ReadRequest; 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.diagram.stubs.DiagramResource; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.diagram.DiagramHints; import org.simantics.layer0.Layer0; import org.simantics.modeling.ComponentUtils; import org.simantics.modeling.ModelingResources; import org.simantics.modeling.actions.NavigateToTarget; import org.simantics.modeling.ui.Activator; import org.simantics.structural.stubs.StructuralResource2; import org.simantics.ui.workbench.editor.AbstractResourceEditorAdapter; import org.simantics.utils.datastructures.Pair; import org.simantics.utils.threads.ThreadUtils; /** * @author Tuukka Lehtonen */ public class OpenDiagramFromConfigurationAdapter extends AbstractResourceEditorAdapter { private static final String EDITOR_ID = "org.simantics.modeling.ui.diagramEditor"; //$NON-NLS-1$ public OpenDiagramFromConfigurationAdapter() { super(Messages.OpenDiagramFromConfigurationAdapter_DiagramEditor, Activator.COMPOSITE_ICON); } protected String getEditorId(ReadGraph g, Resource composite) throws DatabaseException { ModelingResources MOD = ModelingResources.getInstance(g); String preferredEditorId = g.getPossibleRelatedValue(composite, MOD.PreferredDiagramEditorID); if(preferredEditorId != null) return preferredEditorId; else return EDITOR_ID; } @Override public boolean canHandle(ReadGraph g, Resource r) throws DatabaseException { Resource diagram = getDiagram(g, r, Collections.emptySet()); if(diagram == null) return false; // Check if the diagram is locked, because of the locked component type return !isLocked(g, diagram); // return ComponentUtils.compositeHasDiagram(g, r) /*|| ComponentUtils.componentHasDiagram(g, r)*/; } public static boolean isLocked(ReadGraph g, Resource diagram) throws DatabaseException { StructuralResource2 STR = StructuralResource2.getInstance(g); Resource componentType = g.syncRequest(new PossibleTypedParent(diagram, STR.ComponentType)); if(componentType == null) return false; // Not part of a component type return g.hasStatement(componentType, STR.ComponentType_Locked); } @Override public void openEditor(final Resource r) throws Exception { Simantics.getSession().asyncRequest(new ReadRequest() { @Override public void run(ReadGraph g) throws DatabaseException { openEditor(g, r, getEditorId(g, r)); } }); } /** * @param g * @param configurationComposite * @param editorId * @throws DatabaseException */ public static boolean openEditor(ReadGraph g, Resource configurationComposite, final String editorId) throws DatabaseException { return openEditor(g, configurationComposite, editorId, Collections.emptySet()); } protected static Resource getDiagram(ReadGraph graph, Resource r, final Collection selectedObjects) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); if(graph.isInstanceOf(r, DIA.Diagram)) return r; Resource diagram = ComponentUtils.getPossibleCompositeDiagram(graph, r); if(diagram != null) return diagram; // TODO: what if the selected objects are from different diagrams? if (selectedObjects.size() > 0) { Set diagrams = new HashSet<>(); for (Object o : selectedObjects) { if (o instanceof Resource) { Resource res = (Resource)o; if (graph.isInstanceOf(res, DIA.Element)) { diagrams.add(graph.getPossibleObject(res, L0.PartOf)); } } } if (diagrams.size() == 1) { return diagrams.iterator().next(); } } return null; } public static Pair getModelAndRVI(ReadGraph graph, Resource configurationComposite) throws DatabaseException { Variable compositeVariable = Variables.getPossibleVariable(graph, configurationComposite); if (compositeVariable == null) return null; Layer0 L0 = Layer0.getInstance(graph); StructuralResource2 STR = StructuralResource2.getInstance(graph); boolean isComponentType = graph.hasStatement(configurationComposite, STR.Defines); Resource rviContext = graph.syncRequest(new PossibleTypedParent(configurationComposite, L0.RVIContext)); if (isComponentType || rviContext == null) { Resource indexRoot = graph.sync(new PossibleIndexRoot(configurationComposite)); if (indexRoot == null) return null; return Pair.make(indexRoot, null); } final Resource model = Variables.getPossibleModel(graph, compositeVariable); if (model == null) return null; final RVI rvi = compositeVariable.getPossibleRVI(graph); return Pair.make(model, rvi); } /** * @param g * @param configurationComposite * @param editorId * @param selectedObjects * @throws DatabaseException */ public static boolean openEditor(ReadGraph g, Resource r, String editorId, Collection selectedObjects) throws DatabaseException { Resource diagram = getDiagram(g, r, selectedObjects); Resource configurationComposite = diagram != null ? ComponentUtils.getPossibleDiagramComposite(g, diagram) : null; Pair modelAndRVI = configurationComposite != null ? getModelAndRVI(g, configurationComposite) : null; //System.out.println("modelAndRVI: " + modelAndRVI); if (modelAndRVI == null) return false; scheduleOpenEditor(editorId, diagram, modelAndRVI.first, modelAndRVI.second, selectedObjects); return true; } /** * @param g * @param configurationComposite * @param editorId * @param selectedObjects * @throws DatabaseException */ public static boolean openEditor(ReadGraph g, Resource r, String editorId, Collection selectedObjects, Resource model, RVI rvi) throws DatabaseException { Resource diagram = getDiagram(g, r, selectedObjects); if (diagram == null) return false; scheduleOpenEditor(editorId, diagram, model, rvi, selectedObjects); return true; } /** * @param g * @param configurationComposite * @param editorId * @param selectedObjects * @throws DatabaseException */ private static void scheduleOpenEditor(String editorId, Resource diagram, Resource model, RVI rvi, Collection selectedObjects) throws DatabaseException { Runnable editorActivator = NavigateToTarget.editorActivator(editorId, diagram, model, rvi, part -> { if (selectedObjects.isEmpty()) return; ICanvasContext openedCanvas = (ICanvasContext) part.getAdapter(ICanvasContext.class); assert openedCanvas != null; // CanvasContext-wide denial of initial zoom-to-fit on diagram open. openedCanvas.getDefaultHintContext().setHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT, Boolean.FALSE); ThreadUtils.asyncExec(openedCanvas.getThreadAccess(), NavigateToTarget.elementSelectorZoomer(openedCanvas, selectedObjects, false)); }); PlatformUI.getWorkbench().getDisplay().asyncExec(editorActivator); } }