X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2FdiagramEditor%2Fe4%2FPopulateElementDropParticipant.java;h=4e7ac0ab815ab3b8605c5f67ed466018c69c047e;hp=73a2cd018c21cdcf692c2139d8b0cafb6d1c5bdf;hb=b4374193caf61635d382af556ec913bf278d53a8;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/e4/PopulateElementDropParticipant.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/e4/PopulateElementDropParticipant.java index 73a2cd018..4e7ac0ab8 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/e4/PopulateElementDropParticipant.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/e4/PopulateElementDropParticipant.java @@ -1,419 +1,425 @@ -/******************************************************************************* - * 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. 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() { - @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 picks = new ArrayList(); - 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 wses = new ArrayList(); - - 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 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; - } - +/******************************************************************************* + * Copyright (c) 2007, 2020 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.eclipse.osgi.util.NLS; +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.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; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This participant populates Elements from ElementClass-resources drops + */ +public class PopulateElementDropParticipant extends AbstractDiagramParticipant implements IDropTargetParticipant { + + private static final Logger LOGGER = LoggerFactory.getLogger(PopulateElementDropParticipant.class); + + @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. 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() { + @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 NLS.bind(Messages.PopulateElementDropParticipant_CannotInstantiate, + new Object[] { NameUtils.getSafeName(graph, draggedResource), + NameUtils.getURIOrSafeNameInternal(graph, targetModel), + NameUtils.getURIOrSafeNameInternal(graph, sourceModel) }); + } + + // 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 Messages.PopulateElementDropParticipant_CannotCreateElementIntoDiagram; + } + } + + // 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 Messages.PopulateElementDropParticipant_CannotInstantiateUserComponent; + } + } + } + + 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 picks = new ArrayList(); + 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"); //$NON-NLS-1$ + + final IDiagram d = getHint(DiagramHints.KEY_DIAGRAM); + if (d == null) + return; + + IElement pick = tryPick(dtde.getLocation()); + if(pick != null) { + + final List wses = new ArrayList(); + + 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.error("symbolDropHandler invocation failed", 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 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, Messages.PopulateElementDropParticipant_ActivatorDiagramContentTrackingFailed, 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