From: Tuukka Lehtonen Date: Wed, 30 Nov 2016 13:48:51 +0000 (+0200) Subject: Added support for JSON PlainTextTransferable to charts and subscriptions X-Git-Tag: v1.25.0~22 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=777f66ad0fc587dd8d313705442dd2338c65ad30;p=simantics%2Fplatform.git Added support for JSON PlainTextTransferable to charts and subscriptions With these changes dragging JSON text using org.simantics.ui.dnd.PlainTextTransfer on top of model browser charts and subscriptions and also on a chart editor is now supported. The dragged JSON data must be in the following format:
{
    "type" : "variable",
    "uri" : "variable space URI to dragged entity",
    "defaultPropertyUri" : "variable space URI to default referenced
property variable of the dragged entity"
}
Only "type" and "defaultPropertyUri" keys are required. refs #6844 Change-Id: I3684a879a6c80bbff812166d14aa28eac5244663 --- diff --git a/bundles/org.simantics.charts/META-INF/MANIFEST.MF b/bundles/org.simantics.charts/META-INF/MANIFEST.MF index a0c30d589..3d289e419 100644 --- a/bundles/org.simantics.charts/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.charts/META-INF/MANIFEST.MF @@ -47,6 +47,7 @@ Require-Bundle: org.eclipse.ui, org.eclipse.e4.core.commands, org.eclipse.e4.ui.bindings;bundle-version="0.11.0", org.eclipse.e4.core.di.annotations, - org.eclipse.e4.core.services + org.eclipse.e4.core.services, + com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.2" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/editor/SubscriptionDropParticipant.java b/bundles/org.simantics.charts/src/org/simantics/charts/editor/SubscriptionDropParticipant.java index c410414d2..c41070934 100644 --- a/bundles/org.simantics.charts/src/org/simantics/charts/editor/SubscriptionDropParticipant.java +++ b/bundles/org.simantics.charts/src/org/simantics/charts/editor/SubscriptionDropParticipant.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Copyright (c) 2007, 2016 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 @@ -8,9 +8,11 @@ * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - JSON plain text input support *******************************************************************************/ package org.simantics.charts.editor; +import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; @@ -18,13 +20,18 @@ import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; import org.eclipse.jface.viewers.ISelection; import org.simantics.Simantics; +import org.simantics.charts.internal.JsonUtils; import org.simantics.charts.query.AddChartItem; import org.simantics.charts.query.ChartItemDescriptor; import org.simantics.charts.ui.AddVariableToChartAction; @@ -33,7 +40,9 @@ import org.simantics.charts.ui.ChartVariable; import org.simantics.databoard.util.ObjectUtils; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; +import org.simantics.db.Session; import org.simantics.db.common.request.UnaryRead; +import org.simantics.db.common.request.UniqueRead; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.SelectionHints; import org.simantics.db.layer0.request.PossibleModel; @@ -41,7 +50,6 @@ import org.simantics.db.layer0.variable.RVI; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.VariableReference; import org.simantics.db.layer0.variable.Variables; -import org.simantics.db.request.Read; import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant; import org.simantics.g2d.dnd.DragItem; import org.simantics.g2d.dnd.IDnDContext; @@ -54,6 +62,7 @@ import org.simantics.modeling.utils.VariableReferences; import org.simantics.ui.dnd.LocalObjectTransfer; import org.simantics.ui.dnd.LocalObjectTransferable; import org.simantics.ui.selection.WorkbenchSelectionElement; +import org.simantics.utils.FileUtils; import org.simantics.utils.ui.ErrorLogger; import org.simantics.utils.ui.ISelectionUtils; import org.simantics.utils.ui.dialogs.ShowMessage; @@ -88,12 +97,6 @@ public class SubscriptionDropParticipant extends AbstractDiagramParticipant impl @Override public void dragEnter(DropTargetDragEvent dtde, IDnDContext dp) { - // The transferable doesn't know LOT - if (!dtde.isDataFlavorSupported(LocalObjectTransferable.FLAVOR)) { - dtde.rejectDrag(); - return; - } - // The source cannot link, too bad if ((dtde.getSourceActions() & DnDConstants.ACTION_LINK) == 0) { dtde.rejectDrag(); @@ -101,26 +104,34 @@ public class SubscriptionDropParticipant extends AbstractDiagramParticipant impl } // Ensure the content is usable + if (dtde.isDataFlavorSupported(LocalObjectTransferable.FLAVOR)) { + dragEnterLocalObject(dtde, dp); + } else if (dtde.isDataFlavorSupported(DataFlavor.getTextPlainUnicodeFlavor())) { + dragEnterPlainText(dtde, dp); + } else { + dtde.rejectDrag(); + } + } + + private void dragEnterLocalObject(DropTargetDragEvent dtde, IDnDContext dp) { try { - Transferable t = dtde.getTransferable(); - Object data = t.getTransferData(LocalObjectTransferable.FLAVOR); + Object data = dtde.getTransferable().getTransferData(LocalObjectTransferable.FLAVOR); data = LocalObjectTransfer.getTransfer().getObject(); - List items = new ArrayList(); + List items = new ArrayList<>(); + Session session = Simantics.getSession(); final List resources = ISelectionUtils.getPossibleKeys(data, SelectionHints.KEY_MAIN, Resource.class); if (!resources.isEmpty()) { // Support SubscriptionItem drags - items.addAll( Simantics.getSession().syncRequest(new Read>() { + items.addAll( session.syncRequest(new UniqueRead>() { @Override public List perform(ReadGraph graph) throws DatabaseException { - List result = new ArrayList(); - //Layer0 L0 = Layer0.getInstance(graph); + List result = new ArrayList<>(); ModelingResources MOD = ModelingResources.getInstance(graph); Resource targetModel = graph.syncRequest(new PossibleModel(container)); if (targetModel != null) { for (Resource r : resources) { - //System.out.println( graph.getPossibleRelatedValue(r, L0.HasName) ); if (graph.isInstanceOf(r, MOD.Subscription_Item)) { Resource model = graph.syncRequest(new PossibleModel(r)); if (ObjectUtils.objectEquals(targetModel, model)) @@ -135,7 +146,7 @@ public class SubscriptionDropParticipant extends AbstractDiagramParticipant impl if(data instanceof RVI) { - VariableReferenceDragItem vrdi = new VariableReferenceDragItem(Simantics.getSession().sync(new UnaryRead((RVI)data) { + VariableReferenceDragItem vrdi = new VariableReferenceDragItem(session.sync(new UnaryRead((RVI)data) { @Override public VariableReference perform(ReadGraph graph) throws DatabaseException { return new VariableReference(parameter, Variables.getDatatype(graph, model, parameter), null); @@ -150,7 +161,7 @@ public class SubscriptionDropParticipant extends AbstractDiagramParticipant impl // 1st try Variable final List vars2 = ISelectionUtils.getPossibleKeys(data, SelectionHints.KEY_MAIN, Variable.class); if (!vars2.isEmpty()) { - varItems = Simantics.getSession().syncRequest( new Read>() { + varItems = session.syncRequest( new UniqueRead>() { @Override public List perform(ReadGraph graph) throws DatabaseException { return toDragItems( graph.syncRequest(VariableReferences.variablesToReferences(model, vars2)) ); @@ -161,7 +172,7 @@ public class SubscriptionDropParticipant extends AbstractDiagramParticipant impl // Try legacy PropertyVariables final List vars = ISelectionUtils.getPossibleKeys(data, SelectionHints.KEY_MAIN, PropertyVariables.class); if (!vars.isEmpty()) { - varItems = Simantics.getSession().syncRequest( new Read>() { + varItems = session.syncRequest( new UniqueRead>() { @Override public List perform(ReadGraph graph) throws DatabaseException { List vars2 = PropertyVariablesImpl.resolve(graph, vars); @@ -177,10 +188,10 @@ public class SubscriptionDropParticipant extends AbstractDiagramParticipant impl if (data instanceof ISelection) { final List wses = ISelectionUtils.filterSelection((ISelection)data, WorkbenchSelectionElement.class); if (!wses.isEmpty()) { - items.addAll( Simantics.getSession().syncRequest( new Read>() { + items.addAll( session.syncRequest( new UniqueRead>() { @Override public List perform(ReadGraph graph) throws DatabaseException { - List wsevars = new ArrayList(); + List wsevars = new ArrayList<>(); ChartVariable av = new ChartVariable(graph); for(WorkbenchSelectionElement wse : wses) { Variable v = wse.getContent(av); @@ -214,6 +225,40 @@ public class SubscriptionDropParticipant extends AbstractDiagramParticipant impl } } + private void dragEnterPlainText(DropTargetDragEvent dtde, IDnDContext dp) { + try { + DataFlavor flavor = DataFlavor.getTextPlainUnicodeFlavor(); + String flavorCharset = flavor.getParameter("charset"); + Transferable t = dtde.getTransferable(); + InputStream in = (InputStream) t.getTransferData(flavor); + String data = FileUtils.getContents(in, Charset.forName(flavorCharset)); + + List items = new ArrayList<>(); + Session session = Simantics.getSession(); + Optional v = JsonUtils.tryParseJsonPropertyVariable(session, data); + if (v.isPresent()) { + items.addAll( toDragItems( session.syncRequest(VariableReferences.variablesToReferences(model, Collections.singletonList(v.get()))) ) ); + } + + if (items.isEmpty()) { + dtde.rejectDrag(); + } else { + // Accept, make sure it is Link + for (IDragItem i : items) + dp.add(i); + dtde.acceptDrag( DnDConstants.ACTION_LINK ); + } + } catch (UnsupportedFlavorException e) { + throw new RuntimeException(e); + } catch (IOException e) { + ErrorLogger.defaultLogError(e); + dtde.rejectDrag(); + } catch (DatabaseException e) { + ErrorLogger.defaultLogError(e); + dtde.rejectDrag(); + } + } + @Override public void dragExit(DropTargetEvent dte, IDnDContext dp) { for (IDragItem i : dp.getItemsByClass(SubscriptionItemDragItem.class)) @@ -228,30 +273,23 @@ public class SubscriptionDropParticipant extends AbstractDiagramParticipant impl @Override public void drop(DropTargetDropEvent dtde, IDnDContext dp) { - // Subscription Item + // Subscription Item Collection subs = dp.getItemsByClass(SubscriptionItemDragItem.class); if (!subs.isEmpty()) { - List cicr = new ArrayList(); - for (SubscriptionItemDragItem sidi : subs) { - cicr.add(sidi.getObject()); - } - ChartDropActionFactory.addPlots(container, cicr, Collections.emptySet()).run(); + ChartDropActionFactory.addPlots(container, + subs.stream().map(DragItem::getObject).collect(Collectors.toList()), + Collections.emptySet()).run(); dtde.dropComplete(true); return; } - + // Variable Reference Collection vrdis = dp.getItemsByClass(VariableReferenceDragItem.class); if (!vrdis.isEmpty()) { - List refs = new ArrayList(); - for (VariableReferenceDragItem vrdi : vrdis) { - refs.add( vrdi.getObject() ); - } - Resource chart = container; try { - AddVariableToChartAction a = new AddVariableToChartAction( chart, null, refs ); - a.init(); - a.run(); + new AddVariableToChartAction( container, null, + vrdis.stream().map(DragItem::getObject).collect(Collectors.toList()) ) + .init().run(); dtde.dropComplete(true); } catch (DatabaseException e) { ShowMessage.showError(e.getClass().getName(), e.getMessage()); @@ -259,7 +297,7 @@ public class SubscriptionDropParticipant extends AbstractDiagramParticipant impl } return; } - + dtde.rejectDrop(); } @@ -274,14 +312,9 @@ public class SubscriptionDropParticipant extends AbstractDiagramParticipant impl } private static List toDragItems(Collection references) { - List result = new ArrayList(references.size()); - for (VariableReference vr : references) { - VariableReferenceDragItem di = new VariableReferenceDragItem( vr ); - result.add( di ); - } - return result; + return references.stream().map(VariableReferenceDragItem::new).collect(Collectors.toList()); } - + @Override public double getPriority() { return 10.0; diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/internal/JsonUtils.java b/bundles/org.simantics.charts/src/org/simantics/charts/internal/JsonUtils.java new file mode 100644 index 000000000..31861ea27 --- /dev/null +++ b/bundles/org.simantics.charts/src/org/simantics/charts/internal/JsonUtils.java @@ -0,0 +1,71 @@ +package org.simantics.charts.internal; + +import java.io.IOException; +import java.util.Optional; + +import org.simantics.db.ReadGraph; +import org.simantics.db.RequestProcessor; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.layer0.variable.Variables; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; + +/** + * @author Tuukka Lehtonen + * + */ +public class JsonUtils { + + public static Optional tryParseJsonPropertyVariable(RequestProcessor processor, String json) throws DatabaseException { + return processor.syncRequest(new UniqueRead>() { + @Override + public Optional perform(ReadGraph graph) throws DatabaseException { + return tryParseJsonPropertyVariable(graph, json); + } + }); + } + + public static Optional tryParseJsonPropertyVariable(ReadGraph graph, String json) throws DatabaseException { + try (JsonParser jp = new JsonFactory().createParser(json)) { + return JsonUtils.readPossibleVariable(graph, jp); + } catch (IOException e) { + throw new DatabaseException(e); + } + } + + public static Optional readPossibleVariable(ReadGraph graph, JsonParser jp) throws IOException, DatabaseException { + Optional uri = readPossibleVariableUri(jp); + return uri.isPresent() ? Optional.ofNullable(Variables.getPossibleVariable(graph, uri.get())) : Optional.empty(); + } + + public static Optional readPossibleVariableUri(JsonParser jp) throws IOException { + // Sanity check: verify that we got "Json Object": + if (jp.nextToken() != JsonToken.START_OBJECT) + throw new IOException("Expected data to start with an Object"); + + String uri = null; + String type = null; + String defaultPropertyUri = null; + + while (jp.nextToken() != JsonToken.END_OBJECT) { + String fieldName = jp.getCurrentName(); + jp.nextToken(); + if (fieldName.equals("uri")) { + uri = jp.getValueAsString(); + } else if (fieldName.equals("type")) { + type = jp.getValueAsString(); + } else if (fieldName.equals("defaultPropertyUri")) { + defaultPropertyUri = jp.getValueAsString(); + } + } + + return Optional.ofNullable("Variable".equals(type) ? + defaultPropertyUri != null ? defaultPropertyUri : uri + : null); + } + +} diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/ui/AddVariableToChartAction.java b/bundles/org.simantics.charts/src/org/simantics/charts/ui/AddVariableToChartAction.java index 994624a8b..4caa80a66 100644 --- a/bundles/org.simantics.charts/src/org/simantics/charts/ui/AddVariableToChartAction.java +++ b/bundles/org.simantics.charts/src/org/simantics/charts/ui/AddVariableToChartAction.java @@ -65,7 +65,7 @@ public class AddVariableToChartAction implements Runnable { * * @throws DatabaseException */ - public void init() throws DatabaseException + public AddVariableToChartAction init() throws DatabaseException { Simantics.getSession().sync( new ReadRequest() { @Override @@ -73,6 +73,7 @@ public class AddVariableToChartAction implements Runnable { init(g); } } ); + return this; } /** @@ -80,7 +81,7 @@ public class AddVariableToChartAction implements Runnable { * * @throws DatabaseException */ - public void init( ReadGraph g ) throws DatabaseException + public AddVariableToChartAction init( ReadGraph g ) throws DatabaseException { Layer0 L0 = Layer0.getInstance(g); if(chart != null) { @@ -103,6 +104,8 @@ public class AddVariableToChartAction implements Runnable { variableReferences.add( var.getVariableId().toPossibleString(g, configuration) ); } } + + return this; } /** diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/ui/ChartDropActionFactory.java b/bundles/org.simantics.charts/src/org/simantics/charts/ui/ChartDropActionFactory.java index 648336b67..db93f33e4 100644 --- a/bundles/org.simantics.charts/src/org/simantics/charts/ui/ChartDropActionFactory.java +++ b/bundles/org.simantics.charts/src/org/simantics/charts/ui/ChartDropActionFactory.java @@ -13,12 +13,16 @@ package org.simantics.charts.ui; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import org.eclipse.jface.viewers.ISelection; import org.simantics.Simantics; +import org.simantics.charts.internal.JsonUtils; import org.simantics.charts.ontology.ChartResource; import org.simantics.charts.query.AddChartItem; import org.simantics.charts.query.ChartItemDescriptor; @@ -43,7 +47,6 @@ import org.simantics.modeling.PropertyVariablesImpl; import org.simantics.modeling.utils.VariableReferences; import org.simantics.trend.configuration.TrendItem.Renderer; import org.simantics.ui.selection.WorkbenchSelectionElement; -import org.simantics.utils.datastructures.collections.CollectionUtils; import org.simantics.utils.ui.ErrorLogger; import org.simantics.utils.ui.ISelectionUtils; @@ -62,71 +65,41 @@ public class ChartDropActionFactory implements DropActionFactory { if (targetModel == null) return null; if(source instanceof RVI) { - - RVI rvi = (RVI)source; - List refs = CollectionUtils.toList(new VariableReference(rvi, SubscriptionDropActionFactory.getDatatype(g, targetModel, rvi), null)); - - AddVariableToChartAction a = new AddVariableToChartAction(chart, null, refs); - a.init(g); - return a; - + List refs = Collections.singletonList(new VariableReference((RVI)source, + SubscriptionDropActionFactory.getDatatype(g, targetModel, (RVI) source), null)); + return new AddVariableToChartAction(chart, null, refs).init(g); } - + List vars = ISelectionUtils.getPossibleKeys(source, SelectionHints.KEY_MAIN, PropertyVariables.class); if (!vars.isEmpty()) { // FIXME: this is a hack for indexed value support vars = PropertyVariablesImpl.resolve(g, vars); - List references2 = g.syncRequest(VariableReferences.toReferences(targetModel, vars)); - List references = new ArrayList(); - for (VariableReference ref : references2) { - if (ref.datatype instanceof BooleanType || ref.datatype instanceof NumberType) { - references.add(ref); - } - } - - AddVariableToChartAction a = new AddVariableToChartAction(chart, null, references); - a.init(g); - return a; + List references = toPropertyReferences(g, targetModel, vars); + if (!references.isEmpty()) + return new AddVariableToChartAction(chart, null, references).init(g); } - final List vars2 = ISelectionUtils.getPossibleKeys(source, SelectionHints.KEY_MAIN, Variable.class); + + List vars2 = ISelectionUtils.getPossibleKeys(source, SelectionHints.KEY_MAIN, Variable.class); if (!vars2.isEmpty()) { - // FIXME: this is a hack for indexed value support - List references2 = g.syncRequest(VariableReferences.variablesToReferences(targetModel, vars2)); - List references = new ArrayList(); - for (VariableReference ref : references2) { - if (ref.datatype instanceof BooleanType || ref.datatype instanceof NumberType) { - references.add(ref); - } - } - AddVariableToChartAction a = new AddVariableToChartAction(chart, null, references); - a.init(g); - return a; + List references = toReferences(g, targetModel, vars2); + if (!references.isEmpty()) + return new AddVariableToChartAction(chart, null, references).init(g); } if(source instanceof ISelection) { List wses = ISelectionUtils.filterSelection((ISelection)source, WorkbenchSelectionElement.class); if (!wses.isEmpty()) { - List wsevars = new ArrayList(); + List wsevars = new ArrayList<>(); ChartVariable av = new ChartVariable(g); for(WorkbenchSelectionElement wse : wses) { Variable v = wse.getContent(av); - if(v != null) { + if(v != null) wsevars.add(v); - } } + List references = toReferences(g, targetModel, wsevars); if (!wsevars.isEmpty()) { - // FIXME: this is a hack for indexed value support - List references2 = g.syncRequest(VariableReferences.variablesToReferences(targetModel, wsevars)); - List references = new ArrayList(); - for (VariableReference ref : references2) { - if (ref.datatype instanceof BooleanType || ref.datatype instanceof NumberType) { - references.add(ref); - } - } - AddVariableToChartAction a = new AddVariableToChartAction(chart, null, references); - a.init(g); - return a; + return new AddVariableToChartAction(chart, null, references).init(g); } } } @@ -158,22 +131,48 @@ public class ChartDropActionFactory implements DropActionFactory { return addPlots(chart, newItems, movedPlots); } + if (source instanceof String) { + // JSON ? + Optional v = JsonUtils.tryParseJsonPropertyVariable(g, (String) source); + if (v.isPresent()) { + List references = toReferences(g, targetModel, Collections.singletonList(v.get())); + if (!references.isEmpty()) + return new AddVariableToChartAction(chart, null, references).init(g); + } + } + return null; } - public static Runnable addPlots(final Resource chart, final List references, final Set movedPlots) { - return new Runnable() { - @Override - public void run() { - Simantics.getSession().asyncRequest( - AddChartItem.addAndMoveChartItems(chart, references, movedPlots), - new ProcedureAdapter>() { - @Override - public void exception(Throwable e) { + private static List toReferences(ReadGraph graph, Resource contextIndexRoot, List variables) throws DatabaseException { + if (variables.isEmpty()) + return Collections.emptyList(); + return filterReferences( graph.syncRequest(VariableReferences.variablesToReferences(contextIndexRoot, variables)) ); + } + + private static List toPropertyReferences(ReadGraph graph, Resource contextIndexRoot, List variables) throws DatabaseException { + if (variables.isEmpty()) + return Collections.emptyList(); + return filterReferences( graph.syncRequest(VariableReferences.toReferences(contextIndexRoot, variables)) ); + } + + private static List filterReferences(List variables) throws DatabaseException { + return variables.stream() + .filter(ref -> ref.datatype instanceof BooleanType || ref.datatype instanceof NumberType) + .collect(Collectors.toList()); + } + + public static Runnable addPlots(Resource chart, List references, Set movedPlots) { + return () -> { + Simantics.getSession().asyncRequest( + AddChartItem.addAndMoveChartItems(chart, references, movedPlots), + new ProcedureAdapter>() { + @Override + public void exception(Throwable e) { + if (e != null) ErrorLogger.defaultLogError(e); - } - }); - } + } + }); }; } diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/ui/SubscriptionDropActionFactory.java b/bundles/org.simantics.charts/src/org/simantics/charts/ui/SubscriptionDropActionFactory.java index fe865cb8d..ee3975d95 100644 --- a/bundles/org.simantics.charts/src/org/simantics/charts/ui/SubscriptionDropActionFactory.java +++ b/bundles/org.simantics.charts/src/org/simantics/charts/ui/SubscriptionDropActionFactory.java @@ -14,10 +14,12 @@ package org.simantics.charts.ui; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import org.simantics.Simantics; import org.simantics.browsing.ui.common.ErrorLogger; +import org.simantics.charts.internal.JsonUtils; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.ObjectUtils; import org.simantics.db.ReadGraph; @@ -38,8 +40,6 @@ import org.simantics.modeling.ModelingResources; import org.simantics.modeling.PropertyVariables; import org.simantics.modeling.PropertyVariablesImpl; import org.simantics.modeling.utils.VariableReferences; -import org.simantics.utils.datastructures.Callback; -import org.simantics.utils.datastructures.collections.CollectionUtils; import org.simantics.utils.ui.ISelectionUtils; /** @@ -57,68 +57,64 @@ public class SubscriptionDropActionFactory implements DropActionFactory { Resource targetModel = g.syncRequest(new PossibleModel(subscription)); if(source instanceof RVI) { + RVI rvi = (RVI)source; + List refs = Collections.singletonList(new VariableReference(rvi, getDatatype(g, targetModel, rvi), null)); + return addSubscriptions(g, subscription, refs, Collections.emptySet()); + } - RVI rvi = (RVI)source; - List refs = CollectionUtils.toList(new VariableReference(rvi, getDatatype(g, targetModel, rvi), null)); - if (!refs.isEmpty()) - return addSubscriptions(g, subscription, refs, Collections.emptySet()); - + List vars = ISelectionUtils.getPossibleKeys(source, SelectionHints.KEY_MAIN, PropertyVariables.class); + if (!vars.isEmpty()) { + // FIXME: this is a hack for indexed value support + vars = PropertyVariablesImpl.resolve(g, vars); + List references = g.syncRequest(VariableReferences.toReferences(targetModel, vars)); + if (!references.isEmpty()) + return addSubscriptions(g, subscription, references, Collections.emptySet()); } else { - - List vars = ISelectionUtils.getPossibleKeys(source, SelectionHints.KEY_MAIN, PropertyVariables.class); - if (!vars.isEmpty()) { - // FIXME: this is a hack for indexed value support - vars = PropertyVariablesImpl.resolve(g, vars); + List srcs = ISelectionUtils.getPossibleKeys(source, SelectionHints.KEY_MAIN, Resource.class); + ModelingResources MOD = ModelingResources.getInstance(g); + Set movedItems = new HashSet<>(); + for (Resource src : srcs) { + if (g.isInstanceOf(src, MOD.Subscription_Item)) { + Resource model = g.syncRequest(new PossibleModel(src)); + if (ObjectUtils.objectEquals(targetModel, model)) + movedItems.add(src); + } + } + if (!movedItems.isEmpty()) + return addSubscriptions(g, subscription, Collections.emptyList(), movedItems); + } - List references = g.syncRequest(VariableReferences.toReferences(targetModel, vars)); - if (!references.isEmpty()) - return addSubscriptions(g, subscription, references, Collections.emptySet()); - } else { - List srcs = ISelectionUtils.getPossibleKeys(source, SelectionHints.KEY_MAIN, Resource.class); - ModelingResources MOD = ModelingResources.getInstance(g); - Set movedItems = new HashSet(); - for (Resource src : srcs) { - if (g.isInstanceOf(src, MOD.Subscription_Item)) { - Resource model = g.syncRequest(new PossibleModel(src)); - if (ObjectUtils.objectEquals(targetModel, model)) - movedItems.add(src); - } - } - if (!movedItems.isEmpty()) - return addSubscriptions(g, subscription, Collections.emptyList(), movedItems); - } - + if (source instanceof String) { + // JSON ? + Optional v = JsonUtils.tryParseJsonPropertyVariable(g, (String) source); + if (v.isPresent()) { + List references = g.syncRequest(VariableReferences.variablesToReferences(targetModel, Collections.singletonList(v.get()))); + return addSubscriptions(g, subscription, references, Collections.emptySet()); + } } return null; } - private Runnable addSubscriptions(ReadGraph graph, final Resource subscription, final List references, - final Set movedSubscriptionItems) throws DatabaseException { - final AddVariableToChartAction action = new AddVariableToChartAction(null, subscription, references); - action.init(graph); - return new Runnable() { - @Override - public void run() { - action.run(); - if(!movedSubscriptionItems.isEmpty()) { - Simantics.getSession().asyncRequest(new WriteRequest() { - @Override - public void perform(WriteGraph graph) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - for (Resource item : movedSubscriptionItems) { - graph.deny(item, L0.PartOf); - graph.claim(subscription, L0.ConsistsOf, item); - } - } - }, new Callback() { - @Override - public void run(DatabaseException e) { - if (e != null) - ErrorLogger.defaultLogError(e); + private Runnable addSubscriptions(ReadGraph graph, Resource subscription, List references, + Set movedSubscriptionItems) throws DatabaseException { + AddVariableToChartAction action = new AddVariableToChartAction(null, subscription, references).init(graph); + return () -> { + action.run(); + if(!movedSubscriptionItems.isEmpty()) { + Simantics.getSession().asyncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + for (Resource item : movedSubscriptionItems) { + graph.deny(item, L0.PartOf); + graph.claim(subscription, L0.ConsistsOf, item); } - }); - } + } + }, e -> { + if (e != null) + ErrorLogger.defaultLogError(e); + }); } }; } diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerSelectionProvider.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerSelectionProvider.java index 42c489e24..27e58b5d1 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerSelectionProvider.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerSelectionProvider.java @@ -65,6 +65,7 @@ public class DiagramViewerSelectionProvider extends WorkbenchSelectionProvider { 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) @@ -76,6 +77,11 @@ public class DiagramViewerSelectionProvider extends WorkbenchSelectionProvider { 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 @@ -87,7 +93,6 @@ public class DiagramViewerSelectionProvider extends WorkbenchSelectionProvider { } if(graph.isInstanceOf(resource2, DIA.Flag)) { - Layer0 L0 = Layer0.getInstance(graph); Variable signal = FlagUtil.getPossibleFlagSignal(graph, var, resource2, L0.Entity); if(signal != null) return signal; diff --git a/features/org.simantics.charts.feature/feature.xml b/features/org.simantics.charts.feature/feature.xml index 32d412a74..4e8dd9c07 100644 --- a/features/org.simantics.charts.feature/feature.xml +++ b/features/org.simantics.charts.feature/feature.xml @@ -39,4 +39,11 @@ version="0.0.0" unpack="false"/> + +