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

Last change on this file since 2758 was 2758, checked in by mjulius, 14 years ago

fixes #1653 - zoom to the previously shown area
This adds menu entries and the shortcuts '8' and '9' to zoom to the previous and next areas. See also http://josm.openstreetmap.de/wiki/Help/Menu/View

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