source: josm/trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java@ 4851

Last change on this file since 4851 was 3973, checked in by mjulius, 13 years ago

Zoom to conflict now zooms to first selected conflict if there is one selected. Otherwise it zooms to all conflicts (as before).
closes #3266

  • Property svn:eol-style set to native
File size: 10.2 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.marktr;
6import static org.openstreetmap.josm.tools.I18n.tr;
7
8import java.awt.event.ActionEvent;
9import java.awt.event.KeyEvent;
10import java.util.Collection;
11import java.util.HashSet;
12import java.util.List;
13
14import javax.swing.JOptionPane;
15
16import org.openstreetmap.josm.Main;
17import org.openstreetmap.josm.data.Bounds;
18import org.openstreetmap.josm.data.conflict.Conflict;
19import org.openstreetmap.josm.data.osm.OsmPrimitive;
20import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
21import org.openstreetmap.josm.gui.MapView;
22import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
23import org.openstreetmap.josm.gui.layer.Layer;
24import org.openstreetmap.josm.tools.Shortcut;
25
26/**
27 * Toggles the autoScale feature of the mapView
28 * @author imi
29 */
30public class AutoScaleAction extends JosmAction {
31
32 public static final String[] MODES = {
33 marktr("data"),
34 marktr("layer"),
35 marktr("selection"),
36 marktr("conflict"),
37 marktr("download"),
38 marktr("previous"),
39 marktr("next")};
40
41 /**
42 * Zooms the current map view to the currently selected primitives.
43 * Does nothing if there either isn't a current map view or if there isn't a current data
44 * layer.
45 *
46 */
47 public static void zoomToSelection() {
48 if (Main.main == null || Main.main.getEditLayer() == null) return;
49 if (Main.map == null || Main.map.mapView == null) return;
50 Collection<OsmPrimitive> sel = Main.main.getEditLayer().data.getSelected();
51 if (sel.isEmpty()) {
52 JOptionPane.showMessageDialog(
53 Main.parent,
54 tr("Nothing selected to zoom to."),
55 tr("Information"),
56 JOptionPane.INFORMATION_MESSAGE
57 );
58 return;
59 }
60 zoomTo(sel);
61 }
62
63 public static void zoomTo(Collection<OsmPrimitive> sel) {
64 BoundingXYVisitor bboxCalculator = new BoundingXYVisitor();
65 bboxCalculator.computeBoundingBox(sel);
66 // increase bbox by 0.001 degrees on each side. this is required
67 // especially if the bbox contains one single node, but helpful
68 // in most other cases as well.
69 bboxCalculator.enlargeBoundingBox();
70 if (bboxCalculator.getBounds() != null) {
71 Main.map.mapView.recalculateCenterScale(bboxCalculator);
72 }
73 }
74
75 public static void autoScale(String mode) {
76 new AutoScaleAction(mode, false).autoScale();
77 }
78
79 private final String mode;
80
81 private static int getModeShortcut(String mode) {
82 int shortcut = -1;
83
84 if (mode.equals("data")) {
85 shortcut = KeyEvent.VK_1;
86 }
87 if (mode.equals("layer")) {
88 shortcut = KeyEvent.VK_2;
89 }
90 if (mode.equals("selection")) {
91 shortcut = KeyEvent.VK_3;
92 }
93 if (mode.equals("conflict")) {
94 shortcut = KeyEvent.VK_4;
95 }
96 if (mode.equals("download")) {
97 shortcut = KeyEvent.VK_5;
98 }
99 if (mode.equals("previous")) {
100 shortcut = KeyEvent.VK_8;
101 }
102 if (mode.equals("next")) {
103 shortcut = KeyEvent.VK_9;
104 }
105
106 return shortcut;
107 }
108
109 /**
110 *
111 * @param mode
112 * @param marker Used only to differentiate from default constructor
113 */
114 private AutoScaleAction(String mode, boolean marker) {
115 super(false);
116 this.mode = mode;
117 }
118
119
120 public AutoScaleAction(String mode) {
121 super(tr("Zoom to {0}", tr(mode)), "dialogs/autoscale/" + mode, tr("Zoom the view to {0}.", tr(mode)),
122 Shortcut.registerShortcut("view:zoom"+mode, tr("View: {0}", tr("Zoom to {0}", tr(mode))), getModeShortcut(mode), Shortcut.GROUP_EDIT), true);
123 String modeHelp = Character.toUpperCase(mode.charAt(0)) + mode.substring(1);
124 putValue("help", "Action/AutoScale/" + modeHelp);
125 this.mode = mode;
126 if (mode.equals("data")) {
127 putValue("help", ht("/Action/ZoomToData"));
128 } else if (mode.equals("layer")) {
129 putValue("help", ht("/Action/ZoomToLayer"));
130 } else if (mode.equals("selection")) {
131 putValue("help", ht("/Action/ZoomToSelection"));
132 } else if (mode.equals("conflict")) {
133 putValue("help", ht("/Action/ZoomToConflict"));
134 } else if (mode.equals("download")) {
135 putValue("help", ht("/Action/ZoomToDownload"));
136 } else if (mode.equals("previous")) {
137 putValue("help", ht("/Action/ZoomToPrevious"));
138 } else if (mode.equals("next")) {
139 putValue("help", ht("/Action/ZoomToNext"));
140 }
141 }
142
143 public void autoScale() {
144 if (Main.map != null) {
145 if (mode.equals("previous")) {
146 Main.map.mapView.zoomPrevious();
147 } else if (mode.equals("next")) {
148 Main.map.mapView.zoomNext();
149 } else {
150 BoundingXYVisitor bbox = getBoundingBox();
151 if (bbox != null && bbox.getBounds() != null) {
152 Main.map.mapView.recalculateCenterScale(bbox);
153 }
154 }
155 }
156 putValue("active", true);
157 }
158
159 public void actionPerformed(ActionEvent e) {
160 autoScale();
161 }
162
163 protected Layer getActiveLayer() {
164 try {
165 return Main.map.mapView.getActiveLayer();
166 } catch(NullPointerException e) {
167 return null;
168 }
169 }
170
171 /**
172 * Replies the first selected layer in the layer list dialog. null, if no
173 * such layer exists, either because the layer list dialog is not yet created
174 * or because no layer is selected.
175 *
176 * @return the first selected layer in the layer list dialog
177 */
178 protected Layer getFirstSelectedLayer() {
179 if (LayerListDialog.getInstance() == null) return null;
180 List<Layer> layers = LayerListDialog.getInstance().getModel().getSelectedLayers();
181 if (layers.isEmpty()) return null;
182 return layers.get(0);
183 }
184
185 private BoundingXYVisitor getBoundingBox() {
186 BoundingXYVisitor v = new BoundingXYVisitor();
187 if (mode.equals("data")) {
188 for (Layer l : Main.map.mapView.getAllLayers()) {
189 l.visitBoundingBox(v);
190 }
191 } else if (mode.equals("layer")) {
192 if (getActiveLayer() == null)
193 return null;
194 // try to zoom to the first selected layer
195 //
196 Layer l = getFirstSelectedLayer();
197 if (l == null) return null;
198 l.visitBoundingBox(v);
199 } else if (mode.equals("selection") || mode.equals("conflict")) {
200 Collection<OsmPrimitive> sel = new HashSet<OsmPrimitive>();
201 if (mode.equals("selection")) {
202 sel = getCurrentDataSet().getSelected();
203 } else if (mode.equals("conflict")) {
204 Conflict<? extends OsmPrimitive> c = Main.map.conflictDialog.getSelectedConflict();
205 if (c != null) {
206 sel.add(c.getMy());
207 } else if (Main.map.conflictDialog.getConflicts() != null) {
208 sel = Main.map.conflictDialog.getConflicts().getMyConflictParties();
209 }
210 }
211 if (sel.isEmpty()) {
212 JOptionPane.showMessageDialog(
213 Main.parent,
214 (mode.equals("selection") ? tr("Nothing selected to zoom to.") : tr("No conflicts to zoom to")),
215 tr("Information"),
216 JOptionPane.INFORMATION_MESSAGE
217 );
218 return null;
219 }
220 for (OsmPrimitive osm : sel) {
221 osm.visit(v);
222 }
223 // increase bbox by 0.001 degrees on each side. this is required
224 // especially if the bbox contains one single node, but helpful
225 // in most other cases as well.
226 v.enlargeBoundingBox();
227 }
228 else if (mode.equals("download")) {
229 if (Main.pref.hasKey("osm-download.bounds")) {
230 try {
231 v.visit(new Bounds(Main.pref.get("osm-download.bounds"), ";"));
232 } catch (Exception e) {
233 e.printStackTrace();
234 }
235 }
236 }
237 return v;
238 }
239
240 @Override
241 protected void updateEnabledState() {
242 if ("selection".equals(mode)) {
243 setEnabled(getCurrentDataSet() != null && ! getCurrentDataSet().getSelected().isEmpty());
244 } else if ("layer".equals(mode)) {
245 if (Main.map == null || Main.map.mapView == null || Main.map.mapView.getAllLayersAsList().isEmpty()) {
246 setEnabled(false);
247 } else {
248 // FIXME: should also check for whether a layer is selected in the layer list dialog
249 setEnabled(true);
250 }
251 } else if ("previous".equals(mode)) {
252 setEnabled(Main.map != null && Main.map.mapView != null && Main.map.mapView.hasZoomUndoEntries());
253 } else if ("next".equals(mode)) {
254 setEnabled(Main.map != null && Main.map.mapView != null && Main.map.mapView.hasZoomRedoEntries());
255 } else {
256 setEnabled(
257 Main.isDisplayingMapView()
258 && Main.map.mapView.hasLayers()
259 );
260 }
261 }
262
263 @Override
264 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
265 if ("selection".equals(mode)) {
266 setEnabled(selection != null && !selection.isEmpty());
267 }
268 }
269
270 @Override
271 protected void installAdapters() {
272 super.installAdapters();
273 // make this action listen to zoom change events
274 //
275 zoomChangeAdapter = new ZoomChangeAdapter();
276 MapView.addZoomChangeListener(zoomChangeAdapter);
277 initEnabledState();
278 }
279
280 /**
281 * Adapter for selection change events
282 *
283 */
284 private class ZoomChangeAdapter implements MapView.ZoomChangeListener {
285 public void zoomChanged() {
286 updateEnabledState();
287 }
288 }
289
290 private ZoomChangeAdapter zoomChangeAdapter;
291}
Note: See TracBrowser for help on using the repository browser.