source: josm/trunk/src/org/openstreetmap/josm/gui/datatransfer/importers/PrimitiveDataPaster.java@ 12279

Last change on this file since 12279 was 12279, checked in by Don-vip, 7 years ago

sonar - squid:S3878 - Arrays should not be created for varargs parameters

File size: 6.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.datatransfer.importers;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.datatransfer.UnsupportedFlavorException;
7import java.io.IOException;
8import java.util.ArrayList;
9import java.util.EnumMap;
10import java.util.HashMap;
11import java.util.List;
12import java.util.Map;
13
14import javax.swing.TransferHandler.TransferSupport;
15
16import org.openstreetmap.josm.Main;
17import org.openstreetmap.josm.command.AddPrimitivesCommand;
18import org.openstreetmap.josm.data.coor.EastNorth;
19import org.openstreetmap.josm.data.osm.NodeData;
20import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
21import org.openstreetmap.josm.data.osm.PrimitiveData;
22import org.openstreetmap.josm.data.osm.RelationData;
23import org.openstreetmap.josm.data.osm.RelationMemberData;
24import org.openstreetmap.josm.data.osm.WayData;
25import org.openstreetmap.josm.gui.ExtendedDialog;
26import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData;
27import org.openstreetmap.josm.gui.layer.OsmDataLayer;
28import org.openstreetmap.josm.tools.JosmRuntimeException;
29import org.openstreetmap.josm.tools.bugreport.BugReport;
30
31/**
32 * This transfer support allows us to transfer primitives. This is the default paste action when primitives were copied.
33 * @author Michael Zangl
34 * @since 10604
35 */
36public final class PrimitiveDataPaster extends AbstractOsmDataPaster {
37 /**
38 * Create a new {@link PrimitiveDataPaster}
39 */
40 public PrimitiveDataPaster() {
41 super(PrimitiveTransferData.DATA_FLAVOR);
42 }
43
44 @Override
45 public boolean importData(TransferSupport support, final OsmDataLayer layer, EastNorth pasteAt)
46 throws UnsupportedFlavorException, IOException {
47 PrimitiveTransferData pasteBuffer = (PrimitiveTransferData) support.getTransferable().getTransferData(df);
48 // Allow to cancel paste if there are incomplete primitives
49 if (pasteBuffer.hasIncompleteData() && !confirmDeleteIncomplete()) {
50 return false;
51 }
52
53 EastNorth center = pasteBuffer.getCenter();
54 EastNorth offset = center == null || pasteAt == null ? new EastNorth(0, 0) : pasteAt.subtract(center);
55
56 AddPrimitivesCommand command = createNewPrimitives(pasteBuffer, offset, layer);
57
58 /* Now execute the commands to add the duplicated contents of the paste buffer to the map */
59 Main.main.undoRedo.add(command);
60 return true;
61 }
62
63 private static AddPrimitivesCommand createNewPrimitives(PrimitiveTransferData pasteBuffer, EastNorth offset, OsmDataLayer layer) {
64 // Make a copy of pasteBuffer and map from old id to copied data id
65 List<PrimitiveData> bufferCopy = new ArrayList<>();
66 List<PrimitiveData> toSelect = new ArrayList<>();
67 EnumMap<OsmPrimitiveType, Map<Long, Long>> newIds = generateNewPrimitives(pasteBuffer, bufferCopy, toSelect);
68
69 // Update references in copied buffer
70 for (PrimitiveData data : bufferCopy) {
71 try {
72 if (data instanceof NodeData) {
73 NodeData nodeData = (NodeData) data;
74 nodeData.setEastNorth(nodeData.getEastNorth().add(offset));
75 } else if (data instanceof WayData) {
76 updateNodes(newIds.get(OsmPrimitiveType.NODE), data);
77 } else if (data instanceof RelationData) {
78 updateMembers(newIds, data);
79 }
80 } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
81 throw BugReport.intercept(e).put("data", data);
82 }
83 }
84 return new AddPrimitivesCommand(bufferCopy, toSelect, layer);
85 }
86
87 private static EnumMap<OsmPrimitiveType, Map<Long, Long>> generateNewPrimitives(PrimitiveTransferData pasteBuffer,
88 List<PrimitiveData> bufferCopy, List<PrimitiveData> toSelect) {
89 EnumMap<OsmPrimitiveType, Map<Long, Long>> newIds = new EnumMap<>(OsmPrimitiveType.class);
90 newIds.put(OsmPrimitiveType.NODE, new HashMap<Long, Long>());
91 newIds.put(OsmPrimitiveType.WAY, new HashMap<Long, Long>());
92 newIds.put(OsmPrimitiveType.RELATION, new HashMap<Long, Long>());
93
94 for (PrimitiveData data : pasteBuffer.getAll()) {
95 if (data.isIncomplete() || !data.isVisible()) {
96 continue;
97 }
98 PrimitiveData copy = data.makeCopy();
99 // don't know why this is reset, but we need it to not crash on copying incomplete nodes.
100 boolean wasIncomplete = copy.isIncomplete();
101 copy.clearOsmMetadata();
102 copy.setIncomplete(wasIncomplete);
103 newIds.get(data.getType()).put(data.getUniqueId(), copy.getUniqueId());
104
105 bufferCopy.add(copy);
106 if (pasteBuffer.getDirectlyAdded().contains(data)) {
107 toSelect.add(copy);
108 }
109 }
110 return newIds;
111 }
112
113 private static void updateMembers(EnumMap<OsmPrimitiveType, Map<Long, Long>> newIds, PrimitiveData data) {
114 List<RelationMemberData> newMembers = new ArrayList<>();
115 for (RelationMemberData member : ((RelationData) data).getMembers()) {
116 OsmPrimitiveType memberType = member.getMemberType();
117 Long newId = newIds.get(memberType).get(member.getMemberId());
118 if (newId != null) {
119 newMembers.add(new RelationMemberData(member.getRole(), memberType, newId));
120 }
121 }
122 ((RelationData) data).setMembers(newMembers);
123 }
124
125 private static void updateNodes(Map<Long, Long> newNodeIds, PrimitiveData data) {
126 List<Long> newNodes = new ArrayList<>();
127 for (Long oldNodeId : ((WayData) data).getNodes()) {
128 Long newNodeId = newNodeIds.get(oldNodeId);
129 if (newNodeId != null) {
130 newNodes.add(newNodeId);
131 }
132 }
133 ((WayData) data).setNodes(newNodes);
134 }
135
136 private static boolean confirmDeleteIncomplete() {
137 ExtendedDialog ed = new ExtendedDialog(Main.parent, tr("Delete incomplete members?"),
138 tr("Paste without incomplete members"), tr("Cancel"));
139 ed.setButtonIcons("dialogs/relation/deletemembers", "cancel");
140 ed.setContent(tr(
141 "The copied data contains incomplete objects. " + "When pasting the incomplete objects are removed. "
142 + "Do you want to paste the data without the incomplete objects?"));
143 ed.showDialog();
144 return ed.getValue() == 1;
145 }
146}
Note: See TracBrowser for help on using the repository browser.