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

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

fix some Sonar issues (Constructor Calls Overridable Method)

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