source: josm/trunk/src/org/openstreetmap/josm/actions/MoveAction.java@ 13187

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

fix #15252 - see #13036 - MoveCommand created without data set

  • Property svn:eol-style set to native
File size: 5.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.event.ActionEvent;
8import java.awt.event.KeyEvent;
9import java.util.Collection;
10
11import javax.swing.JOptionPane;
12
13import org.openstreetmap.josm.Main;
14import org.openstreetmap.josm.command.Command;
15import org.openstreetmap.josm.command.MoveCommand;
16import org.openstreetmap.josm.data.coor.EastNorth;
17import org.openstreetmap.josm.data.osm.DataSet;
18import org.openstreetmap.josm.data.osm.Node;
19import org.openstreetmap.josm.data.osm.OsmPrimitive;
20import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor;
21import org.openstreetmap.josm.gui.MainApplication;
22import org.openstreetmap.josm.gui.MapView;
23import org.openstreetmap.josm.tools.Shortcut;
24
25/**
26 * Moves the selection
27 *
28 * @author Frederik Ramm
29 */
30public class MoveAction extends JosmAction {
31
32 /**
33 * Move direction.
34 */
35 public enum Direction {
36 /** Move up */
37 UP,
38 /** Move left */
39 LEFT,
40 /** Move right */
41 RIGHT,
42 /** Move down */
43 DOWN
44 }
45
46 private final Direction myDirection;
47
48 // any better idea?
49 private static String calltosupermustbefirststatementinconstructortext(Direction dir) {
50 String directiontext;
51 if (dir == Direction.UP) {
52 directiontext = tr("up");
53 } else if (dir == Direction.DOWN) {
54 directiontext = tr("down");
55 } else if (dir == Direction.LEFT) {
56 directiontext = tr("left");
57 } else {
58 directiontext = tr("right");
59 }
60 return directiontext;
61 }
62
63 // any better idea?
64 private static Shortcut calltosupermustbefirststatementinconstructor(Direction dir) {
65 Shortcut sc;
66 // CHECKSTYLE.OFF: SingleSpaceSeparator
67 if (dir == Direction.UP) {
68 sc = Shortcut.registerShortcut("core:moveup", tr("Move objects {0}", tr("up")), KeyEvent.VK_UP, Shortcut.SHIFT);
69 } else if (dir == Direction.DOWN) {
70 sc = Shortcut.registerShortcut("core:movedown", tr("Move objects {0}", tr("down")), KeyEvent.VK_DOWN, Shortcut.SHIFT);
71 } else if (dir == Direction.LEFT) {
72 sc = Shortcut.registerShortcut("core:moveleft", tr("Move objects {0}", tr("left")), KeyEvent.VK_LEFT, Shortcut.SHIFT);
73 } else { //dir == Direction.RIGHT
74 sc = Shortcut.registerShortcut("core:moveright", tr("Move objects {0}", tr("right")), KeyEvent.VK_RIGHT, Shortcut.SHIFT);
75 }
76 // CHECKSTYLE.ON: SingleSpaceSeparator
77 return sc;
78 }
79
80 /**
81 * Constructs a new {@code MoveAction}.
82 * @param dir direction
83 */
84 public MoveAction(Direction dir) {
85 super(tr("Move {0}", calltosupermustbefirststatementinconstructortext(dir)), null,
86 tr("Moves Objects {0}", calltosupermustbefirststatementinconstructortext(dir)),
87 calltosupermustbefirststatementinconstructor(dir), false);
88 myDirection = dir;
89 putValue("help", ht("/Action/Move"));
90 if (dir == Direction.UP) {
91 putValue("toolbar", "action/move/up");
92 } else if (dir == Direction.DOWN) {
93 putValue("toolbar", "action/move/down");
94 } else if (dir == Direction.LEFT) {
95 putValue("toolbar", "action/move/left");
96 } else { //dir == Direction.RIGHT
97 putValue("toolbar", "action/move/right");
98 }
99 MainApplication.getToolbar().register(this);
100 }
101
102 @Override
103 public void actionPerformed(ActionEvent event) {
104 DataSet ds = getLayerManager().getEditDataSet();
105
106 if (!MainApplication.isDisplayingMapView() || ds == null)
107 return;
108
109 // find out how many "real" units the objects have to be moved in order to
110 // achive an 1-pixel movement
111
112 MapView mapView = MainApplication.getMap().mapView;
113 EastNorth en1 = mapView.getEastNorth(100, 100);
114 EastNorth en2 = mapView.getEastNorth(101, 101);
115
116 double distx = en2.east() - en1.east();
117 double disty = en2.north() - en1.north();
118
119 switch (myDirection) {
120 case UP:
121 distx = 0;
122 disty = -disty;
123 break;
124 case DOWN:
125 distx = 0;
126 break;
127 case LEFT:
128 disty = 0;
129 distx = -distx;
130 break;
131 default:
132 disty = 0;
133 }
134
135 Collection<OsmPrimitive> selection = ds.getSelected();
136 Collection<Node> affectedNodes = AllNodesVisitor.getAllNodes(selection);
137
138 Command c = MainApplication.undoRedo.getLastCommand();
139
140 ds.beginUpdate();
141 try {
142 if (c instanceof MoveCommand && ds.equals(c.getAffectedDataSet())
143 && affectedNodes.equals(((MoveCommand) c).getParticipatingPrimitives())) {
144 ((MoveCommand) c).moveAgain(distx, disty);
145 } else {
146 c = new MoveCommand(ds, selection, distx, disty);
147 MainApplication.undoRedo.add(c);
148 }
149 } finally {
150 ds.endUpdate();
151 }
152
153 for (Node n : affectedNodes) {
154 if (n.getCoor().isOutSideWorld()) {
155 // Revert move
156 ((MoveCommand) c).moveAgain(-distx, -disty);
157 JOptionPane.showMessageDialog(
158 Main.parent,
159 tr("Cannot move objects outside of the world."),
160 tr("Warning"),
161 JOptionPane.WARNING_MESSAGE
162 );
163 return;
164 }
165 }
166
167 mapView.repaint();
168 }
169
170 @Override
171 protected void updateEnabledState() {
172 updateEnabledStateOnCurrentSelection();
173 }
174
175 @Override
176 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
177 setEnabled(selection != null && !selection.isEmpty());
178 }
179}
Note: See TracBrowser for help on using the repository browser.