source: josm/trunk/src/org/openstreetmap/josm/actions/JumpToAction.java@ 11329

Last change on this file since 11329 was 11301, checked in by simon04, 7 years ago

Jump to Position: automatically paste URL from clipboard

Also, use OsmUrlToBounds for parsing bounds from URL

  • Property svn:eol-style set to native
File size: 7.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.BorderLayout;
8import java.awt.GridBagLayout;
9import java.awt.event.ActionEvent;
10import java.awt.event.KeyEvent;
11import java.util.Optional;
12
13import javax.swing.JLabel;
14import javax.swing.JOptionPane;
15import javax.swing.JPanel;
16import javax.swing.event.DocumentEvent;
17import javax.swing.event.DocumentListener;
18
19import org.openstreetmap.josm.Main;
20import org.openstreetmap.josm.data.Bounds;
21import org.openstreetmap.josm.data.coor.LatLon;
22import org.openstreetmap.josm.gui.ExtendedDialog;
23import org.openstreetmap.josm.gui.MapView;
24import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
25import org.openstreetmap.josm.gui.widgets.JosmTextField;
26import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
27import org.openstreetmap.josm.tools.GBC;
28import org.openstreetmap.josm.tools.ImageProvider;
29import org.openstreetmap.josm.tools.OsmUrlToBounds;
30import org.openstreetmap.josm.tools.Shortcut;
31
32/**
33 * Allows to jump to a specific location.
34 * @since 2575
35 */
36public class JumpToAction extends JosmAction {
37
38 /**
39 * Constructs a new {@code JumpToAction}.
40 */
41 public JumpToAction() {
42 super(tr("Jump To Position"), (ImageProvider) null, tr("Opens a dialog that allows to jump to a specific location"),
43 Shortcut.registerShortcut("tools:jumpto", tr("Tool: {0}", tr("Jump To Position")),
44 KeyEvent.VK_J, Shortcut.CTRL), true, "action/jumpto", true);
45 putValue("help", ht("/Action/JumpToPosition"));
46 }
47
48 private final JosmTextField url = new JosmTextField();
49 private final JosmTextField lat = new JosmTextField();
50 private final JosmTextField lon = new JosmTextField();
51 private final JosmTextField zm = new JosmTextField();
52
53 class OsmURLListener implements DocumentListener {
54 @Override
55 public void changedUpdate(DocumentEvent e) {
56 parseURL();
57 }
58
59 @Override
60 public void insertUpdate(DocumentEvent e) {
61 parseURL();
62 }
63
64 @Override
65 public void removeUpdate(DocumentEvent e) {
66 parseURL();
67 }
68 }
69
70 class OsmLonLatListener implements DocumentListener {
71 @Override
72 public void changedUpdate(DocumentEvent e) {
73 updateUrl(false);
74 }
75
76 @Override
77 public void insertUpdate(DocumentEvent e) {
78 updateUrl(false);
79 }
80
81 @Override
82 public void removeUpdate(DocumentEvent e) {
83 updateUrl(false);
84 }
85 }
86
87 /**
88 * Displays the "Jump to" dialog.
89 */
90 public void showJumpToDialog() {
91 if (!Main.isDisplayingMapView()) {
92 return;
93 }
94 MapView mv = Main.map.mapView;
95
96 final Optional<Bounds> boundsFromClipboard = Optional
97 .ofNullable(ClipboardUtils.getClipboardStringContent())
98 .map(OsmUrlToBounds::parse);
99 if (boundsFromClipboard.isPresent()) {
100 setBounds(boundsFromClipboard.get());
101 } else {
102 setBounds(mv.getState().getViewArea().getCornerBounds());
103 }
104 updateUrl(true);
105
106 JPanel panel = new JPanel(new BorderLayout());
107 panel.add(new JLabel("<html>"
108 + tr("Enter Lat/Lon to jump to position.")
109 + "<br>"
110 + tr("You can also paste an URL from www.openstreetmap.org")
111 + "<br>"
112 + "</html>"),
113 BorderLayout.NORTH);
114
115 OsmLonLatListener x = new OsmLonLatListener();
116 lat.getDocument().addDocumentListener(x);
117 lon.getDocument().addDocumentListener(x);
118 zm.getDocument().addDocumentListener(x);
119 url.getDocument().addDocumentListener(new OsmURLListener());
120
121 SelectAllOnFocusGainedDecorator.decorate(lat);
122 SelectAllOnFocusGainedDecorator.decorate(lon);
123 SelectAllOnFocusGainedDecorator.decorate(zm);
124 SelectAllOnFocusGainedDecorator.decorate(url);
125
126 JPanel p = new JPanel(new GridBagLayout());
127 panel.add(p, BorderLayout.NORTH);
128
129 p.add(new JLabel(tr("Latitude")), GBC.eol());
130 p.add(lat, GBC.eol().fill(GBC.HORIZONTAL));
131
132 p.add(new JLabel(tr("Longitude")), GBC.eol());
133 p.add(lon, GBC.eol().fill(GBC.HORIZONTAL));
134
135 p.add(new JLabel(tr("Zoom (in metres)")), GBC.eol());
136 p.add(zm, GBC.eol().fill(GBC.HORIZONTAL));
137
138 p.add(new JLabel(tr("URL")), GBC.eol());
139 p.add(url, GBC.eol().fill(GBC.HORIZONTAL));
140
141 String[] buttons = {tr("Jump there"), tr("Cancel")};
142 LatLon ll = null;
143 double zoomLvl = 100;
144 while (ll == null) {
145 final int option = new ExtendedDialog(Main.parent, tr("Jump to Position"), buttons) {{
146 setContent(panel);
147 setCancelButton(2);
148 }}.showDialog().getValue();
149
150 if (option != 1) return;
151 try {
152 zoomLvl = Double.parseDouble(zm.getText());
153 ll = new LatLon(Double.parseDouble(lat.getText()), Double.parseDouble(lon.getText()));
154 } catch (NumberFormatException ex) {
155 try {
156 ll = LatLon.parse(lat.getText() + "; " + lon.getText());
157 } catch (IllegalArgumentException ex2) {
158 JOptionPane.showMessageDialog(Main.parent,
159 tr("Could not parse Latitude, Longitude or Zoom. Please check."),
160 tr("Unable to parse Lon/Lat"), JOptionPane.ERROR_MESSAGE);
161 }
162 }
163 }
164
165 double zoomFactor = 1/ mv.getDist100Pixel();
166 mv.zoomToFactor(mv.getProjection().latlon2eastNorth(ll), zoomFactor * zoomLvl);
167 }
168
169 private void parseURL() {
170 if (!url.hasFocus()) return;
171 String urlText = url.getText();
172 Bounds b = OsmUrlToBounds.parse(urlText);
173 setBounds(b);
174 }
175
176 private void setBounds(Bounds b) {
177 if (b != null) {
178 final LatLon center = b.getCenter();
179 lat.setText(Double.toString(center.lat()));
180 lon.setText(Double.toString(center.lon()));
181 zm.setText(Double.toString(OsmUrlToBounds.getZoom(b)));
182 }
183 }
184
185 private void updateUrl(boolean force) {
186 if (!lat.hasFocus() && !lon.hasFocus() && !zm.hasFocus() && !force) return;
187 try {
188 double dlat = Double.parseDouble(lat.getText());
189 double dlon = Double.parseDouble(lon.getText());
190 double zoomLvl = Double.parseDouble(zm.getText());
191 url.setText(OsmUrlToBounds.getURL(dlat, dlon, (int) zoomLvl));
192 } catch (NumberFormatException x) {
193 Main.debug(x.getMessage());
194 }
195 }
196
197 @Override
198 public void actionPerformed(ActionEvent e) {
199 showJumpToDialog();
200 }
201
202 @Override
203 protected void updateEnabledState() {
204 setEnabled(Main.isDisplayingMapView());
205 }
206
207 @Override
208 protected void installAdapters() {
209 super.installAdapters();
210 // make this action listen to mapframe change events
211 Main.addMapFrameListener((o, n) -> updateEnabledState());
212 }
213}
Note: See TracBrowser for help on using the repository browser.