source: josm/trunk/src/org/openstreetmap/josm/actions/ImageryAdjustAction.java@ 7083

Last change on this file since 7083 was 7033, checked in by Don-vip, 10 years ago

see #8465 - global use of try-with-resources, according to

  • Property svn:eol-style set to native
File size: 10.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.AWTEvent;
7import java.awt.Cursor;
8import java.awt.GridBagLayout;
9import java.awt.Insets;
10import java.awt.Toolkit;
11import java.awt.event.AWTEventListener;
12import java.awt.event.ActionEvent;
13import java.awt.event.FocusEvent;
14import java.awt.event.FocusListener;
15import java.awt.event.KeyEvent;
16import java.awt.event.MouseEvent;
17import java.awt.event.MouseListener;
18import java.awt.event.MouseMotionListener;
19import java.util.Formatter;
20import java.util.Locale;
21
22import javax.swing.JLabel;
23import javax.swing.JPanel;
24
25import org.openstreetmap.josm.Main;
26import org.openstreetmap.josm.actions.mapmode.MapMode;
27import org.openstreetmap.josm.data.coor.EastNorth;
28import org.openstreetmap.josm.data.imagery.OffsetBookmark;
29import org.openstreetmap.josm.gui.ExtendedDialog;
30import org.openstreetmap.josm.gui.layer.ImageryLayer;
31import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
32import org.openstreetmap.josm.gui.widgets.JosmTextField;
33import org.openstreetmap.josm.tools.GBC;
34import org.openstreetmap.josm.tools.ImageProvider;
35
36public class ImageryAdjustAction extends MapMode implements MouseListener, MouseMotionListener, AWTEventListener{
37 static ImageryOffsetDialog offsetDialog;
38 static Cursor cursor = ImageProvider.getCursor("normal", "move");
39
40 double oldDx, oldDy;
41 boolean mouseDown;
42 EastNorth prevEastNorth;
43 private ImageryLayer layer;
44 private MapMode oldMapMode;
45
46 /**
47 * Constructs a new {@code ImageryAdjustAction} for the given layer.
48 * @param layer The imagery layer
49 */
50 public ImageryAdjustAction(ImageryLayer layer) {
51 super(tr("New offset"), "adjustimg",
52 tr("Adjust the position of this imagery layer"), Main.map,
53 cursor);
54 putValue("toolbar", false);
55 this.layer = layer;
56 }
57
58 @Override
59 public void enterMode() {
60 super.enterMode();
61 if (layer == null)
62 return;
63 if (!layer.isVisible()) {
64 layer.setVisible(true);
65 }
66 oldDx = layer.getDx();
67 oldDy = layer.getDy();
68 addListeners();
69 offsetDialog = new ImageryOffsetDialog();
70 offsetDialog.setVisible(true);
71 }
72
73 protected void addListeners() {
74 Main.map.mapView.addMouseListener(this);
75 Main.map.mapView.addMouseMotionListener(this);
76 try {
77 Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
78 } catch (SecurityException ex) {
79 Main.error(ex);
80 }
81 }
82
83 @Override
84 public void exitMode() {
85 super.exitMode();
86 if (offsetDialog != null) {
87 layer.setOffset(oldDx, oldDy);
88 offsetDialog.setVisible(false);
89 offsetDialog = null;
90 }
91 removeListeners();
92 }
93
94 protected void removeListeners() {
95 try {
96 Toolkit.getDefaultToolkit().removeAWTEventListener(this);
97 } catch (SecurityException ex) {
98 Main.error(ex);
99 }
100 if (Main.isDisplayingMapView()) {
101 Main.map.mapView.removeMouseMotionListener(this);
102 Main.map.mapView.removeMouseListener(this);
103 }
104 }
105
106 @Override
107 public void eventDispatched(AWTEvent event) {
108 if (!(event instanceof KeyEvent)) return;
109 if (event.getID() != KeyEvent.KEY_PRESSED) return;
110 if (layer == null) return;
111 if (offsetDialog != null && offsetDialog.areFieldsInFocus()) return;
112 KeyEvent kev = (KeyEvent)event;
113 double dx = 0, dy = 0;
114 switch (kev.getKeyCode()) {
115 case KeyEvent.VK_UP : dy = +1; break;
116 case KeyEvent.VK_DOWN : dy = -1; break;
117 case KeyEvent.VK_LEFT : dx = -1; break;
118 case KeyEvent.VK_RIGHT : dx = +1; break;
119 }
120 if (dx != 0 || dy != 0) {
121 double ppd = layer.getPPD();
122 layer.displace(dx / ppd, dy / ppd);
123 if (offsetDialog != null) {
124 offsetDialog.updateOffset();
125 }
126 kev.consume();
127 Main.map.repaint();
128 }
129 }
130
131 @Override
132 public void mousePressed(MouseEvent e) {
133 if (e.getButton() != MouseEvent.BUTTON1)
134 return;
135
136 if (layer.isVisible()) {
137 requestFocusInMapView();
138 prevEastNorth=Main.map.mapView.getEastNorth(e.getX(),e.getY());
139 Main.map.mapView.setNewCursor(Cursor.MOVE_CURSOR, this);
140 }
141 }
142
143 @Override
144 public void mouseDragged(MouseEvent e) {
145 if (layer == null || prevEastNorth == null) return;
146 EastNorth eastNorth =
147 Main.map.mapView.getEastNorth(e.getX(),e.getY());
148 double dx = layer.getDx()+eastNorth.east()-prevEastNorth.east();
149 double dy = layer.getDy()+eastNorth.north()-prevEastNorth.north();
150 layer.setOffset(dx, dy);
151 if (offsetDialog != null) {
152 offsetDialog.updateOffset();
153 }
154 Main.map.repaint();
155 prevEastNorth = eastNorth;
156 }
157
158 @Override
159 public void mouseReleased(MouseEvent e) {
160 Main.map.mapView.repaint();
161 Main.map.mapView.resetCursor(this);
162 prevEastNorth = null;
163 }
164
165 @Override
166 public void actionPerformed(ActionEvent e) {
167 if (offsetDialog != null || layer == null || Main.map == null)
168 return;
169 oldMapMode = Main.map.mapMode;
170 super.actionPerformed(e);
171 }
172
173 class ImageryOffsetDialog extends ExtendedDialog implements FocusListener {
174 public final JosmTextField tOffset = new JosmTextField();
175 JosmTextField tBookmarkName = new JosmTextField();
176 private boolean ignoreListener;
177 public ImageryOffsetDialog() {
178 super(Main.parent,
179 tr("Adjust imagery offset"),
180 new String[] { tr("OK"),tr("Cancel") },
181 false);
182 setButtonIcons(new String[] { "ok", "cancel" });
183 contentInsets = new Insets(10, 15, 5, 15);
184 JPanel pnl = new JPanel(new GridBagLayout());
185 pnl.add(new JMultilineLabel(tr("Use arrow keys or drag the imagery layer with mouse to adjust the imagery offset.\n" +
186 "You can also enter east and north offset in the {0} coordinates.\n" +
187 "If you want to save the offset as bookmark, enter the bookmark name below",Main.getProjection().toString())), GBC.eop());
188 pnl.add(new JLabel(tr("Offset: ")),GBC.std());
189 pnl.add(tOffset,GBC.eol().fill(GBC.HORIZONTAL).insets(0,0,0,5));
190 pnl.add(new JLabel(tr("Bookmark name: ")),GBC.std());
191 pnl.add(tBookmarkName,GBC.eol().fill(GBC.HORIZONTAL));
192 tOffset.setColumns(16);
193 updateOffsetIntl();
194 tOffset.addFocusListener(this);
195 setContent(pnl);
196 setupDialog();
197 }
198
199 public boolean areFieldsInFocus() {
200 return tOffset.hasFocus();
201 }
202
203 @Override
204 public void focusGained(FocusEvent e) {
205 }
206
207 @Override
208 public void focusLost(FocusEvent e) {
209 if (ignoreListener) return;
210 String ostr = tOffset.getText();
211 int semicolon = ostr.indexOf(';');
212 if( semicolon >= 0 && semicolon + 1 < ostr.length() ) {
213 try {
214 // here we assume that Double.parseDouble() needs '.' as a decimal separator
215 String easting = ostr.substring(0, semicolon).trim().replace(',', '.');
216 String northing = ostr.substring(semicolon + 1).trim().replace(',', '.');
217 double dx = Double.parseDouble(easting);
218 double dy = Double.parseDouble(northing);
219 layer.setOffset(dx, dy);
220 } catch (NumberFormatException nfe) {
221 // we repaint offset numbers in any case
222 }
223 }
224 updateOffsetIntl();
225 if (Main.isDisplayingMapView()) {
226 Main.map.repaint();
227 }
228 }
229
230 public final void updateOffset() {
231 ignoreListener = true;
232 updateOffsetIntl();
233 ignoreListener = false;
234 }
235
236 public final void updateOffsetIntl() {
237 // Support projections with very small numbers (e.g. 4326)
238 int precision = Main.getProjection().getDefaultZoomInPPD() >= 1.0 ? 2 : 7;
239 // US locale to force decimal separator to be '.'
240 try (Formatter us = new Formatter(Locale.US)) {
241 tOffset.setText(us.format(
242 "%1." + precision + "f; %1." + precision + "f",
243 layer.getDx(), layer.getDy()).toString());
244 }
245 }
246
247 private boolean confirmOverwriteBookmark() {
248 ExtendedDialog dialog = new ExtendedDialog(
249 Main.parent,
250 tr("Overwrite"),
251 new String[] {tr("Overwrite"), tr("Cancel")}
252 ) {{
253 contentInsets = new Insets(10, 15, 10, 15);
254 }};
255 dialog.setContent(tr("Offset bookmark already exists. Overwrite?"));
256 dialog.setButtonIcons(new String[] {"ok.png", "cancel.png"});
257 dialog.setupDialog();
258 dialog.setVisible(true);
259 return dialog.getValue() == 1;
260 }
261
262 @Override
263 protected void buttonAction(int buttonIndex, ActionEvent evt) {
264 if (buttonIndex == 0 && tBookmarkName.getText() != null && !tBookmarkName.getText().isEmpty() &&
265 OffsetBookmark.getBookmarkByName(layer, tBookmarkName.getText()) != null) {
266 if (!confirmOverwriteBookmark()) return;
267 }
268 super.buttonAction(buttonIndex, evt);
269 }
270
271 @Override
272 public void setVisible(boolean visible) {
273 super.setVisible(visible);
274 if (visible) return;
275 offsetDialog = null;
276 if (getValue() != 1) {
277 layer.setOffset(oldDx, oldDy);
278 } else if (tBookmarkName.getText() != null && !tBookmarkName.getText().isEmpty()) {
279 OffsetBookmark.bookmarkOffset(tBookmarkName.getText(), layer);
280 }
281 Main.main.menu.imageryMenu.refreshOffsetMenu();
282 if (Main.map == null) return;
283 if (oldMapMode != null) {
284 Main.map.selectMapMode(oldMapMode);
285 oldMapMode = null;
286 } else {
287 Main.map.selectSelectTool(false);
288 }
289 }
290 }
291
292 @Override
293 public void destroy() {
294 super.destroy();
295 removeListeners();
296 this.layer = null;
297 this.oldMapMode = null;
298 }
299}
Note: See TracBrowser for help on using the repository browser.