Changeset 4314 in josm


Ignore:
Timestamp:
2011-08-13T11:00:41+02:00 (13 years ago)
Author:
bastiK
Message:

add east/north input to 'add node' and 'move node' actions

Location:
trunk/src/org/openstreetmap/josm
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/AddNodeAction.java

    r4191 r4314  
    1010import org.openstreetmap.josm.Main;
    1111import org.openstreetmap.josm.command.AddCommand;
     12import org.openstreetmap.josm.data.coor.EastNorth;
    1213import org.openstreetmap.josm.data.coor.LatLon;
    1314import org.openstreetmap.josm.data.osm.Node;
     
    2122public final class AddNodeAction extends JosmAction {
    2223    // remember input from last time
    23     private String text;
     24    private String textLatLon, textEastNorth;
    2425
    2526    public AddNodeAction() {
    26         super(tr("Add Node..."), "addnode", tr("Add a node by entering latitude and longitude."),
     27        super(tr("Add Node..."), "addnode", tr("Add a node by entering latitude / longitude or easting / northing."),
    2728                Shortcut.registerShortcut("addnode", tr("Edit: {0}", tr("Add Node...")), KeyEvent.VK_D, Shortcut.GROUP_EDIT,
    2829                        Shortcut.SHIFT_DEFAULT), true);
     
    3637        LatLonDialog dialog = new LatLonDialog(Main.parent, tr("Add Node..."), ht("/Action/AddNode"));
    3738
    38         if (text != null) {
    39             dialog.setText(text);
     39        if (textLatLon != null) {
     40            dialog.setLatLonText(textLatLon);
     41        }
     42        if (textEastNorth != null) {
     43            dialog.setEastNorthText(textEastNorth);
    4044        }
    4145
    42         dialog.setVisible(true);
    43         if (dialog.isCanceled())
     46        dialog.showDialog();
     47       
     48        if (dialog.getValue() != 1)
    4449            return;
    4550
     
    4853            return;
    4954
    50         text = dialog.getText();
     55        textLatLon = dialog.getLatLonText();
     56        textEastNorth = dialog.getEastNorthText();
    5157
    5258        Node nnew = new Node(coordinates);
  • trunk/src/org/openstreetmap/josm/actions/MoveNodeAction.java

    r3720 r4314  
    3535        Node n = (Node) getCurrentDataSet().getSelectedNodes().toArray()[0];
    3636        dialog.setCoordinates(n.getCoor());
    37         dialog.setVisible(true);
    38         if (dialog.isCanceled())
     37        dialog.showDialog();
     38        if (dialog.getValue() != 1)
    3939            return;
    4040
  • trunk/src/org/openstreetmap/josm/gui/dialogs/LatLonDialog.java

    r4253 r4314  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    6 import java.awt.BorderLayout;
    76import java.awt.Color;
    87import java.awt.Component;
    9 import java.awt.FlowLayout;
    108import java.awt.GridBagLayout;
    119import java.awt.event.ActionEvent;
    1210import java.awt.event.FocusEvent;
    1311import java.awt.event.FocusListener;
    14 import java.awt.event.KeyEvent;
    1512import java.awt.event.WindowAdapter;
    1613import java.awt.event.WindowEvent;
     
    2522import javax.swing.AbstractAction;
    2623import javax.swing.BorderFactory;
    27 import javax.swing.JComponent;
    28 import javax.swing.JDialog;
    2924import javax.swing.JLabel;
    30 import javax.swing.JOptionPane;
    3125import javax.swing.JPanel;
    3226import javax.swing.JSeparator;
     27import javax.swing.JTabbedPane;
    3328import javax.swing.JTextField;
    34 import javax.swing.KeyStroke;
    3529import javax.swing.UIManager;
     30import javax.swing.event.ChangeEvent;
     31import javax.swing.event.ChangeListener;
    3632import javax.swing.event.DocumentEvent;
    3733import javax.swing.event.DocumentListener;
     
    3935import org.openstreetmap.josm.Main;
    4036import org.openstreetmap.josm.data.coor.CoordinateFormat;
     37import org.openstreetmap.josm.data.coor.EastNorth;
    4138import org.openstreetmap.josm.data.coor.LatLon;
    42 import org.openstreetmap.josm.gui.SideButton;
    43 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
    44 import org.openstreetmap.josm.gui.help.HelpUtil;
     39import org.openstreetmap.josm.gui.ExtendedDialog;
    4540import org.openstreetmap.josm.gui.widgets.HtmlPanel;
    4641import org.openstreetmap.josm.tools.GBC;
     
    4843import org.openstreetmap.josm.tools.WindowGeometry;
    4944
    50 public class LatLonDialog extends JDialog {
     45public class LatLonDialog extends ExtendedDialog {
    5146    private static final Color BG_COLOR_ERROR = new Color(255,224,224);
    5247
    53     private JTextField tfLatLon;
    54     private String help;
    55     private boolean canceled = false;
    56     private LatLon coordinates;
    57     private OKAction actOK;
    58     private CancelAction actCancel;
     48    public JTabbedPane tabs;
     49    private JTextField tfLatLon, tfEastNorth;
     50    private LatLon latLonCoordinates;
     51    private EastNorth eastNorthCoordinates;
    5952
    6053    private static final double ZERO = 0.0;
     
    7972            + "(.+)");
    8073
    81     protected JPanel buildInputForm() {
     74    protected JPanel buildLatLon() {
    8275        JPanel pnl = new JPanel(new GridBagLayout());
    8376        pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     
    131124    }
    132125
    133     protected JPanel buildButtonRow() {
    134         JPanel pnl = new JPanel(new FlowLayout());
    135 
    136         SideButton btn;
    137         pnl.add(btn = new SideButton(actOK = new OKAction()));
    138         makeButtonRespondToEnter(btn);
    139         pnl.add(btn = new SideButton(actCancel = new CancelAction()));
    140         makeButtonRespondToEnter(btn);
    141         pnl.add(new SideButton(new ContextSensitiveHelpAction(help)));
     126    private JPanel buildEastNorth() {
     127        JPanel pnl = new JPanel(new GridBagLayout());
     128        pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     129
     130        pnl.add(new JLabel(tr("Projected coordinates:")), GBC.std().insets(0,10,5,0));
     131        tfEastNorth = new JTextField(24);
     132
     133        pnl.add(tfEastNorth, GBC.eol().insets(0,10,0,0).fill(GBC.HORIZONTAL).weight(1.0, 0.0));
     134
     135        pnl.add(new JSeparator(), GBC.eol().fill(GBC.HORIZONTAL).insets(0,5,0,5));
     136
     137        pnl.add(new HtmlPanel(
     138                tr("Enter easting and northing (x and y) separated by space, comma or semicolon.")),
     139                GBC.eol().fill(GBC.HORIZONTAL));
     140
     141        pnl.add(GBC.glue(1, 1), GBC.eol().fill().weight(1.0, 1.0));
     142
     143        EastNorthInputVerifier inputVerifier = new EastNorthInputVerifier();
     144        tfEastNorth.getDocument().addDocumentListener(inputVerifier);
     145
     146        TextFieldFocusHandler focusHandler = new TextFieldFocusHandler();
     147        tfEastNorth.addFocusListener(focusHandler);
     148
    142149        return pnl;
    143150    }
    144151
    145     protected void makeButtonRespondToEnter(SideButton btn) {
    146         btn.setFocusable(true);
    147         btn.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), "enter");
    148         btn.getActionMap().put("enter", btn.getAction());
    149     }
    150 
    151152    protected void build() {
    152         getContentPane().setLayout(new BorderLayout());
    153         getContentPane().add(buildInputForm(), BorderLayout.CENTER);
    154         getContentPane().add(buildButtonRow(), BorderLayout.SOUTH);
    155         pack();
    156 
    157         // make dialog respond to ESCAPE
    158         //
    159         getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0), "escape");
    160         getRootPane().getActionMap().put("escape", actCancel);
    161 
    162         // make dialog respond to F1
    163         //
    164         HelpUtil.setHelpContext(getRootPane(), help);
     153        tabs = new JTabbedPane();
     154        tabs.addTab(tr("Lat/Lon"), buildLatLon());
     155        tabs.addTab(tr("East/North"), buildEastNorth());
     156        tabs.getModel().addChangeListener(new ChangeListener() {
     157            @Override
     158            public void stateChanged(ChangeEvent e) {
     159                switch (tabs.getModel().getSelectedIndex()) {
     160                    case 0: parseLatLonUserInput(); break;
     161                    case 1: parseEastNorthUserInput(); break;
     162                    default: throw new AssertionError();
     163                }
     164            }
     165        });
     166        setContent(tabs, false);
    165167    }
    166168
    167169    public LatLonDialog(Component parent, String title, String help) {
    168         super(JOptionPane.getFrameForComponent(parent), ModalityType.DOCUMENT_MODAL);
    169         this.help = help;
    170         setTitle(title);
     170        super(Main.parent, tr("Add Node..."), new String[] { tr("Ok"), tr("Cancel") });
     171        setButtonIcons(new String[] { "ok", "cancel" });
     172        configureContextsensitiveHelp("/Action/AddNode", true);
     173
    171174        build();
    172         addWindowListener(new WindowEventHandler());
    173175        setCoordinates(null);
    174176    }
    175177
    176     public void setCoordinates(LatLon coordinates) {
    177         if (coordinates == null) {
    178             coordinates = new LatLon(0,0);
    179         }
    180         this.coordinates = coordinates;
    181         tfLatLon.setText(coordinates.latToString(CoordinateFormat.getDefaultFormat()) + " " + coordinates.lonToString(CoordinateFormat.getDefaultFormat()));
    182         actOK.setEnabled(true);
     178    public boolean isLatLon() {
     179        return tabs.getModel().getSelectedIndex() == 0;
     180    }
     181
     182    public void setCoordinates(LatLon ll) {
     183        if (ll == null) {
     184            ll = new LatLon(0,0);
     185        }
     186        this.latLonCoordinates = ll;
     187        tfLatLon.setText(ll.latToString(CoordinateFormat.getDefaultFormat()) + " " + ll.lonToString(CoordinateFormat.getDefaultFormat()));
     188        EastNorth en = Main.getProjection().latlon2eastNorth(ll);
     189        tfEastNorth.setText(en.east()+" "+en.north());
     190        setOkEnabled(true);
    183191    }
    184192
    185193    public LatLon getCoordinates() {
    186         return coordinates;
     194        if (isLatLon()) {
     195            return latLonCoordinates;
     196        } else {
     197            if (eastNorthCoordinates == null) return null;
     198            return Main.getProjection().eastNorth2latlon(eastNorthCoordinates);
     199        }
     200    }
     201
     202    public LatLon getLatLonCoordinates() {
     203        return latLonCoordinates;
     204    }
     205
     206    public EastNorth getEastNorthCoordinates() {
     207        return eastNorthCoordinates;
    187208    }
    188209
     
    224245    }
    225246
    226     protected void parseUserInput() {
     247    protected void parseLatLonUserInput() {
    227248        LatLon latLon;
    228249        try {
    229             latLon = parse(tfLatLon.getText());
     250            latLon = parseLatLon(tfLatLon.getText());
    230251            if (!LatLon.isValidLat(latLon.lat()) || !LatLon.isValidLon(latLon.lon())) {
    231252                latLon = null;
     
    236257        if (latLon == null) {
    237258            setErrorFeedback(tfLatLon, tr("Please enter a GPS coordinates"));
    238             coordinates = null;
    239             actOK.setEnabled(false);
     259            latLonCoordinates = null;
     260            setOkEnabled(false);
    240261        } else {
    241262            clearErrorFeedback(tfLatLon,tr("Please enter a GPS coordinates"));
    242             coordinates = latLon;
    243             actOK.setEnabled(true);
    244         }
    245     }
    246 
    247     public boolean isCanceled() {
    248         return canceled;
    249     }
    250 
    251     protected void setCanceled(boolean canceled) {
    252         this.canceled = canceled;
     263            latLonCoordinates = latLon;
     264            setOkEnabled(true);
     265        }
     266    }
     267
     268    protected void parseEastNorthUserInput() {
     269        EastNorth en;
     270        try {
     271            en = parseEastNorth(tfEastNorth.getText());
     272        } catch (IllegalArgumentException e) {
     273            en = null;
     274        }
     275        if (en == null) {
     276            setErrorFeedback(tfEastNorth, tr("Please enter a Easting and Northing"));
     277            latLonCoordinates = null;
     278            setOkEnabled(false);
     279        } else {
     280            clearErrorFeedback(tfEastNorth,tr("Please enter a Easting and Northing"));
     281            eastNorthCoordinates = en;
     282            setOkEnabled(true);
     283        }
     284    }
     285
     286    private void setOkEnabled(boolean b) {
     287        if (buttons != null && buttons.size() > 0) {
     288            buttons.get(0).setEnabled(b);
     289        }
    253290    }
    254291
     
    256293    public void setVisible(boolean visible) {
    257294        if (visible) {
    258             setCanceled(false);
    259295            WindowGeometry.centerInWindow(Main.parent, getSize()).applySafe(this);
    260296        }
    261297        super.setVisible(visible);
    262     }
    263 
    264     class OKAction extends AbstractAction {
    265         public OKAction() {
    266             putValue(NAME, tr("OK"));
    267             putValue(SHORT_DESCRIPTION, tr("Close the dialog and create a new node"));
    268             putValue(SMALL_ICON, ImageProvider.get("ok"));
    269         }
    270 
    271         public void actionPerformed(ActionEvent e) {
    272             setCanceled(false);
    273             setVisible(false);
    274         }
    275     }
    276 
    277     class CancelAction extends AbstractAction {
    278         public CancelAction() {
    279             putValue(NAME, tr("Cancel"));
    280             putValue(SHORT_DESCRIPTION, tr("Close the dialog, do not create a new node"));
    281             putValue(SMALL_ICON, ImageProvider.get("cancel"));
    282         }
    283 
    284         public void actionPerformed(ActionEvent e) {
    285             setCanceled(true);
    286             setVisible(false);
    287         }
    288298    }
    289299
    290300    class LatLonInputVerifier implements DocumentListener {
    291301        public void changedUpdate(DocumentEvent e) {
    292             parseUserInput();
     302            parseLatLonUserInput();
    293303        }
    294304
    295305        public void insertUpdate(DocumentEvent e) {
    296             parseUserInput();
     306            parseLatLonUserInput();
    297307        }
    298308
    299309        public void removeUpdate(DocumentEvent e) {
    300             parseUserInput();
     310            parseLatLonUserInput();
     311        }
     312    }
     313
     314    class EastNorthInputVerifier implements DocumentListener {
     315        public void changedUpdate(DocumentEvent e) {
     316            parseEastNorthUserInput();
     317        }
     318
     319        public void insertUpdate(DocumentEvent e) {
     320            parseEastNorthUserInput();
     321        }
     322
     323        public void removeUpdate(DocumentEvent e) {
     324            parseEastNorthUserInput();
    301325        }
    302326    }
     
    313337    }
    314338
    315     class WindowEventHandler extends WindowAdapter {
    316         @Override
    317         public void windowClosing(WindowEvent e) {
    318             setCanceled(true);
    319             setVisible(false);
    320         }
    321 
    322         @Override
    323         public void windowOpened(WindowEvent e) {
    324             tfLatLon.requestFocusInWindow();
    325         }
    326     }
    327 
    328     private static LatLon parse(final String coord) {
     339    private static LatLon parseLatLon(final String coord) {
    329340        final Matcher m = p.matcher(coord);
    330341
     
    409420    }
    410421
     422    private static EastNorth parseEastNorth(String s) {
     423        String[] en = s.split("[;, ]+");
     424        if (en.length != 2) return null;
     425        try {
     426            double east = Double.parseDouble(en[0]);
     427            double north = Double.parseDouble(en[1]);
     428            return new EastNorth(east, north);
     429        } catch (NumberFormatException nfe) {
     430            return null;
     431        }
     432    }
     433
    411434    private static class LatLonHolder {
    412435        double lat, lon;
     
    444467    }
    445468
    446     public String getText() {
     469    public String getLatLonText() {
    447470        return tfLatLon.getText();
    448471    }
    449472
    450     public void setText(String text) {
     473    public void setLatLonText(String text) {
    451474        tfLatLon.setText(text);
    452475    }
     476
     477    public String getEastNorthText() {
     478        return tfEastNorth.getText();
     479    }
     480
     481    public void setEastNorthText(String text) {
     482        tfEastNorth.setText(text);
     483    }
     484
    453485}
Note: See TracChangeset for help on using the changeset viewer.