001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions; 003 004import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 005import static org.openstreetmap.josm.tools.I18n.tr; 006 007import java.awt.event.ActionEvent; 008import java.awt.event.KeyEvent; 009import java.util.Collections; 010 011import javax.swing.SwingUtilities; 012 013import org.openstreetmap.josm.command.AddCommand; 014import org.openstreetmap.josm.data.UndoRedoHandler; 015import org.openstreetmap.josm.data.coor.LatLon; 016import org.openstreetmap.josm.data.osm.DataSet; 017import org.openstreetmap.josm.data.osm.Node; 018import org.openstreetmap.josm.data.osm.OsmPrimitive; 019import org.openstreetmap.josm.gui.MainApplication; 020import org.openstreetmap.josm.gui.MapView; 021import org.openstreetmap.josm.gui.dialogs.LatLonDialog; 022import org.openstreetmap.josm.tools.Shortcut; 023 024/** 025 * This action displays a dialog where the user can enter a latitude and longitude, 026 * and when ok is pressed, a new node is created at the specified position. 027 */ 028public final class AddNodeAction extends JosmAction { 029 // remember input from last time 030 private String textLatLon, textEastNorth; 031 032 /** 033 * Constructs a new {@code AddNodeAction}. 034 */ 035 public AddNodeAction() { 036 super(tr("Add Node..."), "addnode", tr("Add a node by entering latitude / longitude or easting / northing."), 037 Shortcut.registerShortcut("addnode", tr("Edit: {0}", tr("Add Node...")), 038 KeyEvent.VK_D, Shortcut.SHIFT), true); 039 setHelpId(ht("/Action/AddNode")); 040 } 041 042 @Override 043 public void actionPerformed(ActionEvent e) { 044 if (!isEnabled()) 045 return; 046 047 // #17682 - Run the action later in EDT to make sure the KeyEvent triggering it is consumed before the dialog is shown 048 SwingUtilities.invokeLater(() -> { 049 LatLonDialog dialog = new LatLonDialog(MainApplication.getMainFrame(), tr("Add Node..."), ht("/Action/AddNode")); 050 051 if (textLatLon != null) { 052 dialog.setLatLonText(textLatLon); 053 } 054 if (textEastNorth != null) { 055 dialog.setEastNorthText(textEastNorth); 056 } 057 058 dialog.showDialog(); 059 060 if (dialog.getValue() != 1) 061 return; 062 063 LatLon coordinates = dialog.getCoordinates(); 064 if (coordinates == null) 065 return; 066 067 textLatLon = dialog.getLatLonText(); 068 textEastNorth = dialog.getEastNorthText(); 069 070 Node nnew = new Node(coordinates); 071 072 // add the node 073 DataSet ds = getLayerManager().getEditDataSet(); 074 UndoRedoHandler.getInstance().add(new AddCommand(ds, nnew)); 075 ds.setSelected(nnew); 076 MapView mapView = MainApplication.getMap().mapView; 077 if (mapView != null && !mapView.getRealBounds().contains(nnew.getCoor())) { 078 AutoScaleAction.zoomTo(Collections.<OsmPrimitive>singleton(nnew)); 079 } 080 }); 081 } 082 083 @Override 084 protected void updateEnabledState() { 085 setEnabled(getLayerManager().getEditLayer() != null); 086 } 087}