001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032: package com.vividsolutions.jump.workbench.ui.plugin.clipboard;
033:
034: import com.vividsolutions.jts.geom.Geometry;
035:
036: import com.vividsolutions.jump.coordsys.Reprojector;
037: import com.vividsolutions.jump.feature.BasicFeature;
038: import com.vividsolutions.jump.feature.Feature;
039: import com.vividsolutions.jump.feature.FeatureSchema;
040: import com.vividsolutions.jump.io.WKTReader;
041: import com.vividsolutions.jump.util.StringUtil;
042: import com.vividsolutions.jump.workbench.WorkbenchContext;
043: import com.vividsolutions.jump.workbench.model.Layer;
044: import com.vividsolutions.jump.workbench.model.UndoableCommand;
045: import com.vividsolutions.jump.workbench.plugin.AbstractPlugIn;
046: import com.vividsolutions.jump.workbench.plugin.EnableCheck;
047: import com.vividsolutions.jump.workbench.plugin.EnableCheckFactory;
048: import com.vividsolutions.jump.workbench.plugin.MultiEnableCheck;
049: import com.vividsolutions.jump.workbench.plugin.PlugInContext;
050: import com.vividsolutions.jump.workbench.ui.GUIUtil;
051:
052: import java.awt.Toolkit;
053: import java.awt.datatransfer.DataFlavor;
054: import java.awt.datatransfer.Transferable;
055:
056: import java.io.StringReader;
057:
058: import java.util.ArrayList;
059: import java.util.Collection;
060: import java.util.Iterator;
061:
062: import javax.swing.JComponent;
063:
064: /**
065: *
066: * Lets user paste items from the clipboard.
067: *
068: */
069:
070: public class PasteItemsPlugIn extends AbstractPlugIn {
071: private WKTReader reader = new WKTReader();
072:
073: //Note: Need to copy the data twice: once when the user hits Copy, so she is
074: //free to modify the original afterwards, and again when the user hits Paste,
075: //so she is free to modify the first copy then hit Paste again. [Jon Aquino]
076: public PasteItemsPlugIn() {
077: }
078:
079: public String getNameWithMnemonic() {
080: return StringUtil.replace(getName(), "P", "&P", false);
081: }
082:
083: public boolean execute(final PlugInContext context)
084: throws Exception {
085: reportNothingToUndoYet(context);
086:
087: Collection features;
088: Transferable transferable = GUIUtil.getContents(Toolkit
089: .getDefaultToolkit().getSystemClipboard());
090:
091: if (transferable
092: .isDataFlavorSupported(CollectionOfFeaturesTransferable.COLLECTION_OF_FEATURES_FLAVOR)) {
093: features = (Collection) GUIUtil
094: .getContents(
095: Toolkit.getDefaultToolkit()
096: .getSystemClipboard())
097: .getTransferData(
098: CollectionOfFeaturesTransferable.COLLECTION_OF_FEATURES_FLAVOR);
099: } else {
100: //Allow the user to paste features using WKT. [Jon Aquino]
101: features = reader.read(
102: new StringReader((String) transferable
103: .getTransferData(DataFlavor.stringFlavor)))
104: .getFeatures();
105: }
106:
107: final Layer layer = context.getSelectedLayer(0);
108: final Collection featureCopies = conform(features, layer
109: .getFeatureCollectionWrapper().getFeatureSchema());
110: execute(new UndoableCommand(getName()) {
111: public void execute() {
112: layer.getFeatureCollectionWrapper().addAll(
113: featureCopies);
114: }
115:
116: public void unexecute() {
117: layer.getFeatureCollectionWrapper().removeAll(
118: featureCopies);
119: }
120: }, context);
121:
122: return true;
123: }
124:
125: public static Collection conform(Collection features,
126: FeatureSchema targetFeatureSchema) {
127: final ArrayList featureCopies = new ArrayList();
128:
129: for (Iterator i = features.iterator(); i.hasNext();) {
130: Feature feature = (Feature) i.next();
131: featureCopies.add(conform(feature, targetFeatureSchema));
132: }
133:
134: return featureCopies;
135: }
136:
137: private static Feature conform(Feature original,
138: FeatureSchema targetFeatureSchema) {
139: //Transfer as many attributes as possible, matching on name. [Jon Aquino]
140: Feature copy = new BasicFeature(targetFeatureSchema);
141: copy.setGeometry((Geometry) original.getGeometry().clone());
142:
143: for (int i = 0; i < original.getSchema().getAttributeCount(); i++) {
144: if (i == original.getSchema().getGeometryIndex()) {
145: continue;
146: }
147:
148: String attributeName = original.getSchema()
149: .getAttributeName(i);
150:
151: if (!copy.getSchema().hasAttribute(attributeName)) {
152: continue;
153: }
154:
155: if (copy.getSchema().getAttributeType(attributeName) != original
156: .getSchema().getAttributeType(attributeName)) {
157: continue;
158: }
159:
160: copy.setAttribute(attributeName, original
161: .getAttribute(attributeName));
162: }
163:
164: Reprojector.instance().reproject(copy.getGeometry(),
165: original.getSchema().getCoordinateSystem(),
166: copy.getSchema().getCoordinateSystem());
167:
168: return copy;
169: }
170:
171: public static MultiEnableCheck createEnableCheck(
172: final WorkbenchContext workbenchContext) {
173: EnableCheckFactory checkFactory = new EnableCheckFactory(
174: workbenchContext);
175:
176: return new MultiEnableCheck()
177: .add(
178: checkFactory
179: .createWindowWithLayerNamePanelMustBeActiveCheck())
180: .add(
181: checkFactory
182: .createExactlyNLayersMustBeSelectedCheck(1))
183: .add(
184: checkFactory
185: .createSelectedLayersMustBeEditableCheck())
186: .add(new EnableCheck() {
187: public String check(JComponent component) {
188: Transferable transferable = GUIUtil
189: .getContents(Toolkit
190: .getDefaultToolkit()
191: .getSystemClipboard());
192:
193: if (transferable == null) {
194: return "Clipboard must not be empty";
195: }
196:
197: if (transferable
198: .isDataFlavorSupported(CollectionOfFeaturesTransferable.COLLECTION_OF_FEATURES_FLAVOR)) {
199: return null;
200: }
201:
202: try {
203: if (transferable
204: .isDataFlavorSupported(DataFlavor.stringFlavor)
205: && isWKT((String) transferable
206: .getTransferData(DataFlavor.stringFlavor))) {
207: return null;
208: }
209: } catch (Exception e) {
210: workbenchContext.getErrorHandler()
211: .handleThrowable(e);
212: }
213:
214: return "Clipboard must contain geometries or Well-Known Text";
215: }
216:
217: private boolean isWKT(String s) {
218: try {
219: new WKTReader().read(new StringReader(s));
220:
221: return true;
222: } catch (Exception e) {
223: return false;
224: }
225: }
226: });
227: }
228: }
|