/* Find the middle of the pasteBuffer area */
double maxEast = -1E100, minEast = 1E100, maxNorth = -1E100, minNorth = 1E100;
boolean incomplete = false;
for (PrimitiveData data : pasteBuffer.getAll()) {
if (data instanceof NodeData) {
NodeData n = (NodeData)data;
if (n.getEastNorth() != null) {
double east = n.getEastNorth().east();
double north = n.getEastNorth().north();
if (east > maxEast) { maxEast = east; }
if (east < minEast) { minEast = east; }
if (north > maxNorth) { maxNorth = north; }
if (north < minNorth) { minNorth = north; }
}
}
if (data.isIncomplete()) {
incomplete = true;
}
}
// Allow to cancel paste if there are incomplete primitives
if (incomplete) {
if (!confirmDeleteIncomplete()) return;
}
// default to paste in center of map (pasted via menu or cursor not in MapView)
EastNorth mPosition = Main.map.mapView.getCenter();
// We previously checked for modifier to know if the action has been trigerred via shortcut or via menu
// But this does not work if the shortcut is changed to a single key (see #9055)
// Observed behaviour: getActionCommand() returns Action.NAME when triggered via menu, but shortcut text when triggered with it
if (!getValue(NAME).equals(e.getActionCommand())) {
final Point mp = MouseInfo.getPointerInfo().getLocation();
final Point tl = Main.map.mapView.getLocationOnScreen();
final Point pos = new Point(mp.x-tl.x, mp.y-tl.y);
if(Main.map.mapView.contains(pos)) {
mPosition = Main.map.mapView.getEastNorth(pos.x, pos.y);
}
}
double offsetEast = mPosition.east() - (maxEast + minEast)/2.0;
double offsetNorth = mPosition.north() - (maxNorth + minNorth)/2.0;
// Make a copy of pasteBuffer and map from old id to copied data id
List<PrimitiveData> bufferCopy = new ArrayList<>();
List<PrimitiveData> toSelect = new ArrayList<>();
Map<Long, Long> newNodeIds = new HashMap<>();
Map<Long, Long> newWayIds = new HashMap<>();
Map<Long, Long> newRelationIds = new HashMap<>();
for (PrimitiveData data: pasteBuffer.getAll()) {
if (data.isIncomplete()) {
continue;
}
PrimitiveData copy = data.makeCopy();
copy.clearOsmMetadata();
if (data instanceof NodeData) {
newNodeIds.put(data.getUniqueId(), copy.getUniqueId());
} else if (data instanceof WayData) {
newWayIds.put(data.getUniqueId(), copy.getUniqueId());
} else if (data instanceof RelationData) {
newRelationIds.put(data.getUniqueId(), copy.getUniqueId());
}
bufferCopy.add(copy);
if (pasteBuffer.getDirectlyAdded().contains(data)) {
toSelect.add(copy);
}
}
// Update references in copied buffer
for (PrimitiveData data:bufferCopy) {
if (data instanceof NodeData) {
NodeData nodeData = (NodeData)data;
if (Main.main.getEditLayer() == source) {
nodeData.setEastNorth(nodeData.getEastNorth().add(offsetEast, offsetNorth));
}
} else if (data instanceof WayData) {
List<Long> newNodes = new ArrayList<>();
for (Long oldNodeId: ((WayData)data).getNodes()) {
Long newNodeId = newNodeIds.get(oldNodeId);