Package org.openstreetmap.josm.actions

Source Code of org.openstreetmap.josm.actions.ImageryAdjustAction

// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.actions;

import static org.openstreetmap.josm.tools.I18n.tr;

import java.awt.AWTEvent;
import java.awt.Cursor;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Formatter;
import java.util.Locale;

import javax.swing.JLabel;
import javax.swing.JPanel;

import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.actions.mapmode.MapMode;
import org.openstreetmap.josm.data.coor.EastNorth;
import org.openstreetmap.josm.data.imagery.OffsetBookmark;
import org.openstreetmap.josm.gui.ExtendedDialog;
import org.openstreetmap.josm.gui.layer.ImageryLayer;
import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
import org.openstreetmap.josm.gui.widgets.JosmTextField;
import org.openstreetmap.josm.tools.GBC;
import org.openstreetmap.josm.tools.ImageProvider;

public class ImageryAdjustAction extends MapMode implements MouseListener, MouseMotionListener, AWTEventListener{
    static ImageryOffsetDialog offsetDialog;
    static Cursor cursor = ImageProvider.getCursor("normal", "move");

    double oldDx, oldDy;
    boolean mouseDown;
    EastNorth prevEastNorth;
    private ImageryLayer layer;
    private MapMode oldMapMode;

    /**
     * Constructs a new {@code ImageryAdjustAction} for the given layer.
     * @param layer The imagery layer
     */
    public ImageryAdjustAction(ImageryLayer layer) {
        super(tr("New offset"), "adjustimg",
                tr("Adjust the position of this imagery layer"), Main.map,
                cursor);
        putValue("toolbar", false);
        this.layer = layer;
    }

    @Override
    public void enterMode() {
        super.enterMode();
        if (layer == null)
            return;
        if (!layer.isVisible()) {
            layer.setVisible(true);
        }
        oldDx = layer.getDx();
        oldDy = layer.getDy();
        addListeners();
        offsetDialog = new ImageryOffsetDialog();
        offsetDialog.setVisible(true);
    }

    protected void addListeners() {
        Main.map.mapView.addMouseListener(this);
        Main.map.mapView.addMouseMotionListener(this);
        try {
            Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
        } catch (SecurityException ex) {
            Main.error(ex);
        }
    }

    @Override
    public void exitMode() {
        super.exitMode();
        if (offsetDialog != null) {
            if (layer != null) {
                layer.setOffset(oldDx, oldDy);
            }
            offsetDialog.setVisible(false);
            offsetDialog = null;
        }
        removeListeners();
    }

    protected void removeListeners() {
        try {
            Toolkit.getDefaultToolkit().removeAWTEventListener(this);
        } catch (SecurityException ex) {
            Main.error(ex);
        }
        if (Main.isDisplayingMapView()) {
            Main.map.mapView.removeMouseMotionListener(this);
            Main.map.mapView.removeMouseListener(this);
        }
    }

