Ticket #164: continuous-selection.2

File continuous-selection.2, 6.9 KB (added by guilhem.bonnefille@…, 19 years ago)

The (new) patch

Line 
1Add a continuous selection
2
3From: <>
4
5Select all continuous segments
6---
7
8 images/mapmode/selection/continuous.png | Bin
9 .../josm/actions/mapmode/SelectionAction.java | 124 ++++++++++++++++++++---
10 2 files changed, 109 insertions(+), 15 deletions(-)
11
12diff --git a/images/mapmode/selection/continuous.png b/images/mapmode/selection/continuous.png
13new file mode 100644
14index 0000000..6c05cb7
15Binary files /dev/null and b/images/mapmode/selection/continuous.png differ
16diff --git a/src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java b/src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java
17index 62d747b..8167522 100644
18--- a/src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java
19+++ b/src/org/openstreetmap/josm/actions/mapmode/SelectionAction.java
20@@ -63,7 +63,7 @@ import org.openstreetmap.josm.tools.ImageProvider;
21 */
22 public class SelectionAction extends MapMode implements SelectionEnded {
23
24- enum Mode {select, straight}
25+ enum Mode {select, straight, continuous}
26 private final Mode mode;
27
28 public static class Group extends GroupAction {
29@@ -72,6 +72,7 @@ public class SelectionAction extends MapMode implements SelectionEnded {
30 putValue("help", "Action/Selection");
31 actions.add(new SelectionAction(mf, tr("Selection"), Mode.select, tr("Select objects by dragging or clicking.")));
32 actions.add(new SelectionAction(mf, tr("Straight line"), Mode.straight, tr("Select objects in a straight line.")));
33+ actions.add(new SelectionAction(mf, tr("Continuous segments"), Mode.continuous, tr("Select continuous segments.")));
34 setCurrent(0);
35 }
36 }
37@@ -85,10 +86,10 @@ public class SelectionAction extends MapMode implements SelectionEnded {
38 private Node straightStart = null;
39 private Node lastEnd = null;
40 private Collection<OsmPrimitive> oldSelection = null;
41-
42+
43 //TODO: Implement reverse references into data objects and remove this
44 private final Map<Node, Collection<Segment>> reverseSegmentMap = new HashMap<Node, Collection<Segment>>();
45-
46+
47 /**
48 * Create a new SelectionAction in the given frame.
49 * @param mapFrame The frame this action belongs to
50@@ -104,13 +105,19 @@ public class SelectionAction extends MapMode implements SelectionEnded {
51 super.enterMode();
52 if (mode == Mode.select)
53 selectionManager.register(Main.map.mapView);
54- else {
55+ else if (mode == Mode.straight) {
56 Main.map.mapView.addMouseMotionListener(this);
57 Main.map.mapView.addMouseListener(this);
58 for (Segment s : Main.ds.segments) {
59 addBackReference(s.from, s);
60 addBackReference(s.to, s);
61 }
62+ } else if (mode == Mode.continuous) {
63+ Main.map.mapView.addMouseListener(this);
64+ for (Segment s : Main.ds.segments) {
65+ addBackReference(s.from, s);
66+ addBackReference(s.to, s);
67+ }
68 }
69 }
70
71@@ -127,10 +134,12 @@ public class SelectionAction extends MapMode implements SelectionEnded {
72 super.exitMode();
73 if (mode == Mode.select)
74 selectionManager.unregister(Main.map.mapView);
75- else {
76+ else if (mode == Mode.straight) {
77 Main.map.mapView.removeMouseMotionListener(this);
78 Main.map.mapView.removeMouseListener(this);
79 reverseSegmentMap.clear();
80+ } else if (mode == Mode.continuous) {
81+ Main.map.mapView.removeMouseListener(this);
82 }
83 }
84
85@@ -169,21 +178,59 @@ public class SelectionAction extends MapMode implements SelectionEnded {
86 straightStart = lastEnd;
87 if (straightStart != null && lastEnd != null && straightStart != lastEnd && old != lastEnd) {
88 Collection<OsmPrimitive> path = new HashSet<OsmPrimitive>();
89- Collection<OsmPrimitive> sel = new HashSet<OsmPrimitive>();
90 path.add(straightStart);
91 calculateShortestPath(path, straightStart, lastEnd);
92- if ((e.getModifiers() & MouseEvent.CTRL_MASK) != 0) {
93- sel.addAll(oldSelection);
94- sel.removeAll(path);
95- } else if ((e.getModifiers() & MouseEvent.SHIFT_MASK) != 0) {
96- sel = path;
97- sel.addAll(oldSelection);
98- } else
99- sel = path;
100- Main.ds.setSelected(sel);
101+ updateSelection(e, path);
102 }
103 }
104
105+ /**
106+ * Update the selection.
107+ *
108+ * Handles the modifier key.
109+ *
110+ * @param e
111+ * @param path the path to use for updating.
112+ */
113+ private void updateSelection(MouseEvent e, Collection<OsmPrimitive> path) {
114+ oldSelection = Main.ds.getSelected();
115+ Collection<OsmPrimitive> sel = new HashSet<OsmPrimitive>();
116+ if ((e.getModifiers() & MouseEvent.CTRL_MASK) != 0) {
117+ sel.addAll(oldSelection);
118+ sel.removeAll(path);
119+ } else if ((e.getModifiers() & MouseEvent.SHIFT_MASK) != 0) {
120+ sel = path;
121+ sel.addAll(oldSelection);
122+ } else
123+ sel = path;
124+ Main.ds.setSelected(sel);
125+ }
126+
127+ /**
128+ * Continuous selection.
129+ *
130+ * Does a continuous selection.
131+ *
132+ * @param e
133+ */
134+ private void continuousSelection(MouseEvent e) {
135+ // Retrieve the initial segment
136+ Segment initialSegment = Main.map.mapView.getNearestSegment(e.getPoint());
137+ if (initialSegment != null) {
138+ // Initialise the path
139+ Collection<OsmPrimitive> path = new HashSet<OsmPrimitive>();
140+ path.add(initialSegment);
141+ // Fill the path with continuous segments
142+ calculateContinuousPath(path, initialSegment);
143+ // Update the selection with the path
144+ updateSelection(e, path);
145+ }
146+ }
147+
148+ @Override public void mouseClicked(MouseEvent e) {
149+ if (mode == Mode.continuous && e.getButton() == MouseEvent.BUTTON1) continuousSelection(e);
150+ }
151+
152 @Override public void mousePressed(MouseEvent e) {
153 straightStart = Main.map.mapView.getNearestNode(e.getPoint());
154 lastEnd = null;
155@@ -234,4 +281,51 @@ public class SelectionAction extends MapMode implements SelectionEnded {
156 }
157 return null;
158 }
159+
160+ /**
161+ * Get the continuous path.
162+ *
163+ * @param path Path to fill in
164+ * @param initial initial segment
165+ */
166+ private void calculateContinuousPath(Collection<OsmPrimitive> path, Segment initial) {
167+ Segment current = null;
168+ Segment next = initial;
169+ Collection<Segment> c = null;
170+ // Reverse order
171+ while ((current = next) != null && (c = reverseSegmentMap.get(current.from)) != null && c.size() == 2) {
172+ for (Segment s : c) {
173+ if (s != current) {
174+ // s is the other segment connected to current node
175+ if (s != initial && s.to == current.from) {
176+ // s is the preceding segment
177+ path.add(s);
178+ next = s;
179+ } else
180+ // s and next are connected to the same node, but in opposite direction.
181+ // Stop here.
182+ next = null;
183+ }
184+ }
185+ }
186+
187+ next = initial;
188+ // Correct order
189+ while ((current = next) != null && (c = reverseSegmentMap.get(current.to)) != null && c.size() == 2) {
190+ for (Segment s : c) {
191+ if (s != current) {
192+ // s is the other segment connected to current node
193+ if (s != initial && s.from == current.to) {
194+ // s is the preceding segment
195+ path.add(s);
196+ next = s;
197+ } else
198+ // s and next are connected to the same node, but in opposite direction.
199+ // Stop here.
200+ next = null;
201+ }
202+ }
203+ }
204+
205+ }
206 }