source: josm/branch/0.5/src/org/openstreetmap/josm/actions/mapmode/MoveAction.java@ 329

Last change on this file since 329 was 329, checked in by framm, 17 years ago

This commit is a manual merge of all changes that have been made to
the intermediate "core_0.5" branch on the main OSM repository,
bevore JOSM was moved to openstreetmap.de.

Changes incorporated here:

r4464@svn.openstreetmap.org
r4466@svn.openstreetmap.org
r4468@svn.openstreetmap.org
r4469@svn.openstreetmap.org
r4479@svn.openstreetmap.org

File size: 6.5 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.actions.mapmode;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Cursor;
7import java.awt.Point;
8import java.awt.Rectangle;
9import java.awt.event.KeyEvent;
10import java.awt.event.MouseEvent;
11import java.util.Collection;
12
13import javax.swing.JOptionPane;
14
15import org.openstreetmap.josm.Main;
16import org.openstreetmap.josm.actions.GroupAction;
17import org.openstreetmap.josm.command.Command;
18import org.openstreetmap.josm.command.MoveCommand;
19import org.openstreetmap.josm.command.RotateCommand;
20import org.openstreetmap.josm.data.coor.EastNorth;
21import org.openstreetmap.josm.data.osm.Node;
22import org.openstreetmap.josm.data.osm.OsmPrimitive;
23import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor;
24import org.openstreetmap.josm.gui.MapFrame;
25import org.openstreetmap.josm.gui.SelectionManager;
26import org.openstreetmap.josm.gui.SelectionManager.SelectionEnded;
27import org.openstreetmap.josm.tools.ImageProvider;
28/**
29 * Move is an action that can move all kind of OsmPrimitives (except Keys for now).
30 *
31 * If an selected object is under the mouse when dragging, move all selected objects.
32 * If an unselected object is under the mouse when dragging, it becomes selected
33 * and will be moved.
34 * If no object is under the mouse, move all selected objects (if any)
35 *
36 * @author imi
37 */
38public class MoveAction extends MapMode implements SelectionEnded {
39
40 enum Mode {move, rotate}
41 private final Mode mode;
42
43 public static class MoveGroup extends GroupAction {
44 public MoveGroup(MapFrame mf) {
45 super(KeyEvent.VK_M,0);
46 putValue("help", "Action/Move");
47 actions.add(new MoveAction(mf, tr("Move"), Mode.move, tr("Move around objects that are under the mouse or selected.")));
48 actions.add(new MoveAction(mf, tr("Rotate"), Mode.rotate, tr("Rotate selected nodes around centre")));
49 setCurrent(0);
50 }
51 }
52
53 /**
54 * The old cursor before the user pressed the mouse button.
55 */
56 private Cursor oldCursor;
57 /**
58 * The position of the mouse before the user moves a node.
59 */
60 private Point mousePos;
61 private SelectionManager selectionManager;
62 private boolean selectionMode = false;
63
64 /**
65 * Create a new MoveAction
66 * @param mapFrame The MapFrame, this action belongs to.
67 */
68 public MoveAction(MapFrame mapFrame, String name, Mode mode, String desc) {
69 super(name, "move/"+mode, desc, mapFrame, getCursor());
70 this.mode = mode;
71 putValue("help", "Action/Move/"+Character.toUpperCase(mode.toString().charAt(0))+mode.toString().substring(1));
72 selectionManager = new SelectionManager(this, false, mapFrame.mapView);
73 }
74
75 private static Cursor getCursor() {
76 try {
77 return ImageProvider.getCursor("crosshair", null);
78 } catch (Exception e) {
79 }
80 return Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
81 }
82
83 @Override public void enterMode() {
84 super.enterMode();
85 Main.map.mapView.addMouseListener(this);
86 Main.map.mapView.addMouseMotionListener(this);
87 }
88
89 @Override public void exitMode() {
90 super.exitMode();
91 Main.map.mapView.removeMouseListener(this);
92 Main.map.mapView.removeMouseMotionListener(this);
93 }
94
95 /**
96 * If the left mouse button is pressed, move all currently selected
97 * objects (if one of them is under the mouse) or the current one under the
98 * mouse (which will become selected).
99 */
100 @Override public void mouseDragged(MouseEvent e) {
101 if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0)
102 return;
103
104 if (selectionMode)
105 return;
106
107 if (mousePos == null)
108 mousePos = e.getPoint();
109
110 EastNorth mouseEN = Main.map.mapView.getEastNorth(e.getX(), e.getY());
111 EastNorth mouseStartEN = Main.map.mapView.getEastNorth(mousePos.x, mousePos.y);
112 double dx = mouseEN.east() - mouseStartEN.east();
113 double dy = mouseEN.north() - mouseStartEN.north();
114 if (dx == 0 && dy == 0)
115 return;
116
117 Collection<OsmPrimitive> selection = Main.ds.getSelected();
118 Collection<Node> affectedNodes = AllNodesVisitor.getAllNodes(selection);
119
120 // when rotating, having only one node makes no sense - quit silently
121 if (mode == Mode.rotate && affectedNodes.size() < 2)
122 return;
123
124
125 // check if any coordinate would be outside the world
126 for (OsmPrimitive osm : affectedNodes) {
127 if (osm instanceof Node && ((Node)osm).coor.isOutSideWorld()) {
128 JOptionPane.showMessageDialog(Main.parent,tr("Cannot move objects outside of the world."));
129 return;
130 }
131 }
132 Command c = !Main.main.undoRedo.commands.isEmpty() ? Main.main.undoRedo.commands.getLast() : null;
133
134 if (mode == Mode.move) {
135 if (c instanceof MoveCommand && affectedNodes.equals(((MoveCommand)c).objects))
136 ((MoveCommand)c).moveAgain(dx,dy);
137 else
138 Main.main.undoRedo.add(new MoveCommand(selection, dx, dy));
139 } else if (mode == Mode.rotate) {
140 if (c instanceof RotateCommand && affectedNodes.equals(((RotateCommand)c).objects))
141 ((RotateCommand)c).rotateAgain(mouseStartEN, mouseEN);
142 else
143 Main.main.undoRedo.add(new RotateCommand(selection, mouseStartEN, mouseEN));
144 }
145
146 Main.map.mapView.repaint();
147 mousePos = e.getPoint();
148 }
149
150 /**
151 * Look, whether any object is selected. If not, select the nearest node.
152 * If there are no nodes in the dataset, do nothing.
153 *
154 * If the user did not press the left mouse button, do nothing.
155 *
156 * Also remember the starting position of the movement and change the mouse
157 * cursor to movement.
158 */
159 @Override public void mousePressed(MouseEvent e) {
160 if (e.getButton() != MouseEvent.BUTTON1)
161 return;
162
163 Collection<OsmPrimitive> sel = Main.ds.getSelected();
164 OsmPrimitive osm = Main.map.mapView.getNearest(e.getPoint());
165 if (osm != null) {
166 if (!sel.contains(osm))
167 Main.ds.setSelected(osm);
168 oldCursor = Main.map.mapView.getCursor();
169
170 if (mode == Mode.move) {
171 Main.map.mapView.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
172 } else {
173 Main.map.mapView.setCursor(ImageProvider.getCursor("rotate", null));
174 }
175 } else {
176 selectionMode = true;
177 selectionManager.register(Main.map.mapView);
178 }
179
180 Main.map.mapView.repaint();
181
182 mousePos = e.getPoint();
183 }
184
185 /**
186 * Restore the old mouse cursor.
187 */
188 @Override public void mouseReleased(MouseEvent e) {
189 if (selectionMode) {
190 selectionManager.unregister(Main.map.mapView);
191 selectionMode = false;
192 } else
193 Main.map.mapView.setCursor(oldCursor);
194 }
195
196
197 public void selectionEnded(Rectangle r, boolean alt, boolean shift, boolean ctrl) {
198 SelectionAction.selectEverythingInRectangle(selectionManager, r, alt, shift, ctrl);
199 }
200}
Note: See TracBrowser for help on using the repository browser.