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

Revision 3973, 10.2 KB checked in by mjulius, 11 months ago (diff)

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
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.