Changeset 4314 in josm


Ignore:
Timestamp:
13.08.2011 11:00:41 (10 months 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.