source: josm/trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java@ 361

Last change on this file since 361 was 361, checked in by gebner, 17 years ago

Fix build.

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