    @Override
    public void eventDispatched(AWTEvent event) {
        if (!(event instanceof KeyEvent)) return;
        if (event.getID() != KeyEvent.KEY_PRESSED) return;
        if (layer == null) return;
        if (offsetDialog != null && offsetDialog.areFieldsInFocus()) return;
        KeyEvent kev = (KeyEvent)event;
        double dx = 0, dy = 0;
        switch (kev.getKeyCode()) {
        case KeyEvent.VK_UP : dy = +1; break;
        case KeyEvent.VK_DOWN : dy = -1; break;
        case KeyEvent.VK_LEFT : dx = -1; break;
        case KeyEvent.VK_RIGHT : dx = +1; break;
        }
        if (dx != 0 || dy != 0) {
            double ppd = layer.getPPD();
            layer.displace(dx / ppd, dy / ppd);
            if (offsetDialog != null) {
                offsetDialog.updateOffset();
            }
            kev.consume();
            Main.map.repaint();
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        if (e.getButton() != MouseEvent.BUTTON1)
            return;

        if (layer.isVisible()) {
            requestFocusInMapView();
            prevEastNorth=Main.map.mapView.getEastNorth(e.getX(),e.getY());
            Main.map.mapView.setNewCursor(Cursor.MOVE_CURSOR, this);
        }
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if (layer == null || prevEastNorth == null) return;
        EastNorth eastNorth =
            Main.map.mapView.getEastNorth(e.getX(),e.getY());
        double dx = layer.getDx()+eastNorth.east()-prevEastNorth.east();
        double dy = layer.getDy()+eastNorth.north()-prevEastNorth.north();
        layer.setOffset(dx, dy);
        if (offsetDialog != null) {
            offsetDialog.updateOffset();
        }
        Main.map.repaint();
        prevEastNorth = eastNorth;
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        Main.map.mapView.repaint();
        Main.map.mapView.resetCursor(this);
        prevEastNorth = null;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (offsetDialog != null || layer == null || Main.map == null)
            return;
        oldMapMode = Main.map.mapMode;
        super.actionPerformed(e);
    }

    class ImageryOffsetDialog extends ExtendedDialog implements FocusListener {
        public final JosmTextField tOffset = new JosmTextField();
        JosmTextField tBookmarkName = new JosmTextField();
        private boolean ignoreListener;
        public ImageryOffsetDialog() {
            super(Main.parent,
                    tr("Adjust imagery offset"),
                    new String[] { tr("OK"),tr("Cancel") },
                    false);
            setButtonIcons(new String[] { "ok", "cancel" });
            contentInsets = new Insets(10, 15, 5, 15);
            JPanel pnl = new JPanel(new GridBagLayout());
            pnl.add(new JMultilineLabel(tr("Use arrow keys or drag the imagery layer with mouse to adjust the imagery offset.\n" +
                    "You can also enter east and north offset in the {0} coordinates.\n" +
                    "If you want to save the offset as bookmark, enter the bookmark name below",Main.getProjection().toString())), GBC.eop());
            pnl.add(new JLabel(tr("Offset: ")),GBC.std());
            pnl.add(tOffset,GBC.eol().fill(GBC.HORIZONTAL).insets(0,0,0,5));
            pnl.add(new JLabel(tr("Bookmark name: ")),GBC.std());
            pnl.add(tBookmarkName,GBC.eol().fill(GBC.HORIZONTAL));
            tOffset.setColumns(16);
            updateOffsetIntl();
            tOffset.addFocusListener(this);
            setContent(pnl);
            setupDialog();
        }

        public boolean areFieldsInFocus() {
            return tOffset.hasFocus();
        }

        @Override
        public void focusGained(FocusEvent e) {
        }

        @Override
        public void focusLost(FocusEvent e) {
            if (ignoreListener) return;
            String ostr = tOffset.getText();
            int semicolon = ostr.indexOf(';');
            if( semicolon >= 0 && semicolon + 1 < ostr.length() ) {
                try {
                    // here we assume that Double.parseDouble() needs '.' as a decimal separator
                    String easting = ostr.substring(0, semicolon).trim().replace(',', '.');
                    String northing = ostr.substring(semicolon + 1).trim().replace(',', '.');
                    double dx = Double.parseDouble(easting);
                    double dy = Double.parseDouble(northing);
                    layer.setOffset(dx, dy);
                } catch (NumberFormatException nfe) {
                    // we repaint offset numbers in any case
                }
            }
            updateOffsetIntl();
            if (Main.isDisplayingMapView()) {
                Main.map.repaint();
            }
        }

        public final void updateOffset() {
            ignoreListener = true;
            updateOffsetIntl();
            ignoreListener = false;
        }

        public final void updateOffsetIntl() {
            // Support projections with very small numbers (e.g. 4326)
            int precision = Main.getProjection().getDefaultZoomInPPD() >= 1.0 ? 2 : 7;
            // US locale to force decimal separator to be '.'
            try (Formatter us = new Formatter(Locale.US)) {
                tOffset.setText(us.format(
                    "%1." + precision + "f; %1." + precision + "f",
                    layer.getDx(), layer.getDy()).toString());
            }
        }

        private boolean confirmOverwriteBookmark() {
            ExtendedDialog dialog = new ExtendedDialog(
                    Main.parent,
                    tr("Overwrite"),
                    new String[] {tr("Overwrite"), tr("Cancel")}
            ) {{
                contentInsets = new Insets(10, 15, 10, 15);
            }};
            dialog.setContent(tr("Offset bookmark already exists. Overwrite?"));
            dialog.setButtonIcons(new String[] {"ok.png", "cancel.png"});
            dialog.setupDialog();
            dialog.setVisible(true);
            return dialog.getValue() == 1;
        }

        @Override
        protected void buttonAction(int buttonIndex, ActionEvent evt) {
            if (buttonIndex == 0 && tBookmarkName.getText() != null && !tBookmarkName.getText().isEmpty() &&
                    OffsetBookmark.getBookmarkByName(layer, tBookmarkName.getText()) != null) {
                if (!confirmOverwriteBookmark()) return;
            }
            super.buttonAction(buttonIndex, evt);
        }

        @Override
        public void setVisible(boolean visible) {
            super.setVisible(visible);
            if (visible) return;
            offsetDialog = null;
            if (getValue() != 1) {
                layer.setOffset(oldDx, oldDy);
            } else if (tBookmarkName.getText() != null && !tBookmarkName.getText().isEmpty()) {
                OffsetBookmark.bookmarkOffset(tBookmarkName.getText(), layer);
            }
            Main.main.menu.imageryMenu.refreshOffsetMenu();
            if (Main.map == null) return;
            if (oldMapMode != null) {
                Main.map.selectMapMode(oldMapMode);
                oldMapMode = null;
            } else {
                Main.map.selectSelectTool(false);
            }
        }
    }

    @Override
    public void destroy() {
        super.destroy();
        removeListeners();
        this.layer = null;
        this.oldMapMode = null;
    }
}
TOP

Related Classes of org.openstreetmap.josm.actions.ImageryAdjustAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.