/******************************************************************************* * 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.ui; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.simantics.Simantics; import org.simantics.charts.ontology.ChartResource; import org.simantics.databoard.util.ObjectUtils; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.CommentMetadata; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.common.request.WriteResultRequest; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.SelectionHints; import org.simantics.db.layer0.adapter.DropActionFactory; import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor; import org.simantics.db.layer0.request.PossibleModel; import org.simantics.db.layer0.util.ClipboardUtils; import org.simantics.db.layer0.util.SimanticsClipboard.Representation; import org.simantics.db.layer0.util.SimanticsKeys; import org.simantics.graph.db.TransferableGraphs; import org.simantics.graph.representation.TransferableGraph1; import org.simantics.layer0.Layer0; import org.simantics.utils.datastructures.Callback; import org.simantics.utils.ui.ErrorLogger; import org.simantics.utils.ui.ISelectionUtils; import org.simantics.utils.ui.dialogs.ShowError; /** * @author Tuukka Lehtonen */ public class ChartGroupDropActionFactory implements DropActionFactory { @Override public Runnable create(ReadGraph graph, Object target, Object source, int operation) throws DatabaseException { final Resource chartGroup = ISelectionUtils.getSinglePossibleKey(target, SelectionHints.KEY_MAIN, Resource.class); if (chartGroup == null) return null; Resource targetModel = graph.syncRequest(new PossibleModel(chartGroup)); if (targetModel == null) return null; List srcs = ISelectionUtils.getPossibleKeys(source, SelectionHints.KEY_MAIN, Resource.class); Layer0 L0 = Layer0.getInstance(graph); ChartResource CHART = ChartResource.getInstance(graph); Set chartsToMove= new HashSet(); for (Resource res : srcs) { if (graph.isInstanceOf(res, CHART.Chart)) { Resource model = graph.syncRequest(new PossibleModel(res)); if (ObjectUtils.objectEquals(targetModel, model)) { Resource partOf = graph.getPossibleObject(res, L0.PartOf); if (!ObjectUtils.objectEquals(chartGroup, partOf)) { chartsToMove.add(res); } } } } if (!chartsToMove.isEmpty()) { String error = validateDrop(graph, chartGroup, chartsToMove); if (error != null) { ShowError.showError("Chart Drop Failed", error, (Exception) null); return null; } // TODO: support for move & copy return moveCharts(chartGroup, chartsToMove); } return null; } public static String validateDrop(ReadGraph graph, Resource chartGroup, Set chartsToMove) throws DatabaseException { StringBuilder sb = new StringBuilder(); String targetName = NameUtils.getSafeName(graph, chartGroup); Layer0 L0 = Layer0.getInstance(graph); // Verify that target doesn't contain charts names as in chartsToMove Set sourceNames = new HashSet(); for (Resource chart : chartsToMove) { String chartName = NameUtils.getSafeName(graph, chart); if (!sourceNames.add(chartName)) { sb.append("Multiple charts with same '" + chartName + "' cannot be moved into the same chart group.\n"); } } Set reservedNames = NameUtils.findReservedNames(graph, "", chartGroup, L0.ConsistsOf); for (String sourceName : sourceNames) { if (reservedNames.contains(sourceName)) { sb.append("Name '" + sourceName + "' already in use in target '" + targetName + "'.\n"); } } return (sb.length() == 0) ? null : sb.toString(); } public static Runnable moveCharts(final Resource chartGroup, final Set chartsToMove) { return new Runnable() { @Override public void run() { Simantics.getSession().asyncRequest(new WriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { graph.syncRequest(moveChartsRequest(chartGroup, chartsToMove)); } }, new Callback() { @Override public void run(DatabaseException e) { if (e != null) ErrorLogger.defaultLogError(e); } }); } }; } public static MoveCharts moveChartsRequest(Resource chartGroup, Set chartsToMove) { return new MoveCharts(chartGroup, chartsToMove); } public static class MoveCharts extends WriteResultRequest> { private Resource chartGroup; private Set chartsToMove; public MoveCharts(Resource chartGroup, Set chartsToMove) { this.chartGroup = chartGroup; this.chartsToMove = chartsToMove; } @Override public Collection perform(WriteGraph graph) throws DatabaseException { if (chartsToMove.isEmpty()) return Collections.emptyList(); CommentMetadata cm = graph.getMetadata(CommentMetadata.class); String targetName = NameUtils.getSafeName(graph, chartGroup); Layer0 L0 = Layer0.getInstance(graph); List result = new ArrayList(); for (Resource chart : chartsToMove) { graph.deny(chart, L0.PartOf); graph.claim(chartGroup, L0.ConsistsOf, chart); cm.add("Moved chart '" + NameUtils.getSafeLabel(graph, chart) + "' to chart group '" + targetName + "'"); result.add(chart); } graph.addMetadata(cm); return result; } } public static CopyCharts copyChartsRequest(Resource chartGroup, Set> sources) { return new CopyCharts(chartGroup, sources); } public static class CopyCharts extends WriteResultRequest> { private Resource chartGroup; private Set> sources; public CopyCharts(Resource chartGroup, Set> sources) { this.chartGroup = chartGroup; this.sources = sources; } @Override public Collection perform(WriteGraph graph) throws DatabaseException { if (sources.isEmpty()) return Collections.emptyList(); CommentMetadata cm = graph.getMetadata(CommentMetadata.class); String targetName = NameUtils.getSafeName(graph, chartGroup); List result = new ArrayList(); for (Set r : sources) { Collection srcs = ClipboardUtils.accept(graph, r, SimanticsKeys.KEY_COPY_RESOURCES); for(Resource src : srcs) { TransferableGraph1 tg = ClipboardUtils.accept(graph, r, SimanticsKeys.KEY_TRANSFERABLE_GRAPH); DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(chartGroup); TransferableGraphs.importGraph1(graph, tg, advisor); cm.add("Copied chart '" + NameUtils.getSafeLabel(graph, src) + "' to chart group '" + targetName + "'"); result.addAll(advisor.getRoots()); } } graph.addMetadata(cm); return result; } } }