Changeset 10604 in josm for trunk/src/org/openstreetmap/josm/actions/PasteAction.java
- Timestamp:
- 2016-07-23T14:54:19+02:00 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/PasteAction.java
r10413 r10604 8 8 import java.awt.MouseInfo; 9 9 import java.awt.Point; 10 import java.awt.datatransfer.FlavorEvent; 11 import java.awt.datatransfer.FlavorListener; 10 12 import java.awt.event.ActionEvent; 11 13 import java.awt.event.KeyEvent; 12 import java.util.ArrayList;13 import java.util.HashMap;14 import java.util.List;15 import java.util.Map;16 14 17 15 import org.openstreetmap.josm.Main; 18 import org.openstreetmap.josm.command.AddPrimitivesCommand;19 16 import org.openstreetmap.josm.data.coor.EastNorth; 20 import org.openstreetmap.josm.data.osm.NodeData; 21 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 22 import org.openstreetmap.josm.data.osm.PrimitiveData; 23 import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy; 24 import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy.PasteBufferChangedListener; 25 import org.openstreetmap.josm.data.osm.RelationData; 26 import org.openstreetmap.josm.data.osm.RelationMemberData; 27 import org.openstreetmap.josm.data.osm.WayData; 28 import org.openstreetmap.josm.gui.ExtendedDialog; 29 import org.openstreetmap.josm.gui.layer.Layer; 17 import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils; 18 import org.openstreetmap.josm.gui.datatransfer.OsmTransferHandler; 30 19 import org.openstreetmap.josm.tools.Shortcut; 31 20 … … 34 23 * @since 404 35 24 */ 36 public final class PasteAction extends JosmAction implements PasteBufferChangedListener { 25 public final class PasteAction extends JosmAction implements FlavorListener { 26 27 private final OsmTransferHandler transferHandler; 37 28 38 29 /** … … 46 37 Main.registerActionShortcut(this, 47 38 Shortcut.registerShortcut("system:paste:cua", tr("Edit: {0}", tr("Paste")), KeyEvent.VK_INSERT, Shortcut.SHIFT)); 48 Main.pasteBuffer.addPasteBufferChangedListener(this); 39 transferHandler = new OsmTransferHandler(); 40 ClipboardUtils.getClipboard().addFlavorListener(this); 49 41 } 50 42 51 43 @Override 52 44 public void actionPerformed(ActionEvent e) { 53 if (!isEnabled())54 return;55 pasteData(Main.pasteBuffer, Main.pasteSource, e);56 }57 58 /**59 * Paste OSM primitives from the given paste buffer and OSM data layer source to the current edit layer.60 * @param pasteBuffer The paste buffer containing primitive ids to copy61 * @param source The OSM data layer used to look for primitive ids62 * @param e The ActionEvent that triggered this operation63 */64 public void pasteData(PrimitiveDeepCopy pasteBuffer, Layer source, ActionEvent e) {65 /* Find the middle of the pasteBuffer area */66 double maxEast = -1E100;67 double minEast = 1E100;68 double maxNorth = -1E100;69 double minNorth = 1E100;70 boolean incomplete = false;71 for (PrimitiveData data : pasteBuffer.getAll()) {72 if (data instanceof NodeData) {73 NodeData n = (NodeData) data;74 if (n.getEastNorth() != null) {75 double east = n.getEastNorth().east();76 double north = n.getEastNorth().north();77 if (east > maxEast) {78 maxEast = east;79 }80 if (east < minEast) {81 minEast = east;82 }83 if (north > maxNorth) {84 maxNorth = north;85 }86 if (north < minNorth) {87 minNorth = north;88 }89 }90 }91 if (data.isIncomplete()) {92 incomplete = true;93 }94 }95 96 // Allow to cancel paste if there are incomplete primitives97 if (incomplete && !confirmDeleteIncomplete()) {98 return;99 }100 101 45 // default to paste in center of map (pasted via menu or cursor not in MapView) 102 46 EastNorth mPosition = Main.map.mapView.getCenter(); … … 113 57 } 114 58 115 double offsetEast = mPosition.east() - (maxEast + minEast)/2.0; 116 double offsetNorth = mPosition.north() - (maxNorth + minNorth)/2.0; 117 118 // Make a copy of pasteBuffer and map from old id to copied data id 119 List<PrimitiveData> bufferCopy = new ArrayList<>(); 120 List<PrimitiveData> toSelect = new ArrayList<>(); 121 Map<Long, Long> newNodeIds = new HashMap<>(); 122 Map<Long, Long> newWayIds = new HashMap<>(); 123 Map<Long, Long> newRelationIds = new HashMap<>(); 124 for (PrimitiveData data: pasteBuffer.getAll()) { 125 if (data.isIncomplete()) { 126 continue; 127 } 128 PrimitiveData copy = data.makeCopy(); 129 copy.clearOsmMetadata(); 130 if (data instanceof NodeData) { 131 newNodeIds.put(data.getUniqueId(), copy.getUniqueId()); 132 } else if (data instanceof WayData) { 133 newWayIds.put(data.getUniqueId(), copy.getUniqueId()); 134 } else if (data instanceof RelationData) { 135 newRelationIds.put(data.getUniqueId(), copy.getUniqueId()); 136 } 137 bufferCopy.add(copy); 138 if (pasteBuffer.getDirectlyAdded().contains(data)) { 139 toSelect.add(copy); 140 } 141 } 142 143 // Update references in copied buffer 144 for (PrimitiveData data:bufferCopy) { 145 if (data instanceof NodeData) { 146 NodeData nodeData = (NodeData) data; 147 if (Main.getLayerManager().getEditLayer() == source) { 148 nodeData.setEastNorth(nodeData.getEastNorth().add(offsetEast, offsetNorth)); 149 } 150 } else if (data instanceof WayData) { 151 List<Long> newNodes = new ArrayList<>(); 152 for (Long oldNodeId: ((WayData) data).getNodes()) { 153 Long newNodeId = newNodeIds.get(oldNodeId); 154 if (newNodeId != null) { 155 newNodes.add(newNodeId); 156 } 157 } 158 ((WayData) data).setNodes(newNodes); 159 } else if (data instanceof RelationData) { 160 List<RelationMemberData> newMembers = new ArrayList<>(); 161 for (RelationMemberData member: ((RelationData) data).getMembers()) { 162 OsmPrimitiveType memberType = member.getMemberType(); 163 Long newId; 164 switch (memberType) { 165 case NODE: 166 newId = newNodeIds.get(member.getMemberId()); 167 break; 168 case WAY: 169 newId = newWayIds.get(member.getMemberId()); 170 break; 171 case RELATION: 172 newId = newRelationIds.get(member.getMemberId()); 173 break; 174 default: throw new AssertionError(); 175 } 176 if (newId != null) { 177 newMembers.add(new RelationMemberData(member.getRole(), memberType, newId)); 178 } 179 } 180 ((RelationData) data).setMembers(newMembers); 181 } 182 } 183 184 /* Now execute the commands to add the duplicated contents of the paste buffer to the map */ 185 Main.main.undoRedo.add(new AddPrimitivesCommand(bufferCopy, toSelect)); 186 Main.map.mapView.repaint(); 187 } 188 189 private static boolean confirmDeleteIncomplete() { 190 ExtendedDialog ed = new ExtendedDialog(Main.parent, 191 tr("Delete incomplete members?"), 192 new String[] {tr("Paste without incomplete members"), tr("Cancel")}); 193 ed.setButtonIcons(new String[] {"dialogs/relation/deletemembers", "cancel"}); 194 ed.setContent(tr("The copied data contains incomplete objects. " 195 + "When pasting the incomplete objects are removed. " 196 + "Do you want to paste the data without the incomplete objects?")); 197 ed.showDialog(); 198 return ed.getValue() == 1; 59 transferHandler.pasteOn(Main.getLayerManager().getEditLayer(), mPosition); 199 60 } 200 61 201 62 @Override 202 63 protected void updateEnabledState() { 203 if (getLayerManager().getEditDataSet() == null || Main.pasteBuffer == null) { 204 setEnabled(false); 205 return; 206 } 207 setEnabled(!Main.pasteBuffer.isEmpty()); 64 setEnabled(getLayerManager().getEditDataSet() != null && transferHandler.isDataAvailable()); 208 65 } 209 66 210 67 @Override 211 public void pasteBufferChanged(PrimitiveDeepCopy pasteBuffer) {68 public void flavorsChanged(FlavorEvent e) { 212 69 updateEnabledState(); 213 70 }
Note:
See TracChangeset
for help on using the changeset viewer.