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

Last change on this file since 5886 was 5886, checked in by Don-vip, 11 years ago

see #4429 - Right click menu "undo, cut, copy, paste, delete, select all" for each text component (originally based on patch by NooN)

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