### Eclipse Workspace Patch 1.0
#P JOSM
Index: src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 4088)
+++ src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(working copy)
@@ -4,13 +4,17 @@
 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.awt.AWTEvent;
 import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Cursor;
 import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.event.AWTEventListener;
 import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
 import java.awt.geom.AffineTransform;
@@ -50,7 +54,7 @@
  */
 public class ExtrudeAction extends MapMode implements MapViewPaintable {
 
-    enum Mode { extrude, translate, select }
+    enum Mode { extrude, translate, select, create_new }
 
     private Mode mode = Mode.select;
 
@@ -97,7 +101,26 @@
      */
     private MoveCommand moveCommand;
 
+    /** The cursor for the 'create_new' mode. */
+    private final Cursor cursorCreateNew;
+
     /**
+     * This listener is used to indicate the 'create_new' mode, if the Alt modifier is pressed.
+     */
+    private final AWTEventListener altKeyListener = new AWTEventListener() {
+        @Override
+        public void eventDispatched(AWTEvent e) {
+            if(Main.map == null || Main.map.mapView == null || !Main.map.mapView.isActiveLayerDrawable())
+                return;
+            if(mode == Mode.select) {
+                InputEvent ie = (InputEvent) e;
+                boolean altDown = (ie.getModifiers() & ActionEvent.ALT_MASK) != 0;
+                Main.map.mapView.setNewCursor(altDown ? cursorCreateNew : cursor, this);
+            }
+        }
+    };
+
+    /**
      * Create a new SelectAction
      * @param mapFrame The MapFrame this action belongs to.
      */
@@ -109,6 +132,7 @@
         putValue("help", ht("/Action/Extrude"));
         initialMoveDelay = Main.pref.getInteger("edit.initial-move-delay",200);
         selectedColor = PaintColors.SELECTED.get();
+        cursorCreateNew = ImageProvider.getCursor("normal", "rectangle_plus");
     }
 
     @Override public String getModeHelpText() {
@@ -116,8 +140,10 @@
             return tr("Move a segment along its normal, then release the mouse button.");
         else if (mode == Mode.extrude)
             return tr("Draw a rectangle of the desired size, then release the mouse button.");
+        else if (mode == Mode.create_new)
+            return tr("Draw a rectangle of the desired size, then release the mouse button.");
         else
-            return tr("Drag a way segment to make a rectangle. Ctrl-drag to move a segment along its normal.");
+            return tr("Drag a way segment to make a rectangle. Ctrl-drag to move a segment along its normal, Alt-drag to create a new rectangle.");
     }
 
     @Override public boolean layerIsSupported(Layer l) {
@@ -128,18 +154,26 @@
         super.enterMode();
         Main.map.mapView.addMouseListener(this);
         Main.map.mapView.addMouseMotionListener(this);
+        try {
+            Toolkit.getDefaultToolkit().addAWTEventListener(altKeyListener, AWTEvent.KEY_EVENT_MASK);
+        }
+        catch (SecurityException ex) { /* ignore, don't indicate the create_new mode */ }
     }
 
     @Override public void exitMode() {
         Main.map.mapView.removeMouseListener(this);
         Main.map.mapView.removeMouseMotionListener(this);
         Main.map.mapView.removeTemporaryLayer(this);
+        try {
+            Toolkit.getDefaultToolkit().removeAWTEventListener(altKeyListener);
+        }
+        catch (SecurityException ex) { /* ignore, don't indicate the create_new mode */ }
         super.exitMode();
     }
 
     /**
      * If the left mouse button is pressed over a segment, switch
-     * to either extrude or translate mode depending on whether Ctrl is held.
+     * to either extrude, translate or create_new mode depending on whether Ctrl or Alt is held.
      */
     @Override public void mousePressed(MouseEvent e) {
         if(!Main.map.mapView.isActiveLayerVisible())
@@ -158,6 +192,11 @@
 
             if ((e.getModifiers() & ActionEvent.CTRL_MASK) != 0) {
                 mode = Mode.translate;
+            } else if ((e.getModifiers() & ActionEvent.ALT_MASK) != 0) {
+                mode = Mode.create_new;
+                // create a new segment and then select and extrude the new segment
+                getCurrentDataSet().setSelected(selectedSegment.way);
+                alwaysCreateNodes = true;
             } else {
                 mode = Mode.extrude;
                 getCurrentDataSet().setSelected(selectedSegment.way);
@@ -224,7 +263,7 @@
         if (mode == Mode.select) {
             // Just sit tight and wait for mouse to be released.
         } else {
-            //move and extrude mode - move the selected segment
+            //move, create new and extrude mode - move the selected segment
 
             EastNorth initialMouseEn = Main.map.mapView.getEastNorth(initialMousePos.x, initialMousePos.y);
             EastNorth mouseEn = Main.map.mapView.getEastNorth(e.getPoint().x, e.getPoint().y);
@@ -260,7 +299,7 @@
 
             Main.map.mapView.setNewCursor(Cursor.MOVE_CURSOR, this);
 
-            if (mode == Mode.extrude) {
+            if (mode == Mode.extrude || mode == Mode.create_new) {
                 //nothing here
             } else if (mode == Mode.translate) {
                 //move nodes to new position
@@ -292,8 +331,28 @@
         if (mode == Mode.select) {
             // Nothing to be done
         } else {
-            if (mode == Mode.extrude) {
+            if (mode == Mode.create_new) {
                 if (e.getPoint().distance(initialMousePos) > 10 && newN1en != null) {
+                    Collection<Command> cmds = new LinkedList<Command>();
+                    Node third = new Node(newN2en);
+                    Node fourth = new Node(newN1en);
+                    Way wnew = new Way();
+                    wnew.addNode(selectedSegment.getFirstNode());
+                    wnew.addNode(selectedSegment.getSecondNode());
+                    wnew.addNode(third);
+                    wnew.addNode(fourth);
+                    // ... and close the way
+                    wnew.addNode(selectedSegment.getFirstNode());
+                    // undo support
+                    cmds.add(new AddCommand(third));
+                    cmds.add(new AddCommand(fourth));
+                    cmds.add(new AddCommand(wnew));
+                    Command c = new SequenceCommand(tr("Extrude Way"), cmds);
+                    Main.main.undoRedo.add(c);
+                    getCurrentDataSet().setSelected(wnew);
+                }
+            } else if (mode == Mode.extrude) {
+                if (e.getPoint().distance(initialMousePos) > 10 && newN1en != null) {
                     // create extrusion
 
                     Collection<Command> cmds = new LinkedList<Command>();
@@ -438,7 +497,7 @@
                 Point p3 = mv.getPoint(newN1en);
                 Point p4 = mv.getPoint(newN2en);
 
-                if (mode == Mode.extrude) {
+                if (mode == Mode.extrude || mode == Mode.create_new) {
                     // Draw rectangle around new area.
                     GeneralPath b = new GeneralPath();
                     b.moveTo(p1.x, p1.y); b.lineTo(p3.x, p3.y);
