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

Revision 4982, 10.1 KB checked in by stoecker, 3 months ago (diff)

see #7226 - patch by akks (fixed a bit) - fix shortcut deprecations

  • 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        /* 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.map != null) {
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.map != null && Main.map.mapView != null && Main.map.mapView.hasZoomUndoEntries());
240        } else if ("next".equals(mode)) {
241            setEnabled(Main.map != null && Main.map.mapView != null && 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.