Ticket #13290: patch-paste-at-same-position.patch
File patch-paste-at-same-position.patch, 14.1 KB (added by , 8 years ago) |
---|
-
new file src/org/openstreetmap/josm/actions/AbstractPasteAction.java
diff --git a/src/org/openstreetmap/josm/actions/AbstractPasteAction.java b/src/org/openstreetmap/josm/actions/AbstractPasteAction.java new file mode 100644 index 0000000..183d3af
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.actions; 3 4 import java.awt.MouseInfo; 5 import java.awt.Point; 6 import java.awt.datatransfer.FlavorEvent; 7 import java.awt.datatransfer.FlavorListener; 8 import java.awt.datatransfer.Transferable; 9 import java.awt.event.ActionEvent; 10 11 import org.openstreetmap.josm.Main; 12 import org.openstreetmap.josm.data.coor.EastNorth; 13 import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils; 14 import org.openstreetmap.josm.gui.datatransfer.OsmTransferHandler; 15 import org.openstreetmap.josm.tools.Shortcut; 16 17 /** 18 * This is the base class for all actions that paste objects. 19 * @author Michael Zangl 20 * @since xxx 21 */ 22 public abstract class AbstractPasteAction extends JosmAction implements FlavorListener { 23 24 protected final OsmTransferHandler transferHandler; 25 26 /** 27 * Create a new {@link AbstractPasteAction} 28 * @param name See {@link JosmAction#JosmAction(String, String, String, Shortcut, boolean, String, boolean)} 29 * @param iconName See {@link JosmAction#JosmAction(String, String, String, Shortcut, boolean, String, boolean)} 30 * @param tooltip See {@link JosmAction#JosmAction(String, String, String, Shortcut, boolean, String, boolean)} 31 * @param shortcut See {@link JosmAction#JosmAction(String, String, String, Shortcut, boolean, String, boolean)} 32 * @param registerInToolbar See {@link JosmAction#JosmAction(String, String, String, Shortcut, boolean, String, boolean)} 33 */ 34 public AbstractPasteAction(String name, String iconName, String tooltip, Shortcut shortcut, 35 boolean registerInToolbar) { 36 super(name, iconName, tooltip, shortcut, registerInToolbar); 37 transferHandler = new OsmTransferHandler(); 38 ClipboardUtils.getClipboard().addFlavorListener(this); 39 } 40 41 /** 42 * Compute the location the objects should be pasted at. 43 * @param e The action event that triggered the paste 44 * @return The paste position. 45 */ 46 protected EastNorth computePastePosition(ActionEvent e) { 47 // default to paste in center of map (pasted via menu or cursor not in MapView) 48 EastNorth mPosition = Main.map.mapView.getCenter(); 49 // We previously checked for modifier to know if the action has been trigerred via shortcut or via menu 50 // But this does not work if the shortcut is changed to a single key (see #9055) 51 // Observed behaviour: getActionCommand() returns Action.NAME when triggered via menu, but shortcut text when triggered with it 52 if (e != null && !getValue(NAME).equals(e.getActionCommand())) { 53 final Point mp = MouseInfo.getPointerInfo().getLocation(); 54 final Point tl = Main.map.mapView.getLocationOnScreen(); 55 final Point pos = new Point(mp.x-tl.x, mp.y-tl.y); 56 if (Main.map.mapView.contains(pos)) { 57 mPosition = Main.map.mapView.getEastNorth(pos.x, pos.y); 58 } 59 } 60 return mPosition; 61 } 62 63 @Override 64 public void actionPerformed(ActionEvent e) { 65 Transferable contents = ClipboardUtils.getClipboard().getContents(null); 66 doPaste(e, contents); 67 } 68 69 protected void doPaste(ActionEvent e, Transferable contents) { 70 transferHandler.pasteOn(Main.getLayerManager().getEditLayer(), computePastePosition(e), contents); 71 } 72 73 @Override 74 protected void updateEnabledState() { 75 setEnabled(getLayerManager().getEditDataSet() != null && transferHandler.isDataAvailable()); 76 } 77 78 @Override 79 public void flavorsChanged(FlavorEvent e) { 80 updateEnabledState(); 81 } 82 83 } -
src/org/openstreetmap/josm/actions/DuplicateAction.java
diff --git a/src/org/openstreetmap/josm/actions/DuplicateAction.java b/src/org/openstreetmap/josm/actions/DuplicateAction.java index 66efb08..cb8bb5d 100644
a b import java.awt.event.ActionEvent; 9 9 import java.awt.event.KeyEvent; 10 10 import java.util.Collection; 11 11 12 import org.openstreetmap.josm.Main;13 12 import org.openstreetmap.josm.data.osm.OsmPrimitive; 14 import org.openstreetmap.josm.gui.datatransfer.OsmTransferHandler;15 13 import org.openstreetmap.josm.gui.datatransfer.PrimitiveTransferable; 16 14 import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData; 17 15 import org.openstreetmap.josm.tools.Shortcut; … … import org.openstreetmap.josm.tools.Shortcut; 19 17 /** 20 18 * An action that duplicates the given nodes. They are not added to the clipboard. 21 19 */ 22 public final class DuplicateAction extends JosmAction {20 public final class DuplicateAction extends AbstractPasteAction { 23 21 24 22 /** 25 23 * Constructs a new {@code DuplicateAction}. … … public final class DuplicateAction extends JosmAction { 34 32 @Override 35 33 public void actionPerformed(ActionEvent e) { 36 34 PrimitiveTransferData data = PrimitiveTransferData.getDataWithReferences(getLayerManager().getEditDataSet().getSelected()); 37 new OsmTransferHandler().pasteOn(Main.getLayerManager().getEditLayer(), 38 PasteAction.computePastePosition(e, getValue(NAME)), new PrimitiveTransferable(data)); 35 doPaste(e, new PrimitiveTransferable(data)); 39 36 } 40 37 41 38 @Override -
src/org/openstreetmap/josm/actions/PasteAction.java
diff --git a/src/org/openstreetmap/josm/actions/PasteAction.java b/src/org/openstreetmap/josm/actions/PasteAction.java index 9ab5725..b54f14b 100644
a b package org.openstreetmap.josm.actions; 5 5 import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 6 6 import static org.openstreetmap.josm.tools.I18n.tr; 7 7 8 import java.awt.MouseInfo;9 import java.awt.Point;10 import java.awt.datatransfer.FlavorEvent;11 import java.awt.datatransfer.FlavorListener;12 import java.awt.event.ActionEvent;13 8 import java.awt.event.KeyEvent; 14 9 15 10 import org.openstreetmap.josm.Main; 16 import org.openstreetmap.josm.data.coor.EastNorth;17 import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;18 import org.openstreetmap.josm.gui.datatransfer.OsmTransferHandler;19 11 import org.openstreetmap.josm.tools.Shortcut; 20 12 21 13 /** 22 14 * Paste OSM primitives from clipboard to the current edit layer. 23 15 * @since 404 24 16 */ 25 public final class PasteAction extends JosmAction implements FlavorListener { 26 27 private final OsmTransferHandler transferHandler; 17 public final class PasteAction extends AbstractPasteAction { 28 18 29 19 /** 30 20 * Constructs a new {@code PasteAction}. 31 21 */ 32 22 public PasteAction() { 33 super(tr("Paste"), "paste", tr("Paste contents of paste buffer."),23 super(tr("Paste"), "paste", tr("Paste contents of clipboard."), 34 24 Shortcut.registerShortcut("system:paste", tr("Edit: {0}", tr("Paste")), KeyEvent.VK_V, Shortcut.CTRL), true); 35 25 putValue("help", ht("/Action/Paste")); 36 26 // CUA shortcut for paste (https://en.wikipedia.org/wiki/IBM_Common_User_Access#Description) 37 27 Main.registerActionShortcut(this, 38 28 Shortcut.registerShortcut("system:paste:cua", tr("Edit: {0}", tr("Paste")), KeyEvent.VK_INSERT, Shortcut.SHIFT)); 39 transferHandler = new OsmTransferHandler();40 ClipboardUtils.getClipboard().addFlavorListener(this);41 }42 43 @Override44 public void actionPerformed(ActionEvent e) {45 transferHandler.pasteOn(Main.getLayerManager().getEditLayer(), computePastePosition(e, getValue(NAME)));46 }47 48 static EastNorth computePastePosition(ActionEvent e, Object name) {49 // default to paste in center of map (pasted via menu or cursor not in MapView)50 EastNorth mPosition = Main.map.mapView.getCenter();51 // We previously checked for modifier to know if the action has been trigerred via shortcut or via menu52 // But this does not work if the shortcut is changed to a single key (see #9055)53 // Observed behaviour: getActionCommand() returns Action.NAME when triggered via menu, but shortcut text when triggered with it54 if (e != null && !name.equals(e.getActionCommand())) {55 final Point mp = MouseInfo.getPointerInfo().getLocation();56 final Point tl = Main.map.mapView.getLocationOnScreen();57 final Point pos = new Point(mp.x-tl.x, mp.y-tl.y);58 if (Main.map.mapView.contains(pos)) {59 mPosition = Main.map.mapView.getEastNorth(pos.x, pos.y);60 }61 }62 return mPosition;63 }64 65 @Override66 protected void updateEnabledState() {67 setEnabled(getLayerManager().getEditDataSet() != null && transferHandler.isDataAvailable());68 }69 70 @Override71 public void flavorsChanged(FlavorEvent e) {72 updateEnabledState();73 29 } 74 30 } -
new file src/org/openstreetmap/josm/actions/PasteAtSourcePositionAction.java
diff --git a/src/org/openstreetmap/josm/actions/PasteAtSourcePositionAction.java b/src/org/openstreetmap/josm/actions/PasteAtSourcePositionAction.java new file mode 100644 index 0000000..86a1f14
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.actions; 3 4 import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 5 import static org.openstreetmap.josm.tools.I18n.tr; 6 7 import java.awt.event.ActionEvent; 8 import java.awt.event.KeyEvent; 9 10 import org.openstreetmap.josm.data.coor.EastNorth; 11 import org.openstreetmap.josm.tools.Shortcut; 12 13 /** 14 * A special version of the {@link PasteAction} that pastes at the exact source location the item was copied from. 15 * @author Michael Zangl 16 * @since xxx 17 */ 18 public class PasteAtSourcePositionAction extends AbstractPasteAction { 19 /** 20 * Constructs a new {@link PasteAtSourcePositionAction} 21 */ 22 public PasteAtSourcePositionAction() { 23 super(tr("Paste at source position"), "paste", tr("Paste contents of clipboard at the position they were copied from."), 24 Shortcut.registerShortcut("menu:edit:pasteAtSource", tr("Edit: {0}", tr("Paste at source position")), 25 KeyEvent.VK_V, Shortcut.ALT_CTRL), true); 26 putValue("help", ht("/Action/Paste")); 27 } 28 29 @Override 30 protected EastNorth computePastePosition(ActionEvent e) { 31 // null means use old position 32 return null; 33 } 34 } -
src/org/openstreetmap/josm/gui/MainMenu.java
diff --git a/src/org/openstreetmap/josm/gui/MainMenu.java b/src/org/openstreetmap/josm/gui/MainMenu.java index 172e60b..060c293 100644
a b import org.openstreetmap.josm.actions.OrthogonalizeAction; 73 73 import org.openstreetmap.josm.actions.OrthogonalizeAction.Undo; 74 74 import org.openstreetmap.josm.actions.OverpassDownloadAction; 75 75 import org.openstreetmap.josm.actions.PasteAction; 76 import org.openstreetmap.josm.actions.PasteAtSourcePositionAction; 76 77 import org.openstreetmap.josm.actions.PasteTagsAction; 77 78 import org.openstreetmap.josm.actions.PreferenceToggleAction; 78 79 import org.openstreetmap.josm.actions.PreferencesAction; … … public class MainMenu extends JMenuBar { 194 195 public final JosmAction copyCoordinates = new CopyCoordinatesAction(); 195 196 /** Edit / Paste */ 196 197 public final PasteAction paste = new PasteAction(); 198 /** Edit / Paste at source */ 199 private final PasteAtSourcePositionAction pasteAtSource = new PasteAtSourcePositionAction(); 197 200 /** Edit / Paste Tags */ 198 201 public final PasteTagsAction pasteTags = new PasteTagsAction(); 199 202 /** Edit / Duplicate */ … … public class MainMenu extends JMenuBar { 679 682 add(editMenu, copy); 680 683 add(editMenu, copyCoordinates, true); 681 684 add(editMenu, paste); 685 add(editMenu, pasteAtSource); 682 686 add(editMenu, pasteTags); 683 687 add(editMenu, duplicate); 684 688 add(editMenu, delete); -
src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java b/src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java index 5001c48..fdc8b89 100644
a b public class OsmTransferHandler extends TransferHandler { 82 82 /** 83 83 * Paste the current clipboard current at the given position 84 84 * @param editLayer The layer to paste on. 85 * @param mPosition The position to paste at. 85 * @param mPosition The position to paste at. If it is <code>null</code>, the original position will be used. 86 86 */ 87 87 public void pasteOn(OsmDataLayer editLayer, EastNorth mPosition) { 88 88 Transferable transferable = ClipboardUtils.getClipboard().getContents(null); … … public class OsmTransferHandler extends TransferHandler { 92 92 /** 93 93 * Paste the given clipboard current at the given position 94 94 * @param editLayer The layer to paste on. 95 * @param mPosition The position to paste at. 95 * @param mPosition The position to paste at. If it is <code>null</code>, the original position will be used. 96 96 * @param transferable The transferable to use. 97 97 */ 98 98 public void pasteOn(OsmDataLayer editLayer, EastNorth mPosition, Transferable transferable) { -
src/org/openstreetmap/josm/gui/datatransfer/importers/PrimitiveDataPaster.java
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/importers/PrimitiveDataPaster.java b/src/org/openstreetmap/josm/gui/datatransfer/importers/PrimitiveDataPaster.java index 1823263..804b209 100644
a b public final class PrimitiveDataPaster extends AbstractOsmDataPaster { 49 49 } 50 50 51 51 EastNorth center = pasteBuffer.getCenter(); 52 EastNorth offset = center == null ? null: pasteAt.subtract(center);52 EastNorth offset = center == null || pasteAt == null ? new EastNorth(0, 0) : pasteAt.subtract(center); 53 53 54 54 AddPrimitivesCommand command = createNewPrimitives(pasteBuffer, offset, layer); 55 55