/******************************************************************************* * Copyright (c) 2007, 2011 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.charts.editor; 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.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.eclipse.jface.viewers.ISelection; import org.simantics.Simantics; import org.simantics.charts.query.AddChartItem; import org.simantics.charts.query.ChartItemDescriptor; import org.simantics.charts.ui.AddVariableToChartAction; import org.simantics.charts.ui.ChartDropActionFactory; 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.common.request.UnaryRead; 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.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; import org.simantics.g2d.dnd.IDragItem; import org.simantics.g2d.dnd.IDropTargetParticipant; import org.simantics.modeling.ModelingResources; import org.simantics.modeling.PropertyVariables; import org.simantics.modeling.PropertyVariablesImpl; 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.ui.ErrorLogger; import org.simantics.utils.ui.ISelectionUtils; import org.simantics.utils.ui.dialogs.ShowMessage; /** * @author Tuukka Lehtonen */ public class SubscriptionDropParticipant extends AbstractDiagramParticipant implements IDropTargetParticipant { private static class SubscriptionItemDragItem extends DragItem { public SubscriptionItemDragItem(ChartItemDescriptor obj) { super(obj); } } private static class VariableReferenceDragItem extends DragItem { public VariableReferenceDragItem(VariableReference obj) { super(obj); } } Resource container; Resource model; public SubscriptionDropParticipant(Resource container) { this.container = container; try { model = Simantics.getSession().sync( new PossibleModel( container ) ); } catch (DatabaseException e) { } } @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(); return; } // Ensure the content is usable try { Transferable t = dtde.getTransferable(); Object data = t.getTransferData(LocalObjectTransferable.FLAVOR); data = LocalObjectTransfer.getTransfer().getObject(); List items = new ArrayList(); final List resources = ISelectionUtils.getPossibleKeys(data, SelectionHints.KEY_MAIN, Resource.class); if (!resources.isEmpty()) { // Support SubscriptionItem drags items.addAll( Simantics.getSession().syncRequest(new Read>() { @Override public List perform(ReadGraph graph) throws DatabaseException { List result = new ArrayList(); //Layer0 L0 = Layer0.getInstance(graph); 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)) result.add( new SubscriptionItemDragItem( AddChartItem.createDescriptor(graph, r) ) ); } } } return result; } }) ); } if(data instanceof RVI) { VariableReferenceDragItem vrdi = new VariableReferenceDragItem(Simantics.getSession().sync(new UnaryRead((RVI)data) { @Override public VariableReference perform(ReadGraph graph) throws DatabaseException { return new VariableReference(parameter, Variables.getDatatype(graph, model, parameter), null); } })); items.add( vrdi ); } else { // Variable/PropertyVariable are mutually exclusive List varItems = null; // 1st try Variable final List vars2 = ISelectionUtils.getPossibleKeys(data, SelectionHints.KEY_MAIN, Variable.class); if (!vars2.isEmpty()) { varItems = Simantics.getSession().syncRequest( new Read>() { @Override public List perform(ReadGraph graph) throws DatabaseException { return toDragItems( graph.syncRequest(VariableReferences.variablesToReferences(model, vars2)) ); } } ); } if (varItems == null || varItems.isEmpty()) { // Try legacy PropertyVariables final List vars = ISelectionUtils.getPossibleKeys(data, SelectionHints.KEY_MAIN, PropertyVariables.class); if (!vars.isEmpty()) { varItems = Simantics.getSession().syncRequest( new Read>() { @Override public List perform(ReadGraph graph) throws DatabaseException { List vars2 = PropertyVariablesImpl.resolve(graph, vars); return toDragItems( graph.syncRequest(VariableReferences.toReferences(model, vars2)) ); } } ); } } if (varItems != null) items.addAll(varItems); // Try WorkbenchSelectionElement if (data instanceof ISelection) { final List wses = ISelectionUtils.filterSelection((ISelection)data, WorkbenchSelectionElement.class); if (!wses.isEmpty()) { items.addAll( Simantics.getSession().syncRequest( new Read>() { @Override public List perform(ReadGraph graph) throws DatabaseException { List wsevars = new ArrayList(); ChartVariable av = new ChartVariable(graph); for(WorkbenchSelectionElement wse : wses) { Variable v = wse.getContent(av); if(v != null) { wsevars.add(v); } } return toDragItems( graph.syncRequest(VariableReferences.variablesToReferences(model, wsevars)) ); } } ) ); } } } 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)) dp.remove(i); for (IDragItem i : dp.getItemsByClass(VariableReferenceDragItem.class)) dp.remove(i); } @Override public void dragOver(DropTargetDragEvent dtde, IDnDContext dp) { } @Override public void drop(DropTargetDropEvent dtde, IDnDContext dp) { // 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(); 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(); dtde.dropComplete(true); } catch (DatabaseException e) { ShowMessage.showError(e.getClass().getName(), e.getMessage()); dtde.dropComplete(true); } return; } dtde.rejectDrop(); } @Override public void dropActionChanged(DropTargetDragEvent dtde, IDnDContext dp) { dtde.acceptDrag( DnDConstants.ACTION_LINK ); } @Override public int getAllowedOps() { return DnDConstants.ACTION_LINK; } 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; } @Override public double getPriority() { return 10.0; } }