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

Last change on this file since 3734 was 3327, checked in by jttt, 14 years ago

Fix some of "Keystroke %s is already assigned to %s, will be overridden by %s" warnings

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