-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.modeling.ui.diagramEditor.e4;\r
-\r
-import java.awt.Point;\r
-import java.awt.datatransfer.Transferable;\r
-import java.awt.datatransfer.UnsupportedFlavorException;\r
-import java.awt.dnd.DnDConstants;\r
-import java.awt.dnd.DropTargetDragEvent;\r
-import java.awt.dnd.DropTargetDropEvent;\r
-import java.awt.dnd.DropTargetEvent;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Point2D;\r
-import java.io.IOException;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-import java.util.Set;\r
-\r
-import org.eclipse.core.runtime.IAdaptable;\r
-import org.eclipse.core.runtime.IStatus;\r
-import org.eclipse.core.runtime.Status;\r
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;\r
-import org.eclipse.jface.viewers.IStructuredSelection;\r
-import org.simantics.Simantics;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.RequestProcessor;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.request.PossibleIndexRoot;\r
-import org.simantics.db.common.request.UniqueRead;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.common.utils.NameUtils;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.request.IsLinkedTo;\r
-import org.simantics.db.layer0.util.Layer0Utils;\r
-import org.simantics.db.service.SerialisationSupport;\r
-import org.simantics.diagram.Logger;\r
-import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;\r
-import org.simantics.diagram.content.Change;\r
-import org.simantics.diagram.content.DiagramContentChanges;\r
-import org.simantics.diagram.content.DiagramContentTracker;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.diagram.symbollibrary.ISymbolItem;\r
-import org.simantics.diagram.synchronization.runtime.DiagramSelectionUpdater;\r
-import org.simantics.diagram.ui.DiagramModelHints;\r
-import org.simantics.diagram.ui.ElementClassTransferable;\r
-import org.simantics.diagram.ui.ElementClassTransferable.ResourceElementClassTransferData;\r
-import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
-import org.simantics.g2d.diagram.DiagramHints;\r
-import org.simantics.g2d.diagram.DiagramUtils;\r
-import org.simantics.g2d.diagram.IDiagram;\r
-import org.simantics.g2d.diagram.handler.PickContext;\r
-import org.simantics.g2d.diagram.handler.PickRequest;\r
-import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;\r
-import org.simantics.g2d.dnd.DnDHints;\r
-import org.simantics.g2d.dnd.ElementClassDragItem;\r
-import org.simantics.g2d.dnd.IDnDContext;\r
-import org.simantics.g2d.dnd.IDragItem;\r
-import org.simantics.g2d.dnd.IDropTargetParticipant;\r
-import org.simantics.g2d.element.ElementClass;\r
-import org.simantics.g2d.element.ElementHints;\r
-import org.simantics.g2d.element.ElementUtils;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.g2d.participant.TransformUtil;\r
-import org.simantics.modeling.ModelingResources;\r
-import org.simantics.modeling.ui.Activator;\r
-import org.simantics.modeling.ui.diagramEditor.WSEDragItem;\r
-import org.simantics.scenegraph.g2d.snap.ISnapAdvisor;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-import org.simantics.ui.dnd.LocalObjectTransfer;\r
-import org.simantics.ui.dnd.LocalObjectTransferable;\r
-import org.simantics.ui.selection.WorkbenchSelectionElement;\r
-import org.simantics.ui.workbench.e4.E4WorkbenchUtils;\r
-import org.simantics.utils.logging.TimeLogger;\r
-\r
-/**\r
- * This participant populates Elements from ElementClass-resources drops\r
- */\r
-public class PopulateElementDropParticipant extends AbstractDiagramParticipant implements IDropTargetParticipant {\r
-\r
- @Dependency PickContext pickContext;\r
- @Dependency TransformUtil transformUtil;\r
- \r
- protected GraphToDiagramSynchronizer synchronizer;\r
- protected MPart part;\r
-\r
- public PopulateElementDropParticipant(GraphToDiagramSynchronizer synchronizer) {\r
- this(synchronizer, null);\r
- }\r
-\r
- public PopulateElementDropParticipant(GraphToDiagramSynchronizer synchronizer, MPart part) {\r
- this.synchronizer = synchronizer;\r
- this.part = part;\r
- }\r
-\r
- @Override\r
- public void dragEnter(DropTargetDragEvent dtde, IDnDContext dp) {\r
- if (diagram == null)\r
- return;\r
-\r
- Transferable tr = dtde.getTransferable();\r
- if (tr.isDataFlavorSupported(LocalObjectTransferable.FLAVOR)) {\r
- // System.out.println("joo");\r
- Object obj = null;\r
-\r
- // This must be done to have SWT transfer set the source data\r
- try {\r
- obj = tr.getTransferData(LocalObjectTransferable.FLAVOR);\r
- // System.out.println("GOT FROM AWT: " + obj);\r
- } catch (UnsupportedFlavorException e) {\r
- // TODO Auto-generated catch block\r
- e.printStackTrace();\r
- } catch (IOException e) {\r
- // TODO Auto-generated catch block\r
- e.printStackTrace();\r
- }\r
-\r
- // Check SWT\r
- if (!(obj instanceof IStructuredSelection)) {\r
- obj = LocalObjectTransfer.getTransfer().getObject();\r
- // System.out.println("GOT FROM SWT: " + obj);\r
- }\r
-\r
- if (obj instanceof IStructuredSelection) {\r
- IStructuredSelection sel = (IStructuredSelection) obj;\r
- if (!sel.isEmpty()) {\r
- for (Object elm : sel.toList()) {\r
- if (elm instanceof IAdaptable) {\r
- ElementClass ec = (ElementClass) ((IAdaptable) elm).getAdapter(ElementClass.class);\r
- if (ec != null) {\r
- dp.add(new ElementClassDragItem(ec));\r
- } else {\r
- Resource r = (Resource) ((IAdaptable) elm).getAdapter(Resource.class);\r
- if (r != null) {\r
- if (elm instanceof ISymbolItem) {\r
- /* FIXME fix this check \r
- ISymbolItem symbol = (ISymbolItem) elm;\r
- Resource dia = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);\r
- try {\r
- if (!DiagramTypeUtils.symbolAllowedOnDiagram(synchronizer.getSession(), symbol, dia)) {\r
- // Deny dragging of this symbol\r
- continue;\r
- }\r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- continue;\r
- }*/\r
- }\r
-\r
- try {\r
- String valid = validateDrop(synchronizer.getSession(), r,\r
- diagram.<Resource> getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE));\r
- if (valid == null) {\r
- ElementClassDragItem item = new ElementClassDragItem(synchronizer.getNodeClass(r));\r
- item.getHintContext().setHint(ElementHints.KEY_TRANSFORM, AffineTransform.getScaleInstance(1, 1));\r
- dp.add(item);\r
- }\r
- } catch (DatabaseException e) {\r
- // Ignore node-class retrieval failures.\r
- //System.out.println("error: " + e.getMessage());\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- // Let the default logic handle out how many columns to use.\r
- dp.getHints().removeHint(DnDHints.KEY_DND_GRID_COLUMNS);\r
- }\r
- }\r
-\r
- return;\r
- }\r
-\r
- if (tr.isDataFlavorSupported(ElementClassTransferable.FLAVOR)) {\r
- ResourceElementClassTransferData dada;\r
- try {\r
- dada = (ResourceElementClassTransferData) tr.getTransferData(ElementClassTransferable.FLAVOR);\r
- } catch (UnsupportedFlavorException e) {\r
- throw new Error(e);\r
- } catch (IOException e) {\r
- throw new Error(e);\r
- }\r
- Session s = synchronizer.getSession();\r
- try {\r
- for (String rid : dada.elementClassResourceRandomAccessReference) {\r
- SerialisationSupport support = s.getService(SerialisationSupport.class);\r
- Resource r = support.getResource(Long.parseLong(rid));\r
- dp.add(new ElementClassDragItem(synchronizer.getNodeClass(r)));\r
- }\r
- } catch (DatabaseException e) {\r
- throw new RuntimeException(e);\r
- }\r
-\r
- return;\r
- }\r
- }\r
-\r
- private String validateDrop(RequestProcessor processor, final Resource draggedResource, final Resource dropTarget) throws DatabaseException {\r
- return processor.syncRequest(new UniqueRead<String>() {\r
- @Override\r
- public String perform(ReadGraph graph) throws DatabaseException {\r
-// System.out.println("dragged resource: " + draggedResource);\r
-// System.out.println("drop target resource: " + dropTarget);\r
- Resource sourceModel = graph.syncRequest(new PossibleIndexRoot(draggedResource));\r
- Resource targetModel = graph.syncRequest(new PossibleIndexRoot(dropTarget));\r
-// System.out.println("source model: " + sourceModel);\r
-// System.out.println("target model: " + targetModel);\r
-\r
- // Prevent dragging data from one source model to another.\r
- // If source is not part of any model, everything is okay.\r
- if (sourceModel != null && !graph.syncRequest(new IsLinkedTo(targetModel, sourceModel))) {\r
- // Prevent a symbol instantiating within its own configuration.\r
- // NOTE: this doesn't handle transitive cycles.\r
- return "Cannot instantiate " + NameUtils.getSafeName(graph, draggedResource) + " into model "\r
- + NameUtils.getURIOrSafeNameInternal(graph, targetModel) + ". The source namespace ("\r
- + NameUtils.getURIOrSafeNameInternal(graph, sourceModel) + ") is not linked to the target model.";\r
- }\r
- \r
- // Prevent dragging to published components\r
- ModelingResources MOD = ModelingResources.getInstance(graph);\r
- StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
- Resource configuration = graph.getPossibleObject(dropTarget, MOD.DiagramToComposite);\r
- if (configuration != null) {\r
- Resource componentTypeFromDiagram = graph.getPossibleObject(configuration, STR.Defines);\r
- if(componentTypeFromDiagram != null) {\r
- if(Layer0Utils.isPublished(graph, componentTypeFromDiagram))\r
- return "Cannot create elements into a diagram that belongs to a published user component.";\r
- }\r
- }\r
-\r
- // Prevent dragging a symbol of component type into its own configuration.\r
- Resource componentTypeFromSymbol = graph.getPossibleObject(draggedResource, MOD.SymbolToComponentType);\r
- if (componentTypeFromSymbol != null) {\r
- if (configuration != null) {\r
- Resource componentTypeFromDiagram = graph.getPossibleObject(configuration, STR.Defines);\r
- if (componentTypeFromDiagram != null && componentTypeFromSymbol.equals(componentTypeFromDiagram)) {\r
- return "Cannot instantiate user component within its own configuration.";\r
- }\r
- }\r
- }\r
-\r
- return null;\r
- }\r
- });\r
- }\r
-\r
- @Override\r
- public void dragExit(DropTargetEvent dte, IDnDContext dp) {\r
- // System.out.println("exit");\r
- }\r
-\r
- @Override\r
- public void dragOver(DropTargetDragEvent dtde, IDnDContext dp) {\r
- // System.out.println("over");\r
- }\r
-\r
- private IElement tryPick(Point p) {\r
-\r
- Point2D canvas = transformUtil.controlToCanvas(p, null);\r
- \r
- assertDependencies();\r
-\r
- PickRequest req = new PickRequest(canvas);\r
- req.pickPolicy = PickRequest.PickPolicy.PICK_INTERSECTING_OBJECTS;\r
- List<IElement> picks = new ArrayList<IElement>();\r
- pickContext.pick(diagram, req, picks);\r
-\r
- if(picks.size() == 1) return picks.iterator().next();\r
- \r
- return null;\r
- \r
- }\r
-\r
- @Override\r
- public void drop(DropTargetDropEvent dtde, final IDnDContext dp) {\r
- TimeLogger.resetTimeAndLog(getClass(), "drop");\r
-\r
- final IDiagram d = getHint(DiagramHints.KEY_DIAGRAM);\r
- if (d == null)\r
- return;\r
-\r
- IElement pick = tryPick(dtde.getLocation()); \r
- if(pick != null) {\r
- \r
- final List<WorkbenchSelectionElement> wses = new ArrayList<WorkbenchSelectionElement>();\r
- \r
- for(IDragItem i : dp.toArray())\r
- if(i instanceof WSEDragItem)\r
- wses.add(((WSEDragItem)i).getObject());\r
-\r
- final Resource element = (Resource)ElementUtils.getData(d, pick);\r
- if(element != null && !wses.isEmpty()) {\r
- \r
- try {\r
- \r
- Simantics.getSession().syncRequest(new WriteRequest() {\r
-\r
- @Override\r
- public void perform(WriteGraph graph) throws DatabaseException {\r
- \r
- DiagramResource DIA = DiagramResource.getInstance(graph);\r
- \r
- Simantics.invokeSCLWrite(graph, element, DIA.symbolDropHandler, wses);\r
- \r
- }\r
- \r
- });\r
- \r
- } catch (DatabaseException e) {\r
- Logger.defaultLogError(e);\r
- }\r
- \r
- return;\r
- \r
- }\r
- \r
-\r
- }\r
- \r
- Runnable creator = () -> {\r
- DiagramUtils.mutateDiagram(d, m -> {\r
- IDragItem items[] = dp.toArray();\r
-\r
- for (IDragItem i : items) {\r
- if (!(i instanceof ElementClassDragItem))\r
- continue;\r
-\r
- ElementClassDragItem res = (ElementClassDragItem) i;\r
- ElementClass ec = res.getElementClass();\r
-\r
- Point2D pos = dp.getItemPosition(i);\r
- // System.out.println(pos);\r
- assert (pos != null);\r
-\r
- IElement element = m.newElement(ec);\r
- element.setHints(res.getHintContext().getHints());\r
-\r
- setupDroppedElement(element, pos);\r
-\r
- // Remove only the drag items we've processed.\r
- dp.remove(i);\r
- }\r
- });\r
- };\r
-\r
- selectNewDiagramContentAfter(d, part, creator);\r
-\r
- getContext().getContentContext().setDirty();\r
- }\r
-\r
- protected void selectNewDiagramContentAfter(IDiagram d, MPart activatePart, Runnable diagramModifier) {\r
- try {\r
- Resource diagramResource = d.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);\r
- final DiagramContentTracker tracker = diagramResource == null ? null\r
- : DiagramContentTracker.start(getContext(), Simantics.getSession(), diagramResource);\r
-\r
- diagramModifier.run();\r
-\r
- if (tracker != null) {\r
- // Get difference of diagram contents to find out what was added.\r
- DiagramContentChanges changes = tracker.update();\r
- Set<Resource> addedElements = changes.pick(changes.elements, Change.ADDED);\r
- if (!addedElements.isEmpty()) {\r
- new DiagramSelectionUpdater(getContext())\r
- .setNewSelection(0, addedElements)\r
- .setOneshot(true)\r
- .track();\r
- if (activatePart != null)\r
- E4WorkbenchUtils.activatePart(activatePart);\r
- }\r
- }\r
- } catch (DatabaseException e) {\r
- Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Diagram content change tracking failed.", e));\r
- }\r
- }\r
-\r
- protected void setupDroppedElement(IElement element, Point2D dropPos) {\r
- // This works only for elements without parents.\r
- ISnapAdvisor snapAdvisor = getContext().getHintStack().getHint(DiagramHints.SNAP_ADVISOR);\r
- if(snapAdvisor != null)\r
- snapAdvisor.snap(dropPos);\r
-\r
- IElement parent = element.getHint(ElementHints.KEY_PARENT_ELEMENT);\r
- if (parent != null) {\r
- Point2D parentPos = ElementUtils.getPos(parent);\r
- Point2D pos = new Point2D.Double(dropPos.getX() - parentPos.getX(), dropPos.getY() - parentPos.getY());\r
- ElementUtils.setPos(element, pos);\r
- } else {\r
- ElementUtils.setPos(element, dropPos);\r
- }\r
- }\r
-\r
- @Override\r
- public void dropActionChanged(DropTargetDragEvent dtde, IDnDContext dp) {\r
- dtde.acceptDrag(DnDConstants.ACTION_COPY);\r
- }\r
-\r
- @Override\r
- public int getAllowedOps() {\r
- return DnDConstants.ACTION_COPY;\r
- }\r
- \r
- @Override\r
- public double getPriority() {\r
- return 10.0;\r
- }\r
-\r
+/*******************************************************************************
+ * 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.e4;
+
+import java.awt.Point;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetEvent;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.PossibleIndexRoot;
+import org.simantics.db.common.request.UniqueRead;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.request.IsLinkedTo;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.db.service.SerialisationSupport;
+import org.simantics.diagram.Logger;
+import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;
+import org.simantics.diagram.content.Change;
+import org.simantics.diagram.content.DiagramContentChanges;
+import org.simantics.diagram.content.DiagramContentTracker;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.diagram.symbollibrary.ISymbolItem;
+import org.simantics.diagram.synchronization.runtime.DiagramSelectionUpdater;
+import org.simantics.diagram.ui.DiagramModelHints;
+import org.simantics.diagram.ui.ElementClassTransferable;
+import org.simantics.diagram.ui.ElementClassTransferable.ResourceElementClassTransferData;
+import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
+import org.simantics.g2d.diagram.DiagramHints;
+import org.simantics.g2d.diagram.DiagramUtils;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.handler.PickContext;
+import org.simantics.g2d.diagram.handler.PickRequest;
+import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
+import org.simantics.g2d.dnd.DnDHints;
+import org.simantics.g2d.dnd.ElementClassDragItem;
+import org.simantics.g2d.dnd.IDnDContext;
+import org.simantics.g2d.dnd.IDragItem;
+import org.simantics.g2d.dnd.IDropTargetParticipant;
+import org.simantics.g2d.element.ElementClass;
+import org.simantics.g2d.element.ElementHints;
+import org.simantics.g2d.element.ElementUtils;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.participant.TransformUtil;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.modeling.ui.Activator;
+import org.simantics.modeling.ui.diagramEditor.WSEDragItem;
+import org.simantics.scenegraph.g2d.snap.ISnapAdvisor;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.ui.dnd.LocalObjectTransfer;
+import org.simantics.ui.dnd.LocalObjectTransferable;
+import org.simantics.ui.selection.WorkbenchSelectionElement;
+import org.simantics.ui.workbench.e4.E4WorkbenchUtils;
+import org.simantics.utils.logging.TimeLogger;
+
+/**
+ * This participant populates Elements from ElementClass-resources drops
+ */
+public class PopulateElementDropParticipant extends AbstractDiagramParticipant implements IDropTargetParticipant {
+
+ @Dependency PickContext pickContext;
+ @Dependency TransformUtil transformUtil;
+
+ protected GraphToDiagramSynchronizer synchronizer;
+ protected MPart part;
+
+ public PopulateElementDropParticipant(GraphToDiagramSynchronizer synchronizer) {
+ this(synchronizer, null);
+ }
+
+ public PopulateElementDropParticipant(GraphToDiagramSynchronizer synchronizer, MPart part) {
+ this.synchronizer = synchronizer;
+ this.part = part;
+ }
+
+ @Override
+ public void dragEnter(DropTargetDragEvent dtde, IDnDContext dp) {
+ if (diagram == null)
+ return;
+
+ Transferable tr = dtde.getTransferable();
+ if (tr.isDataFlavorSupported(LocalObjectTransferable.FLAVOR)) {
+ // System.out.println("joo");
+ Object obj = null;
+
+ // This must be done to have SWT transfer set the source data
+ try {
+ obj = tr.getTransferData(LocalObjectTransferable.FLAVOR);
+ // System.out.println("GOT FROM AWT: " + obj);
+ } catch (UnsupportedFlavorException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ // Check SWT
+ if (!(obj instanceof IStructuredSelection)) {
+ obj = LocalObjectTransfer.getTransfer().getObject();
+ // System.out.println("GOT FROM SWT: " + obj);
+ }
+
+ if (obj instanceof IStructuredSelection) {
+ IStructuredSelection sel = (IStructuredSelection) obj;
+ if (!sel.isEmpty()) {
+ for (Object elm : sel.toList()) {
+ if (elm instanceof IAdaptable) {
+ ElementClass ec = (ElementClass) ((IAdaptable) elm).getAdapter(ElementClass.class);
+ if (ec != null) {
+ dp.add(new ElementClassDragItem(ec));
+ } else {
+ Resource r = (Resource) ((IAdaptable) elm).getAdapter(Resource.class);
+ if (r != null) {
+ if (elm instanceof ISymbolItem) {
+ /* FIXME fix this check
+ ISymbolItem symbol = (ISymbolItem) elm;
+ Resource dia = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);
+ try {
+ if (!DiagramTypeUtils.symbolAllowedOnDiagram(synchronizer.getSession(), symbol, dia)) {
+ // Deny dragging of this symbol
+ continue;
+ }
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ continue;
+ }*/
+ }
+
+ try {
+ String valid = validateDrop(synchronizer.getSession(), r,
+ diagram.<Resource> getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE));
+ if (valid == null) {
+ ElementClassDragItem item = new ElementClassDragItem(synchronizer.getNodeClass(r));
+ item.getHintContext().setHint(ElementHints.KEY_TRANSFORM, AffineTransform.getScaleInstance(1, 1));
+ dp.add(item);
+ }
+ } catch (DatabaseException e) {
+ // Ignore node-class retrieval failures.
+ //System.out.println("error: " + e.getMessage());
+ }
+ }
+ }
+ }
+ }
+
+ // Let the default logic handle out how many columns to use.
+ dp.getHints().removeHint(DnDHints.KEY_DND_GRID_COLUMNS);
+ }
+ }
+
+ return;
+ }
+
+ if (tr.isDataFlavorSupported(ElementClassTransferable.FLAVOR)) {
+ ResourceElementClassTransferData dada;
+ try {
+ dada = (ResourceElementClassTransferData) tr.getTransferData(ElementClassTransferable.FLAVOR);
+ } catch (UnsupportedFlavorException e) {
+ throw new Error(e);
+ } catch (IOException e) {
+ throw new Error(e);
+ }
+ Session s = synchronizer.getSession();
+ try {
+ for (String rid : dada.elementClassResourceRandomAccessReference) {
+ SerialisationSupport support = s.getService(SerialisationSupport.class);
+ Resource r = support.getResource(Long.parseLong(rid));
+ dp.add(new ElementClassDragItem(synchronizer.getNodeClass(r)));
+ }
+ } catch (DatabaseException e) {
+ throw new RuntimeException(e);
+ }
+
+ return;
+ }
+ }
+
+ private String validateDrop(RequestProcessor processor, final Resource draggedResource, final Resource dropTarget) throws DatabaseException {
+ return processor.syncRequest(new UniqueRead<String>() {
+ @Override
+ public String perform(ReadGraph graph) throws DatabaseException {
+// System.out.println("dragged resource: " + draggedResource);
+// System.out.println("drop target resource: " + dropTarget);
+ Resource sourceModel = graph.syncRequest(new PossibleIndexRoot(draggedResource));
+ Resource targetModel = graph.syncRequest(new PossibleIndexRoot(dropTarget));
+// System.out.println("source model: " + sourceModel);
+// System.out.println("target model: " + targetModel);
+
+ // Prevent dragging data from one source model to another.
+ // If source is not part of any model, everything is okay.
+ if (sourceModel != null && !graph.syncRequest(new IsLinkedTo(targetModel, sourceModel))) {
+ // Prevent a symbol instantiating within its own configuration.
+ // NOTE: this doesn't handle transitive cycles.
+ return "Cannot instantiate " + NameUtils.getSafeName(graph, draggedResource) + " into model "
+ + NameUtils.getURIOrSafeNameInternal(graph, targetModel) + ". The source namespace ("
+ + NameUtils.getURIOrSafeNameInternal(graph, sourceModel) + ") is not linked to the target model.";
+ }
+
+ // Prevent dragging to published components
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+ Resource configuration = graph.getPossibleObject(dropTarget, MOD.DiagramToComposite);
+ if (configuration != null) {
+ Resource componentTypeFromDiagram = graph.getPossibleObject(configuration, STR.Defines);
+ if(componentTypeFromDiagram != null) {
+ if(Layer0Utils.isPublished(graph, componentTypeFromDiagram))
+ return "Cannot create elements into a diagram that belongs to a published user component.";
+ }
+ }
+
+ // Prevent dragging a symbol of component type into its own configuration.
+ Resource componentTypeFromSymbol = graph.getPossibleObject(draggedResource, MOD.SymbolToComponentType);
+ if (componentTypeFromSymbol != null) {
+ if (configuration != null) {
+ Resource componentTypeFromDiagram = graph.getPossibleObject(configuration, STR.Defines);
+ if (componentTypeFromDiagram != null && componentTypeFromSymbol.equals(componentTypeFromDiagram)) {
+ return "Cannot instantiate user component within its own configuration.";
+ }
+ }
+ }
+
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public void dragExit(DropTargetEvent dte, IDnDContext dp) {
+ // System.out.println("exit");
+ }
+
+ @Override
+ public void dragOver(DropTargetDragEvent dtde, IDnDContext dp) {
+ // System.out.println("over");
+ }
+
+ private IElement tryPick(Point p) {
+
+ Point2D canvas = transformUtil.controlToCanvas(p, null);
+
+ assertDependencies();
+
+ PickRequest req = new PickRequest(canvas);
+ req.pickPolicy = PickRequest.PickPolicy.PICK_INTERSECTING_OBJECTS;
+ List<IElement> picks = new ArrayList<IElement>();
+ pickContext.pick(diagram, req, picks);
+
+ if(picks.size() == 1) return picks.iterator().next();
+
+ return null;
+
+ }
+
+ @Override
+ public void drop(DropTargetDropEvent dtde, final IDnDContext dp) {
+ TimeLogger.resetTimeAndLog(getClass(), "drop");
+
+ final IDiagram d = getHint(DiagramHints.KEY_DIAGRAM);
+ if (d == null)
+ return;
+
+ IElement pick = tryPick(dtde.getLocation());
+ if(pick != null) {
+
+ final List<WorkbenchSelectionElement> wses = new ArrayList<WorkbenchSelectionElement>();
+
+ for(IDragItem i : dp.toArray())
+ if(i instanceof WSEDragItem)
+ wses.add(((WSEDragItem)i).getObject());
+
+ final Resource element = (Resource)ElementUtils.getData(d, pick);
+ if(element != null && !wses.isEmpty()) {
+
+ try {
+
+ Simantics.getSession().syncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+
+ Simantics.invokeSCLWrite(graph, element, DIA.symbolDropHandler, wses);
+
+ }
+
+ });
+
+ } catch (DatabaseException e) {
+ Logger.defaultLogError(e);
+ }
+
+ return;
+
+ }
+
+
+ }
+
+ Runnable creator = () -> {
+ DiagramUtils.mutateDiagram(d, m -> {
+ IDragItem items[] = dp.toArray();
+
+ for (IDragItem i : items) {
+ if (!(i instanceof ElementClassDragItem))
+ continue;
+
+ ElementClassDragItem res = (ElementClassDragItem) i;
+ ElementClass ec = res.getElementClass();
+
+ Point2D pos = dp.getItemPosition(i);
+ // System.out.println(pos);
+ assert (pos != null);
+
+ IElement element = m.newElement(ec);
+ element.setHints(res.getHintContext().getHints());
+
+ setupDroppedElement(element, pos);
+
+ // Remove only the drag items we've processed.
+ dp.remove(i);
+ }
+ });
+ };
+
+ selectNewDiagramContentAfter(d, part, creator);
+
+ getContext().getContentContext().setDirty();
+ }
+
+ protected void selectNewDiagramContentAfter(IDiagram d, MPart activatePart, Runnable diagramModifier) {
+ try {
+ Resource diagramResource = d.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);
+ final DiagramContentTracker tracker = diagramResource == null ? null
+ : DiagramContentTracker.start(getContext(), Simantics.getSession(), diagramResource);
+
+ diagramModifier.run();
+
+ if (tracker != null) {
+ // Get difference of diagram contents to find out what was added.
+ DiagramContentChanges changes = tracker.update();
+ Set<Resource> addedElements = changes.pick(changes.elements, Change.ADDED);
+ if (!addedElements.isEmpty()) {
+ new DiagramSelectionUpdater(getContext())
+ .setNewSelection(0, addedElements)
+ .setOneshot(true)
+ .track();
+ if (activatePart != null)
+ E4WorkbenchUtils.activatePart(activatePart);
+ }
+ }
+ } catch (DatabaseException e) {
+ Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Diagram content change tracking failed.", e));
+ }
+ }
+
+ protected void setupDroppedElement(IElement element, Point2D dropPos) {
+ // This works only for elements without parents.
+ ISnapAdvisor snapAdvisor = getContext().getHintStack().getHint(DiagramHints.SNAP_ADVISOR);
+ if(snapAdvisor != null)
+ snapAdvisor.snap(dropPos);
+
+ IElement parent = element.getHint(ElementHints.KEY_PARENT_ELEMENT);
+ if (parent != null) {
+ Point2D parentPos = ElementUtils.getPos(parent);
+ Point2D pos = new Point2D.Double(dropPos.getX() - parentPos.getX(), dropPos.getY() - parentPos.getY());
+ ElementUtils.setPos(element, pos);
+ } else {
+ ElementUtils.setPos(element, dropPos);
+ }
+ }
+
+ @Override
+ public void dropActionChanged(DropTargetDragEvent dtde, IDnDContext dp) {
+ dtde.acceptDrag(DnDConstants.ACTION_COPY);
+ }
+
+ @Override
+ public int getAllowedOps() {
+ return DnDConstants.ACTION_COPY;
+ }
+
+ @Override
+ public double getPriority() {
+ return 10.0;
+ }
+
}
\ No newline at end of file