package org.simantics.modeling.ui.diagramEditor; import java.util.ArrayList; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.ui.IWorkbenchPartSite; import org.simantics.Simantics; import org.simantics.browsing.ui.swt.AdaptableHintContext; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ResourceRead; import org.simantics.db.common.request.ResourceRead2; import org.simantics.db.common.utils.RequestUtil; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.SelectionHints; import org.simantics.db.layer0.request.PossibleModel; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.Variables; import org.simantics.diagram.Logger; import org.simantics.diagram.flag.FlagUtil; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.diagram.ui.DiagramModelHints; import org.simantics.diagram.ui.WorkbenchSelectionProvider; import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.element.ElementHints; import org.simantics.g2d.element.ElementUtils; import org.simantics.g2d.element.IElement; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; import org.simantics.ui.SimanticsUI; import org.simantics.ui.selection.AnyResource; import org.simantics.ui.selection.AnyVariable; import org.simantics.ui.selection.WorkbenchSelectionContentType; import org.simantics.utils.DataContainer; import org.simantics.utils.threads.IThreadWorkQueue; import org.simantics.utils.ui.ErrorLogger; /** * @author Antti Villberg */ public class DiagramViewerSelectionProvider extends WorkbenchSelectionProvider { protected static class SelectionElement extends AdaptableHintContext { final public Resource runtime; final public Resource element; public SelectionElement(Key[] keys, Resource runtime, Resource element) { super(keys); this.runtime = runtime; this.element = element; } @SuppressWarnings("unchecked") @Override public T getContent(WorkbenchSelectionContentType contentType) { if(contentType instanceof AnyResource) return (T)element; else if(contentType instanceof AnyVariable) { AnyVariable type = (AnyVariable)contentType; try { return (T) type.processor.sync(new ResourceRead2(runtime, element) { @Override public Variable perform(ReadGraph graph) throws DatabaseException { DiagramResource DIA = DiagramResource.getInstance(graph); ModelingResources MOD = ModelingResources.getInstance(graph); Layer0 L0 = Layer0.getInstance(graph); String uri = graph.getPossibleRelatedValue(resource, DIA.RuntimeDiagram_HasVariable); if (uri == null) return null; Variable var = Variables.getPossibleVariable(graph, uri); if (var == null) return null; Resource config = graph.getPossibleObject(resource2, MOD.ElementToComponent); if (config == null) { if (graph.isInstanceOf(resource2, DIA.Connection)) { Variable v = FlagUtil.getPossibleConnectionSignal(graph, var, resource2, L0.Entity); if (v != null) return v; } // Apros #9646: if resource2 is the diagram // itself, return the diagram composite variable // since it is generally more useful than the // variable to the diagram. Resource composite = graph.getPossibleObject(resource2, MOD.DiagramToComposite); if (composite != null && composite.equals(var.getPossibleRepresents(graph))) { //return Variables.getPossibleVariable(graph, resource2); return var; } if(graph.isInstanceOf(resource2, DIA.Flag)) { Variable signal = FlagUtil.getPossibleFlagSignal(graph, var, resource2, L0.Entity); if(signal != null) return signal; } return null; } return var.browsePossible(graph, config); } }); } catch (DatabaseException e) { Logger.defaultLogError(e); } } return null; } } protected DataContainer sourceDiagram; public DiagramViewerSelectionProvider(IThreadWorkQueue queue, IWorkbenchPartSite site, DataContainer sourceDiagram) { super(queue, site); assert(sourceDiagram != null); this.sourceDiagram = sourceDiagram; } @Override protected ISelection constructAdaptableSelection(Iterable selection) { ArrayList objects = new ArrayList(); IDiagram diagram = sourceDiagram.get(); if (diagram != null) { Resource runtime = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE); Resource dr = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE); for (Object o : selection) { Resource resource = getSelectionResource(o); if (resource != null) { objects.add( constructSelectionElement(runtime, resource) ); } else { System.out.println(" unrecognized selection: " + o.getClass() + ": " + o); } } if (objects.isEmpty() && runtime != null && dr != null) { objects.add( constructSelectionElement(runtime, dr) ); } } return new StructuredSelection(objects); } protected Resource getSelectionResource(Object o) { if (o instanceof IElement) { IElement e = (IElement) o; Object object = e.getHint(ElementHints.KEY_OBJECT); if (object instanceof Resource) return (Resource) object; object = ElementUtils.adaptElement(e, Resource.class); if (object != null) return (Resource) object; } return null; } /** * @param runtime * @param object * @return */ protected static SelectionElement constructSelectionElement(Resource runtime, Resource object) { SelectionElement context = new SelectionElement(SelectionHints.STD_KEYS, runtime, object); context.setHint(SelectionHints.KEY_MAIN, object); if (runtime != null) { context.setHint(SelectionHints.KEY_VARIABLE_RESOURCE, runtime); try { Resource model = RequestUtil.trySyncRequest( Simantics.getSession(), SimanticsUI.UI_THREAD_REQUEST_START_TIMEOUT, SimanticsUI.UI_THREAD_REQUEST_EXECUTION_TIMEOUT, null, new ModelOfRuntime(runtime)); if (model != null) context.setHint(SelectionHints.KEY_MODEL, model); } catch (DatabaseException | InterruptedException ex) { ErrorLogger.defaultLogError(ex); } } return context; } private static class ModelOfRuntime extends ResourceRead { public ModelOfRuntime(Resource runtime) { super(runtime); } @Override public Resource perform(ReadGraph graph) throws DatabaseException { DiagramResource DIA = DiagramResource.getInstance(graph); String uri = graph.getPossibleRelatedValue(resource, DIA.RuntimeDiagram_HasModelURI); if (uri != null) { Resource resource = graph.getPossibleResource(uri); if(resource != null) return resource; } Resource diagram = graph.getPossibleObject(resource, DIA.RuntimeDiagram_HasConfiguration); if (diagram == null) return null; return graph.syncRequest(new PossibleModel(diagram)); } } }