Index: trunk/src/org/openstreetmap/josm/actions/AddNodeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AddNodeAction.java	(revision 1130)
+++ trunk/src/org/openstreetmap/josm/actions/AddNodeAction.java	(revision 1130)
@@ -0,0 +1,87 @@
+// License: GPL. Copyright 2007 by Immanuel Scholz and others
+package org.openstreetmap.josm.actions;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import static org.openstreetmap.josm.tools.I18n.trn;
+
+import java.awt.BorderLayout;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.command.AddCommand;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.tools.AutoCompleteComboBox;
+import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ * This action displays a dialog where the user can enter a latitude and longitude, 
+ * and when ok is pressed, a new node is created at the specified position.
+ */
+public final class AddNodeAction extends JosmAction {
+
+    public AddNodeAction() {
+    	super(tr("Add Node"), "addnode", tr("Add a node by entering latitude and longitude."),
+			Shortcut.registerShortcut("addnode", tr("Edit: {0}", tr("Add Node")), KeyEvent.VK_D, Shortcut.GROUP_MENU), true);
+    }
+
+	public void actionPerformed(ActionEvent e) {   
+        JPanel p = new JPanel(new GridBagLayout());
+        p.add(new JLabel("<html>"+
+                tr("Enter the coordinates for the new node.") + 
+                "<br>" + tr("Use decimal degrees.") + 
+                "<br>" + tr("Negative values denote Western/Southern hemisphere.")), 
+                GBC.eol());
+        
+        p.add(new JLabel(tr("Latitude")), GBC.std().insets(0,10,5,0));
+        final JTextField lat = new JTextField(12);
+        p.add(lat, GBC.eol().insets(0,10,0,0));
+        p.add(new JLabel(tr("Longitude")), GBC.std().insets(0,0,5,10));
+        final JTextField lon = new JTextField(12);
+        p.add(lon, GBC.eol().insets(0,0,0,10));    
+        
+        Node nnew = null;
+
+        while(nnew == null) {
+            JOptionPane pane = new JOptionPane(p, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
+            pane.createDialog(Main.parent, tr("Add Node")).setVisible(true);
+            if (!Integer.valueOf(JOptionPane.OK_OPTION).equals(pane.getValue()))
+                return;
+            try {
+                LatLon ll = new LatLon(Double.parseDouble(lat.getText()), Double.parseDouble(lon.getText()));
+                if (!ll.isOutSideWorld()) nnew = new Node(ll);
+            } catch (Exception ex) { }
+        }
+        
+		/* Now execute the commands to add the dupicated contents of the paste buffer to the map */
+		
+		Main.main.undoRedo.add(new AddCommand(nnew));
+		Main.ds.setSelected(nnew);
+		Main.map.mapView.repaint();
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/MainMenu.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MainMenu.java	(revision 1122)
+++ trunk/src/org/openstreetmap/josm/gui/MainMenu.java	(revision 1130)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.AboutAction;
+import org.openstreetmap.josm.actions.AddNodeAction;
 import org.openstreetmap.josm.actions.AlignInCircleAction;
 import org.openstreetmap.josm.actions.AlignInLineAction;
@@ -64,197 +65,201 @@
 
 /**
- * This is the JOSM main menu bar. It is overwritten to initialize itself and provide
- * all menu entries as member variables (sort of collect them).
- *
+ * This is the JOSM main menu bar. It is overwritten to initialize itself and provide all menu
+ * entries as member variables (sort of collect them).
+ * 
  * It also provides possibilities to attach new menu entries (used by plugins).
- *
+ * 
  * @author Immanuel.Scholz
  */
 public class MainMenu extends JMenuBar {
 
-	/* File menu */
-	public final NewAction newAction = new NewAction();
-	public final OpenAction open = new OpenAction();
-	public final JosmAction save = new SaveAction(null);
-	public final JosmAction saveAs = new SaveAsAction(null);
-	public final JosmAction gpxExport = new GpxExportAction(null);
-	public final DownloadAction download = new DownloadAction();
-	public final JosmAction upload = new UploadAction();
-	public final JosmAction exit = new ExitAction();
-
-	/* Edit menu */
-	public final UndoAction undo = new UndoAction();
-	public final RedoAction redo = new RedoAction();
-	public final JosmAction copy = new CopyAction();
-	public final JosmAction paste = new PasteAction();
-	public final JosmAction delete = new DeleteAction();
-	public final JosmAction pasteTags = new PasteTagsAction(copy);
-	public final JosmAction duplicate = new DuplicateAction();
-	public final JosmAction selectAll = new SelectAllAction();
-	public final JosmAction unselectAll = new UnselectAllAction();
+    /* File menu */
+    public final NewAction newAction = new NewAction();
+    public final OpenAction open = new OpenAction();
+    public final JosmAction save = new SaveAction(null);
+    public final JosmAction saveAs = new SaveAsAction(null);
+    public final JosmAction gpxExport = new GpxExportAction(null);
+    public final DownloadAction download = new DownloadAction();
+    public final JosmAction upload = new UploadAction();
+    public final JosmAction exit = new ExitAction();
+
+    /* Edit menu */
+    public final UndoAction undo = new UndoAction();
+    public final RedoAction redo = new RedoAction();
+    public final AddNodeAction addnode = new AddNodeAction();
+    public final JosmAction copy = new CopyAction();
+    public final JosmAction paste = new PasteAction();
+    public final JosmAction delete = new DeleteAction();
+    public final JosmAction pasteTags = new PasteTagsAction(copy);
+    public final JosmAction duplicate = new DuplicateAction();
+    public final JosmAction selectAll = new SelectAllAction();
+    public final JosmAction unselectAll = new UnselectAllAction();
     /* crashes when loading data, if using JosmAction for search */
-	public final JosmAction search = new SearchAction();
-	public final JosmAction preferences = new PreferencesAction();
-
-	/* View menu */
-	public final JosmAction toggleGPXLines = new ToggleGPXLinesAction();
-
-	/* Tools menu */
-	public final JosmAction splitWay = new SplitWayAction();
-	public final JosmAction combineWay = new CombineWayAction();
-	public final JosmAction reverseWay = new ReverseWayAction();
-	public final JosmAction alignInCircle = new AlignInCircleAction();
-	public final JosmAction alignInLine = new AlignInLineAction();
+    public final JosmAction search = new SearchAction();
+    public final JosmAction preferences = new PreferencesAction();
+
+    /* View menu */
+    public final JosmAction toggleGPXLines = new ToggleGPXLinesAction();
+
+    /* Tools menu */
+    public final JosmAction splitWay = new SplitWayAction();
+    public final JosmAction combineWay = new CombineWayAction();
+    public final JosmAction reverseWay = new ReverseWayAction();
+    public final JosmAction alignInCircle = new AlignInCircleAction();
+    public final JosmAction alignInLine = new AlignInLineAction();
     public final JosmAction ortho = new OrthogonalizeAction();
-	public final JosmAction createCircle = new CreateCircleAction();
-	public final JosmAction mergeNodes = new MergeNodesAction();
-	public final JosmAction joinNodeWay = new JoinNodeWayAction();
-	public final JosmAction unglueNodes = new UnGlueAction();
-
-	/* Audio menu */
-	public final JosmAction audioPlayPause = new AudioPlayPauseAction();
-	public final JosmAction audioNext = new AudioNextAction();
-	public final JosmAction audioPrev = new AudioPrevAction();
-	public final JosmAction audioFwd = new AudioFwdAction();
-	public final JosmAction audioBack = new AudioBackAction();
-	public final JosmAction audioFaster = new AudioFasterAction();
-	public final JosmAction audioSlower = new AudioSlowerAction();
-
-	/* Help menu */
-	public final HelpAction help = new HelpAction();
-	public final JosmAction about = new AboutAction();
-	public final HistoryInfoAction historyinfo = new HistoryInfoAction();
-
-	public final JMenu fileMenu = new JMenu(tr("File"));
-	public final JMenu editMenu = new JMenu(tr("Edit"));
-	public final JMenu viewMenu = new JMenu(tr("View"));
-	public final JMenu toolsMenu = new JMenu(tr("Tools"));
-	public final JMenu audioMenu = new JMenu(tr("Audio"));
-	public final JMenu presetsMenu = new JMenu(tr("Presets"));
-	public final JMenu helpMenu = new JMenu(tr("Help"));
-
-	/**
-	 * Add a JosmAction to a menu.
-	 *
-	 * This method handles all the shortcut handling.
-	 * It also makes sure that actions that are handled by the
-	 * OS are not duplicated on the menu.
-	 */
-	public static void add(JMenu menu, JosmAction action) {
-		if (!action.getShortcut().getAutomatic()) {
-			JMenuItem menuitem = menu.add(action);
-			KeyStroke ks = action.getShortcut().getKeyStroke();
-			if (ks != null) {
-				menuitem.setAccelerator(ks);
-			}
-		}
-	}
-
-	/**
-	 * Add a menu to the main menu.
-	 *
-	 * This method handles all the shortcut handling.
-	 */
-	public void add(JMenu menu, int mnemonicKey, String shortName) {
-		Shortcut.registerShortcut("menu:"+shortName, tr("Menu: {0}", menu.getText()), mnemonicKey, Shortcut.GROUP_MNEMONIC).setMnemonic(menu);
-		add(menu);
-	}
-
-	public MainMenu() {
-		JMenuItem current;
-
-		add(fileMenu, newAction);
-		add(fileMenu, open);
-		fileMenu.addSeparator();
-		add(fileMenu, save);
-		add(fileMenu, saveAs);
-		add(fileMenu, gpxExport);
-		fileMenu.addSeparator();
-		add(fileMenu, download);
-		add(fileMenu, upload);
-		add(fileMenu, exit);
-		add(fileMenu, KeyEvent.VK_F, "file");
-
-		add(editMenu, undo);
-		add(editMenu, redo);
-		editMenu.addSeparator();
-		add(editMenu, copy);
-		add(editMenu, delete);
-		add(editMenu, paste);
-		add(editMenu, pasteTags);
-		add(editMenu, duplicate);
-		editMenu.addSeparator();
-		add(editMenu, selectAll);
-		add(editMenu, unselectAll);
-		editMenu.addSeparator();
-		add(editMenu, search);
-		editMenu.addSeparator();
-		add(editMenu, preferences);
-		add(editMenu, KeyEvent.VK_E, "edit");
-
-		for (String mode : AutoScaleAction.modes) {
-			JosmAction autoScaleAction = new AutoScaleAction(mode);
-			add(viewMenu, autoScaleAction);
-		}
-		viewMenu.addSeparator();
-		add(viewMenu, new ZoomOutAction());
-		add(viewMenu, new ZoomInAction());
-		viewMenu.addSeparator();
-		// TODO move code to an "action" like the others?
-		final JCheckBoxMenuItem wireframe = new JCheckBoxMenuItem(tr("Wireframe view"));
-		wireframe.setSelected(Main.pref.getBoolean("draw.wireframe", false));
-		wireframe.setAccelerator(Shortcut.registerShortcut("menu:view:wireframe", "Toggle Wireframe view", KeyEvent.VK_W, Shortcut.GROUP_MENU).getKeyStroke());
-		wireframe.addActionListener(new ActionListener() {
-			public void actionPerformed(ActionEvent ev) {
-				Main.pref.put("draw.wireframe", wireframe.isSelected());
-				if (Main.map != null) {
-					Main.map.mapView.repaint();
-				}
-			}
-		});
-		viewMenu.add(wireframe);
-		add(viewMenu, KeyEvent.VK_V, "view");
-
-		add(toolsMenu, splitWay);
-		add(toolsMenu, combineWay);
-		toolsMenu.addSeparator();
-		add(toolsMenu, reverseWay);
-		toolsMenu.addSeparator();
-		add(toolsMenu, alignInCircle);
-		add(toolsMenu, alignInLine);
-		add(toolsMenu, ortho);
-		toolsMenu.addSeparator();
-		add(toolsMenu, createCircle);
-		toolsMenu.addSeparator();
-		add(toolsMenu, mergeNodes);
-		add(toolsMenu, joinNodeWay);
-		add(toolsMenu, unglueNodes);
-		add(toolsMenu, KeyEvent.VK_T, "tools");
-
-		if (! Main.pref.getBoolean("audio.menuinvisible")) {
-			add(audioMenu, audioPlayPause);
-			add(audioMenu, audioNext);
-			add(audioMenu, audioPrev);
-			add(audioMenu, audioFwd);
-			add(audioMenu, audioBack);
-			add(audioMenu, audioSlower);
-			add(audioMenu, audioFaster);
-			add(audioMenu, KeyEvent.VK_A, "audio");
-		}
-
-		add(presetsMenu, KeyEvent.VK_P, "presets");
-
-		JMenuItem check = new JMenuItem("DEBUG: Check Dataset");
-		check.addActionListener(new ActionListener(){
-			public void actionPerformed(ActionEvent e) {
-				DataSetChecker.check();
-			}
-		});
-		helpMenu.add(check);
-		current = helpMenu.add(help); // why is help not a JosmAction?
-		current.setAccelerator(Shortcut.registerShortcut("system:help", tr("Help"), KeyEvent.VK_F1, Shortcut.GROUP_DIRECT).getKeyStroke());
-		add(helpMenu, about);
-		add(helpMenu, historyinfo);
-		add(helpMenu, KeyEvent.VK_H, "help");
+    public final JosmAction createCircle = new CreateCircleAction();
+    public final JosmAction mergeNodes = new MergeNodesAction();
+    public final JosmAction joinNodeWay = new JoinNodeWayAction();
+    public final JosmAction unglueNodes = new UnGlueAction();
+
+    /* Audio menu */
+    public final JosmAction audioPlayPause = new AudioPlayPauseAction();
+    public final JosmAction audioNext = new AudioNextAction();
+    public final JosmAction audioPrev = new AudioPrevAction();
+    public final JosmAction audioFwd = new AudioFwdAction();
+    public final JosmAction audioBack = new AudioBackAction();
+    public final JosmAction audioFaster = new AudioFasterAction();
+    public final JosmAction audioSlower = new AudioSlowerAction();
+
+    /* Help menu */
+    public final HelpAction help = new HelpAction();
+    public final JosmAction about = new AboutAction();
+    public final HistoryInfoAction historyinfo = new HistoryInfoAction();
+
+    public final JMenu fileMenu = new JMenu(tr("File"));
+    public final JMenu editMenu = new JMenu(tr("Edit"));
+    public final JMenu viewMenu = new JMenu(tr("View"));
+    public final JMenu toolsMenu = new JMenu(tr("Tools"));
+    public final JMenu audioMenu = new JMenu(tr("Audio"));
+    public final JMenu presetsMenu = new JMenu(tr("Presets"));
+    public final JMenu helpMenu = new JMenu(tr("Help"));
+
+    /**
+     * Add a JosmAction to a menu.
+     * 
+     * This method handles all the shortcut handling. It also makes sure that actions that are
+     * handled by the OS are not duplicated on the menu.
+     */
+    public static void add(JMenu menu, JosmAction action) {
+        if (!action.getShortcut().getAutomatic()) {
+            JMenuItem menuitem = menu.add(action);
+            KeyStroke ks = action.getShortcut().getKeyStroke();
+            if (ks != null) {
+                menuitem.setAccelerator(ks);
+            }
+        }
+    }
+
+    /**
+     * Add a menu to the main menu.
+     * 
+     * This method handles all the shortcut handling.
+     */
+    public void add(JMenu menu, int mnemonicKey, String shortName) {
+        Shortcut.registerShortcut("menu:" + shortName, tr("Menu: {0}", menu.getText()), mnemonicKey,
+                Shortcut.GROUP_MNEMONIC).setMnemonic(menu);
+        add(menu);
+    }
+
+    public MainMenu() {
+        JMenuItem current;
+
+        add(fileMenu, newAction);
+        add(fileMenu, open);
+        fileMenu.addSeparator();
+        add(fileMenu, save);
+        add(fileMenu, saveAs);
+        add(fileMenu, gpxExport);
+        fileMenu.addSeparator();
+        add(fileMenu, download);
+        add(fileMenu, upload);
+        add(fileMenu, exit);
+        add(fileMenu, KeyEvent.VK_F, "file");
+
+        add(editMenu, undo);
+        add(editMenu, redo);
+        editMenu.addSeparator();
+        add(editMenu, addnode);
+        add(editMenu, copy);
+        add(editMenu, delete);
+        add(editMenu, paste);
+        add(editMenu, pasteTags);
+        add(editMenu, duplicate);
+        editMenu.addSeparator();
+        add(editMenu, selectAll);
+        add(editMenu, unselectAll);
+        editMenu.addSeparator();
+        add(editMenu, search);
+        editMenu.addSeparator();
+        add(editMenu, preferences);
+        add(editMenu, KeyEvent.VK_E, "edit");
+
+        for (String mode : AutoScaleAction.modes) {
+            JosmAction autoScaleAction = new AutoScaleAction(mode);
+            add(viewMenu, autoScaleAction);
+        }
+        viewMenu.addSeparator();
+        add(viewMenu, new ZoomOutAction());
+        add(viewMenu, new ZoomInAction());
+        viewMenu.addSeparator();
+        // TODO move code to an "action" like the others?
+        final JCheckBoxMenuItem wireframe = new JCheckBoxMenuItem(tr("Wireframe view"));
+        wireframe.setSelected(Main.pref.getBoolean("draw.wireframe", false));
+        wireframe.setAccelerator(Shortcut.registerShortcut("menu:view:wireframe", "Toggle Wireframe view",
+                KeyEvent.VK_W, Shortcut.GROUP_MENU).getKeyStroke());
+        wireframe.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent ev) {
+                Main.pref.put("draw.wireframe", wireframe.isSelected());
+                if (Main.map != null) {
+                    Main.map.mapView.repaint();
+                }
+            }
+        });
+        viewMenu.add(wireframe);
+        add(viewMenu, KeyEvent.VK_V, "view");
+
+        add(toolsMenu, splitWay);
+        add(toolsMenu, combineWay);
+        toolsMenu.addSeparator();
+        add(toolsMenu, reverseWay);
+        toolsMenu.addSeparator();
+        add(toolsMenu, alignInCircle);
+        add(toolsMenu, alignInLine);
+        add(toolsMenu, ortho);
+        toolsMenu.addSeparator();
+        add(toolsMenu, createCircle);
+        toolsMenu.addSeparator();
+        add(toolsMenu, mergeNodes);
+        add(toolsMenu, joinNodeWay);
+        add(toolsMenu, unglueNodes);
+        add(toolsMenu, KeyEvent.VK_T, "tools");
+
+        if (!Main.pref.getBoolean("audio.menuinvisible")) {
+            add(audioMenu, audioPlayPause);
+            add(audioMenu, audioNext);
+            add(audioMenu, audioPrev);
+            add(audioMenu, audioFwd);
+            add(audioMenu, audioBack);
+            add(audioMenu, audioSlower);
+            add(audioMenu, audioFaster);
+            add(audioMenu, KeyEvent.VK_A, "audio");
+        }
+
+        add(presetsMenu, KeyEvent.VK_P, "presets");
+
+        JMenuItem check = new JMenuItem("DEBUG: Check Dataset");
+        check.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                DataSetChecker.check();
+            }
+        });
+        helpMenu.add(check);
+        current = helpMenu.add(help); // why is help not a JosmAction?
+        current.setAccelerator(Shortcut.registerShortcut("system:help", tr("Help"), KeyEvent.VK_F1,
+                Shortcut.GROUP_DIRECT).getKeyStroke());
+        add(helpMenu, about);
+        add(helpMenu, historyinfo);
+        add(helpMenu, KeyEvent.VK_H, "help");
     }
 }
