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

Last change on this file since 5508 was 5460, checked in by Don-vip, 12 years ago

global use of Main.isDisplayingMapView()

  • Property svn:eol-style set to native
File size: 10.1 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 /* leave as single line for shortcut overview parsing! */
85 if (mode.equals("data")) { shortcut = KeyEvent.VK_1; }
86 else if (mode.equals("layer")) { shortcut = KeyEvent.VK_2; }
87 else if (mode.equals("selection")) { shortcut = KeyEvent.VK_3; }
88 else if (mode.equals("conflict")) { shortcut = KeyEvent.VK_4; }
89 else if (mode.equals("download")) { shortcut = KeyEvent.VK_5; }
90 else if (mode.equals("previous")) { shortcut = KeyEvent.VK_8; }
91 else if (mode.equals("next")) { shortcut = KeyEvent.VK_9; }
92
93 return shortcut;
94 }
95
96 /**
97 *
98 * @param mode
99 * @param marker Used only to differentiate from default constructor
100 */
101 private AutoScaleAction(String mode, boolean marker) {
102 super(false);
103 this.mode = mode;
104 }
105
106
107 public AutoScaleAction(String mode) {
108 super(tr("Zoom to {0}", tr(mode)), "dialogs/autoscale/" + mode, tr("Zoom the view to {0}.", tr(mode)),
109 Shortcut.registerShortcut("view:zoom"+mode, tr("View: {0}", tr("Zoom to {0}", tr(mode))), getModeShortcut(mode), Shortcut.DIRECT), true);
110 String modeHelp = Character.toUpperCase(mode.charAt(0)) + mode.substring(1);
111 putValue("help", "Action/AutoScale/" + modeHelp);
112 this.mode = mode;
113 if (mode.equals("data")) {
114 putValue("help", ht("/Action/ZoomToData"));
115 } else if (mode.equals("layer")) {
116 putValue("help", ht("/Action/ZoomToLayer"));
117 } else if (mode.equals("selection")) {
118 putValue("help", ht("/Action/ZoomToSelection"));
119 } else if (mode.equals("conflict")) {
120 putValue("help", ht("/Action/ZoomToConflict"));
121 } else if (mode.equals("download")) {
122 putValue("help", ht("/Action/ZoomToDownload"));
123 } else if (mode.equals("previous")) {
124 putValue("help", ht("/Action/ZoomToPrevious"));
125 } else if (mode.equals("next")) {
126 putValue("help", ht("/Action/ZoomToNext"));
127 }
128 }
129
130 public void autoScale() {
131 if (Main.isDisplayingMapView()) {
132 if (mode.equals("previous")) {
133 Main.map.mapView.zoomPrevious();
134 } else if (mode.equals("next")) {
135 Main.map.mapView.zoomNext();
136 } else {
137 BoundingXYVisitor bbox = getBoundingBox();
138 if (bbox != null && bbox.getBounds() != null) {
139 Main.map.mapView.recalculateCenterScale(bbox);
140 }
141 }
142 }
143 putValue("active", true);
144 }
145
146 public void actionPerformed(ActionEvent e) {
147 autoScale();
148 }
149
150 protected Layer getActiveLayer() {
151 try {
152 return Main.map.mapView.getActiveLayer();
153 } catch(NullPointerException e) {
154 return null;
155 }
156 }
157
158 /**
159 * Replies the first selected layer in the layer list dialog. null, if no
160 * such layer exists, either because the layer list dialog is not yet created
161 * or because no layer is selected.
162 *
163 * @return the first selected layer in the layer list dialog
164 */
165 protected Layer getFirstSelectedLayer() {
166 if (LayerListDialog.getInstance() == null) return null;
167 List<Layer> layers = LayerListDialog.getInstance().getModel().getSelectedLayers();
168 if (layers.isEmpty()) return null;
169 return layers.get(0);
170 }
171
172 private BoundingXYVisitor getBoundingBox() {
173 BoundingXYVisitor v = new BoundingXYVisitor();
174 if (mode.equals("data")) {
175 for (Layer l : Main.map.mapView.getAllLayers()) {
176 l.visitBoundingBox(v);
177 }
178 } else if (mode.equals("layer")) {
179 if (getActiveLayer() == null)
180 return null;
181 // try to zoom to the first selected layer
182 //
183 Layer l = getFirstSelectedLayer();
184 if (l == null) return null;
185 l.visitBoundingBox(v);
186 } else if (mode.equals("selection") || mode.equals("conflict")) {
187 Collection<OsmPrimitive> sel = new HashSet<OsmPrimitive>();
188 if (mode.equals("selection")) {
189 sel = getCurrentDataSet().getSelected();
190 } else if (mode.equals("conflict")) {
191 Conflict<? extends OsmPrimitive> c = Main.map.conflictDialog.getSelectedConflict();
192 if (c != null) {
193 sel.add(c.getMy());
194 } else if (Main.map.conflictDialog.getConflicts() != null) {
195 sel = Main.map.conflictDialog.getConflicts().getMyConflictParties();
196 }
197 }
198 if (sel.isEmpty()) {
199 JOptionPane.showMessageDialog(
200 Main.parent,
201 (mode.equals("selection") ? tr("Nothing selected to zoom to.") : tr("No conflicts to zoom to")),
202 tr("Information"),
203 JOptionPane.INFORMATION_MESSAGE
204 );
205 return null;
206 }
207 for (OsmPrimitive osm : sel) {
208 osm.visit(v);
209 }
210 // increase bbox by 0.001 degrees on each side. this is required
211 // especially if the bbox contains one single node, but helpful
212 // in most other cases as well.
213 v.enlargeBoundingBox();
214 }
215 else if (mode.equals("download")) {
216 if (!Main.pref.get("osm-download.bounds").isEmpty()) {
217 try {
218 v.visit(new Bounds(Main.pref.get("osm-download.bounds"), ";"));
219 } catch (Exception e) {
220 e.printStackTrace();
221 }
222 }
223 }
224 return v;
225 }
226
227 @Override
228 protected void updateEnabledState() {
229 if ("selection".equals(mode)) {
230 setEnabled(getCurrentDataSet() != null && ! getCurrentDataSet().getSelected().isEmpty());
231 } else if ("layer".equals(mode)) {
232 if (Main.map == null || Main.map.mapView == null || Main.map.mapView.getAllLayersAsList().isEmpty()) {
233 setEnabled(false);
234 } else {
235 // FIXME: should also check for whether a layer is selected in the layer list dialog
236 setEnabled(true);
237 }
238 } else if ("previous".equals(mode)) {
239 setEnabled(Main.isDisplayingMapView() && Main.map.mapView.hasZoomUndoEntries());
240 } else if ("next".equals(mode)) {
241 setEnabled(Main.isDisplayingMapView() && Main.map.mapView.hasZoomRedoEntries());
242 } else {
243 setEnabled(
244 Main.isDisplayingMapView()
245 && Main.map.mapView.hasLayers()
246 );
247 }
248 }
249
250 @Override
251 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
252 if ("selection".equals(mode)) {
253 setEnabled(selection != null && !selection.isEmpty());
254 }
255 }
256
257 @Override
258 protected void installAdapters() {
259 super.installAdapters();
260 // make this action listen to zoom change events
261 //
262 zoomChangeAdapter = new ZoomChangeAdapter();
263 MapView.addZoomChangeListener(zoomChangeAdapter);
264 initEnabledState();
265 }
266
267 /**
268 * Adapter for selection change events
269 *
270 */
271 private class ZoomChangeAdapter implements MapView.ZoomChangeListener {
272 public void zoomChanged() {
273 updateEnabledState();
274 }
275 }
276
277 private ZoomChangeAdapter zoomChangeAdapter;
278}
Note: See TracBrowser for help on using the repository browser.