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.PointerInfo;
|
---|
7 | import java.awt.datatransfer.FlavorEvent;
|
---|
8 | import java.awt.datatransfer.FlavorListener;
|
---|
9 | import java.awt.datatransfer.Transferable;
|
---|
10 | import java.awt.event.ActionEvent;
|
---|
11 |
|
---|
12 | import org.openstreetmap.josm.data.coor.EastNorth;
|
---|
13 | import org.openstreetmap.josm.gui.MainApplication;
|
---|
14 | import org.openstreetmap.josm.gui.MapView;
|
---|
15 | import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
|
---|
16 | import org.openstreetmap.josm.gui.datatransfer.OsmTransferHandler;
|
---|
17 | import org.openstreetmap.josm.tools.Logging;
|
---|
18 | import org.openstreetmap.josm.tools.Shortcut;
|
---|
19 |
|
---|
20 | /**
|
---|
21 | * This is the base class for all actions that paste objects.
|
---|
22 | * @author Michael Zangl
|
---|
23 | * @since 10765
|
---|
24 | */
|
---|
25 | public abstract class AbstractPasteAction extends JosmAction implements FlavorListener {
|
---|
26 |
|
---|
27 | protected final OsmTransferHandler transferHandler;
|
---|
28 |
|
---|
29 | /**
|
---|
30 | * Constructs a new {@link AbstractPasteAction}.
|
---|
31 | * @param name the action's text as displayed on the menu (if it is added to a menu)
|
---|
32 | * @param iconName the filename of the icon to use
|
---|
33 | * @param tooltip a longer description of the action that will be displayed in the tooltip. Please note
|
---|
34 | * that html is not supported for menu actions on some platforms.
|
---|
35 | * @param shortcut a ready-created shortcut object or null if you don't want a shortcut. But you always
|
---|
36 | * do want a shortcut, remember you can always register it with group=none, so you
|
---|
37 | * won't be assigned a shortcut unless the user configures one. If you pass null here,
|
---|
38 | * the user CANNOT configure a shortcut for your action.
|
---|
39 | * @param registerInToolbar register this action for the toolbar preferences?
|
---|
40 | */
|
---|
41 | protected AbstractPasteAction(String name, String iconName, String tooltip, Shortcut shortcut,
|
---|
42 | boolean registerInToolbar) {
|
---|
43 | this(name, iconName, tooltip, shortcut, registerInToolbar, null);
|
---|
44 | }
|
---|
45 |
|
---|
46 | /**
|
---|
47 | * Constructs a new {@link AbstractPasteAction}.
|
---|
48 | * @param name the action's text as displayed on the menu (if it is added to a menu)
|
---|
49 | * @param iconName the filename of the icon to use
|
---|
50 | * @param tooltip a longer description of the action that will be displayed in the tooltip. Please note
|
---|
51 | * that html is not supported for menu actions on some platforms.
|
---|
52 | * @param shortcut a ready-created shortcut object or null if you don't want a shortcut. But you always
|
---|
53 | * do want a shortcut, remember you can always register it with group=none, so you
|
---|
54 | * won't be assigned a shortcut unless the user configures one. If you pass null here,
|
---|
55 | * the user CANNOT configure a shortcut for your action.
|
---|
56 | * @param registerInToolbar register this action for the toolbar preferences?
|
---|
57 | * @param toolbarId identifier for the toolbar preferences. The iconName is used, if this parameter is null
|
---|
58 | */
|
---|
59 | protected AbstractPasteAction(String name, String iconName, String tooltip, Shortcut shortcut,
|
---|
60 | boolean registerInToolbar, String toolbarId) {
|
---|
61 | super(name, iconName, tooltip, shortcut, registerInToolbar, toolbarId, true);
|
---|
62 | transferHandler = new OsmTransferHandler();
|
---|
63 | ClipboardUtils.getClipboard().addFlavorListener(this);
|
---|
64 | }
|
---|
65 |
|
---|
66 | /**
|
---|
67 | * Compute the location the objects should be pasted at.
|
---|
68 | * @param e The action event that triggered the paste
|
---|
69 | * @return The paste position.
|
---|
70 | */
|
---|
71 | protected EastNorth computePastePosition(ActionEvent e) {
|
---|
72 | // default to paste in center of map (pasted via menu or cursor not in MapView)
|
---|
73 | MapView mapView = MainApplication.getMap().mapView;
|
---|
74 | EastNorth mPosition = mapView.getCenter();
|
---|
75 | // We previously checked for modifier to know if the action has been triggered via shortcut or via menu
|
---|
76 | // But this does not work if the shortcut is changed to a single key (see #9055)
|
---|
77 | // Observed behaviour: getActionCommand() returns Action.NAME when triggered via menu, but shortcut text when triggered with it
|
---|
78 | if (e != null && !getValue(NAME).equals(e.getActionCommand())) {
|
---|
79 | try {
|
---|
80 | final PointerInfo pointerInfo = MouseInfo.getPointerInfo();
|
---|
81 | if (pointerInfo != null) {
|
---|
82 | final Point mp = pointerInfo.getLocation();
|
---|
83 | final Point tl = mapView.getLocationOnScreen();
|
---|
84 | final Point pos = new Point(mp.x-tl.x, mp.y-tl.y);
|
---|
85 | if (mapView.contains(pos)) {
|
---|
86 | mPosition = mapView.getEastNorth(pos.x, pos.y);
|
---|
87 | }
|
---|
88 | }
|
---|
89 | } catch (SecurityException ex) {
|
---|
90 | Logging.log(Logging.LEVEL_ERROR, "Unable to get mouse pointer info", ex);
|
---|
91 | }
|
---|
92 | }
|
---|
93 | return mPosition;
|
---|
94 | }
|
---|
95 |
|
---|
96 | @Override
|
---|
97 | public void actionPerformed(ActionEvent e) {
|
---|
98 | doPaste(e, ClipboardUtils.getClipboardContent());
|
---|
99 | }
|
---|
100 |
|
---|
101 | protected void doPaste(ActionEvent e, Transferable contents) {
|
---|
102 | transferHandler.pasteOn(getLayerManager().getEditLayer(), computePastePosition(e), contents);
|
---|
103 | }
|
---|
104 |
|
---|
105 | @Override
|
---|
106 | protected void updateEnabledState() {
|
---|
107 | setEnabled(getLayerManager().getEditDataSet() != null && transferHandler != null && transferHandler.isDataAvailable());
|
---|
108 | }
|
---|
109 |
|
---|
110 | @Override
|
---|
111 | public void flavorsChanged(FlavorEvent e) {
|
---|
112 | updateEnabledState();
|
---|
113 | }
|
---|
114 | }
|
---|