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

Revision 4845, 9.9 KB checked in by bastiK, 4 months ago (diff)

fixed #7240 - don`t know exatly

  • Property svn:eol-style set to native
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;
22import javax.swing.JTextField;
23
24import org.openstreetmap.josm.Main;
25import org.openstreetmap.josm.actions.mapmode.MapMode;
26import org.openstreetmap.josm.data.coor.EastNorth;
27import org.openstreetmap.josm.data.imagery.OffsetBookmark;
28import org.openstreetmap.josm.gui.ExtendedDialog;
29import org.openstreetmap.josm.gui.JMultilineLabel;
30import org.openstreetmap.josm.gui.layer.ImageryLayer;
31import org.openstreetmap.josm.tools.GBC;
32import org.openstreetmap.josm.tools.ImageProvider;
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        layer.enableOffsetServer(false);
148        super.actionPerformed(e);
149    }
150
151    class ImageryOffsetDialog extends ExtendedDialog implements FocusListener {
152        public final JTextField tOffset = new JTextField();
153        JTextField tBookmarkName = new JTextField();
154        private boolean ignoreListener;
155        public ImageryOffsetDialog() {
156            super(Main.parent,
157                    tr("Adjust imagery offset"),
158                    new String[] { tr("OK"),tr("Cancel") },
159                    false);
160            setButtonIcons(new String[] { "ok", "cancel" });
161            contentInsets = new Insets(10, 15, 5, 15);
162            JPanel pnl = new JPanel(new GridBagLayout());
163            pnl.add(new JMultilineLabel(tr("Use arrow keys or drag the imagery layer with mouse to adjust the imagery offset.\n" +
164                    "You can also enter east and north offset in the {0} coordinates.\n" +
165                    "If you want to save the offset as bookmark, enter the bookmark name below",Main.getProjection().toString())), GBC.eop());
166            pnl.add(new JLabel(tr("Offset: ")),GBC.std());
167            pnl.add(tOffset,GBC.eol().fill(GBC.HORIZONTAL).insets(0,0,0,5));
168            pnl.add(new JLabel(tr("Bookmark name: ")),GBC.std());
169            pnl.add(tBookmarkName,GBC.eol().fill(GBC.HORIZONTAL));
170            tOffset.setColumns(16);
171            updateOffsetIntl();
172            tOffset.addFocusListener(this);
173            setContent(pnl);
174            setupDialog();
175        }
176
177        public boolean areFieldsInFocus() {
178            return tOffset.hasFocus();
179        }
180
181        @Override
182        public void focusGained(FocusEvent e) {
183        }
184
185        @Override
186        public void focusLost(FocusEvent e) {
187            if (ignoreListener) return;
188            String ostr = tOffset.getText();
189            int semicolon = ostr.indexOf(';');
190            if( semicolon >= 0 && semicolon + 1 < ostr.length() ) {
191                try {
192                    // here we assume that Double.parseDouble() needs '.' as a decimal separator
193                    String easting = ostr.substring(0, semicolon).trim().replace(',', '.');
194                    String northing = ostr.substring(semicolon + 1).trim().replace(',', '.');
195                    double dx = Double.parseDouble(easting);
196                    double dy = Double.parseDouble(northing);
197                    layer.setOffset(dx, dy);
198                } catch (NumberFormatException nfe) {
199                    // we repaint offset numbers in any case
200                }
201            }
202            updateOffsetIntl();
203            if (Main.map != null) {
204                Main.map.repaint();
205            }
206        }
207
208        public void updateOffset() {
209            ignoreListener = true;
210            updateOffsetIntl();
211            ignoreListener = false;
212        }
213
214        public void updateOffsetIntl() {
215            // Support projections with very small numbers (e.g. 4326)
216            int precision = Main.getProjection().getDefaultZoomInPPD() >= 1.0 ? 2 : 7;
217            // US locale to force decimal separator to be '.'
218            tOffset.setText(new java.util.Formatter(java.util.Locale.US).format(
219                    "%1." + precision + "f; %1." + precision + "f",
220                    layer.getDx(), layer.getDy()).toString());
221        }
222
223        private boolean confirmOverwriteBookmark() {
224            ExtendedDialog dialog = new ExtendedDialog(
225                    Main.parent,
226                    tr("Overwrite"),
227                    new String[] {tr("Overwrite"), tr("Cancel")}
228            ) {{
229                contentInsets = new Insets(10, 15, 10, 15);
230            }};
231            dialog.setContent(tr("Offset bookmark already exists. Overwrite?"));
232            dialog.setButtonIcons(new String[] {"ok.png", "cancel.png"});
233            dialog.setupDialog();
234            dialog.setVisible(true);
235            return dialog.getValue() == 1;
236        }
237
238        @Override
239        protected void buttonAction(int buttonIndex, ActionEvent evt) {
240            if (buttonIndex == 0 && tBookmarkName.getText() != null && !"".equals(tBookmarkName.getText()) &&
241                    OffsetBookmark.getBookmarkByName(layer, tBookmarkName.getText()) != null) {
242                if (!confirmOverwriteBookmark()) return;
243            }
244            super.buttonAction(buttonIndex, evt);
245        }
246
247        @Override
248        public void setVisible(boolean visible) {
249            super.setVisible(visible);
250            if (visible) return;
251            offsetDialog = null;
252            if (getValue() != 1) {
253                layer.setOffset(oldDx, oldDy);
254            } else if (tBookmarkName.getText() != null && !"".equals(tBookmarkName.getText())) {
255                OffsetBookmark.bookmarkOffset(tBookmarkName.getText(), layer);
256            }
257            Main.main.menu.imageryMenu.refreshOffsetMenu();
258            if (Main.map == null) return;
259            if (oldMapMode != null) {
260                Main.map.selectMapMode(oldMapMode);
261                oldMapMode = null;
262            } else {
263                Main.map.selectSelectTool(false);
264            }
265        }
266    }
267}
Note: See TracBrowser for help on using the repository browser.