Index: src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 4776)
+++ src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(working copy)
@@ -1,9 +1,11 @@
 // License: GPL. See LICENSE file for details.
 package org.openstreetmap.josm.actions.mapmode;
 
+import javax.swing.JCheckBoxMenuItem;
 import static org.openstreetmap.josm.tools.I18n.tr;
 import static org.openstreetmap.josm.tools.I18n.trn;
 import static org.openstreetmap.josm.tools.I18n.marktr;
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 
 import java.awt.AWTEvent;
 import java.awt.BasicStroke;
@@ -36,6 +38,7 @@
 
 import javax.swing.SwingUtilities;
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.command.AddCommand;
 import org.openstreetmap.josm.command.ChangeCommand;
 import org.openstreetmap.josm.command.Command;
@@ -50,6 +53,7 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.WaySegment;
 import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors;
+import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.layer.Layer;
@@ -89,7 +93,8 @@
     private Shortcut extraShortcut;
     private Shortcut backspaceShortcut;
     
-    boolean snapOn;
+    private JCheckBoxMenuItem snapCheckboxMenuItem;
+    
             
     public DrawAction(MapFrame mapFrame) {
         super(tr("Draw"), "node/autonode", tr("Draw nodes"),
@@ -99,7 +104,9 @@
         // Add extra shortcut N
         extraShortcut = Shortcut.registerShortcut("mapmode:drawfocus", tr("Mode: Draw Focus"), KeyEvent.VK_N, Shortcut.GROUP_EDIT);
         Main.registerActionShortcut(this, extraShortcut);
-
+        
+        snapCheckboxMenuItem = MainMenu.addWithCheckbox(Main.main.menu.editMenu, new SnapChangeAction(),  MainMenu.WINDOW_MENU_GROUP.VOLATILE);
+        snapHelper.setMenuCheckBox(snapCheckboxMenuItem);
         cursorJoinNode = ImageProvider.getCursor("crosshair", "joinnode");
         cursorJoinWay = ImageProvider.getCursor("crosshair", "joinway");
     }
@@ -134,6 +141,7 @@
         drawTargetHighlight = Main.pref.getBoolean("draw.target-highlight", true);
         wayIsFinished = false;
         snapHelper.init();
+        snapCheckboxMenuItem.getAction().setEnabled(true);
         
         backspaceShortcut = Shortcut.registerShortcut("mapmode:backspace", tr("Backspace in Add mode"), KeyEvent.VK_BACK_SPACE, Shortcut.GROUP_EDIT);
         Main.registerActionShortcut(new BackSpaceAction(), backspaceShortcut);
@@ -159,7 +167,8 @@
         DataSet.removeSelectionListener(this);
         Main.unregisterActionShortcut(backspaceShortcut);
         snapHelper.unsetFixedMode();
-
+        snapCheckboxMenuItem.getAction().setEnabled(false);
+        
         removeHighlighting();
         try {
             Toolkit.getDefaultToolkit().removeAWTEventListener(this);
@@ -264,7 +273,7 @@
         // request focus in order to enable the expected keyboard shortcuts
         //
         Main.map.mapView.requestFocus();
-
+        
         if(e.getClickCount() > 1 && mousePos != null && mousePos.equals(oldMousePos)) {
             // A double click equals "user clicked last node again, finish way"
             // Change draw tool only if mouse position is nearly the same, as
@@ -324,7 +333,7 @@
                 }
             } else { // n==null, no node found in clicked area
                 EastNorth mouseEN = Main.map.mapView.getEastNorth(e.getX(), e.getY());
-                newEN = snapOn ? snapHelper.getSnapPoint(mouseEN) : mouseEN;
+                newEN = snapHelper.isSnapOn() ? snapHelper.getSnapPoint(mouseEN) : mouseEN;
                 n = new Node(newEN); //create node at clicked point
                 newNode = true;
             }
@@ -698,7 +707,7 @@
             angle += angle < 0 ? 360 : 0;
         }
         
-        if (snapOn) snapHelper.checkAngleSnapping(currentMouseEastNorth,angle);
+        snapHelper.checkAngleSnapping(currentMouseEastNorth,angle);
         
         Main.map.statusLine.setAngle(angle);
         Main.map.statusLine.setHeading(hdg);
@@ -948,12 +957,14 @@
         if (!Main.map.mapView.getBounds().contains(mousePos)) return;
         
         Graphics2D g2 = g;
-        if (snapOn) snapHelper.draw(g2,mv);
+        snapHelper.drawIfNeeded(g2,mv);
         if (!drawHelperLine || wayIsFinished || shift) return;
         
         if (!snapHelper.isActive()) { // else use color and stoke from  snapHelper.draw
             g2.setColor(selectedColor);
             g2.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+        } else {
+            if (!snapHelper.drawConstructionGeometry) return;
         }
         GeneralPath b = new GeneralPath();
         Point p1=mv.getPoint(currentBaseNode);
@@ -1018,7 +1029,7 @@
             } else {
                 rv += " " + tr("Continue way from last node.");
             }
-            if (snapOn) {
+            if (snapHelper.isSnapOn()) {
                 rv += " "+ tr("Angle snapping ON.");
             }
         }
@@ -1092,9 +1103,16 @@
  }
 
     private class SnapHelper {
+        boolean snapOn; // snapping is turned on
+        
         private boolean active; // snapping is activa for current mouse position
         private boolean fixed; // snap angle is fixed
         private boolean absoluteFix; // snap angle is absolute
+        
+        private boolean drawConstructionGeometry; 
+        private boolean showProjectedPoint; 
+        private boolean showAngle; 
+        
         EastNorth dir2;
         EastNorth projected;
         String labelText;
@@ -1110,11 +1128,14 @@
         Color snapHelperColor;
         private Stroke normalStroke;
         private Stroke helperStroke;
-
+        
+        JCheckBoxMenuItem checkBox;
+        
         private  void init() {
             snapOn=false;
+            checkBox.setState(snapOn);
             fixed=false; absoluteFix=false;
-            
+                        
             Collection<String> angles = Main.pref.getCollection("draw.anglesnap.angles", 
                     Arrays.asList("0","30","45","60","90","120","135","150","210","225","240","270","300","315","330"));
             
@@ -1130,6 +1151,9 @@
                 i++;
             }
             snapAngleTolerance = Main.pref.getDouble("draw.anglesnap.tolerance", 5.0);
+            drawConstructionGeometry = Main.pref.getBoolean("draw.anglesnap.drawConstructionGeometry", true);
+            showProjectedPoint = Main.pref.getBoolean("draw.anglesnap.drawProjectedPoint", true);
+            showAngle = Main.pref.getBoolean("draw.anglesnap.showAngle", true);
 
             normalStroke = new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
             snapHelperColor = Main.pref.getColor(marktr("draw angle snap"), Color.ORANGE);
@@ -1146,26 +1170,28 @@
             labelText=null;
         }
 
-        private void draw(Graphics2D g2, MapView mv) {
+        private void drawIfNeeded(Graphics2D g2, MapView mv) {
+            if (!snapOn) return;
             if (!active) return;
             Point p1=mv.getPoint(currentBaseNode);
             Point p2=mv.getPoint(dir2);
             Point p3=mv.getPoint(projected);
             GeneralPath b;
-            
-            g2.setColor(snapHelperColor);
-            g2.setStroke(helperStroke);
-            
-            b = new GeneralPath();
-            if (absoluteFix) {
-                b.moveTo(p2.x,p2.y); 
-                b.lineTo(2*p1.x-p2.x,2*p1.y-p2.y); // bi-directional line
-            } else {
-                b.moveTo(p2.x,p2.y);
-                b.lineTo(p3.x,p3.y);
-            } 
-            g2.draw(b);
+            if (drawConstructionGeometry) {
+                g2.setColor(snapHelperColor);
+                g2.setStroke(helperStroke);
 
+                b = new GeneralPath();
+                if (absoluteFix) {
+                    b.moveTo(p2.x,p2.y); 
+                    b.lineTo(2*p1.x-p2.x,2*p1.y-p2.y); // bi-directional line
+                } else {
+                    b.moveTo(p2.x,p2.y);
+                    b.lineTo(p3.x,p3.y);
+                } 
+                g2.draw(b);
+            }
+
             g2.setColor(selectedColor);
             g2.setStroke(normalStroke);
             b = new GeneralPath();
@@ -1174,8 +1200,10 @@
             g2.draw(b);
             
             g2.drawString(labelText, p3.x-5, p3.y+20);
-            g2.setStroke(normalStroke);
-            g2.drawOval(p3.x-5, p3.y-5, 10, 10); // projected point
+            if (showProjectedPoint) {
+                g2.setStroke(normalStroke);
+                g2.drawOval(p3.x-5, p3.y-5, 10, 10); // projected point
+            }
             
             g2.setColor(snapHelperColor);
             g2.setStroke(helperStroke);
@@ -1190,6 +1218,7 @@
         /* If mouse position is close to line at 15-30-45-... angle, remembers this direction
          */
         private void checkAngleSnapping(EastNorth currentEN, double angle) {
+            if (!snapOn) return;
             if (!absoluteFix && previousNode==null) return;
             
             double nearestAngle;
@@ -1207,12 +1236,19 @@
 
                 EastNorth p0 = currentBaseNode.getEastNorth();
                 e0=p0.east(); n0=p0.north();
-
-                if (fixed) {
-                    if (absoluteFix) labelText = "=";
-                                else labelText = String.format(fixFmt, (int) nearestAngle);
-                } else labelText = String.format("%d", (int) nearestAngle);
                 
+                if (showAngle)  {
+                    if (fixed) {
+                        if (absoluteFix) labelText = "=";
+                                    else labelText = String.format(fixFmt, (int) nearestAngle);
+                    } else labelText = String.format("%d", (int) nearestAngle);
+                } else {
+                    if (fixed) {
+                        if (absoluteFix) labelText = "=";
+                        else labelText = String.format(tr("FIX"),0);
+                    } else labelText="";
+                } 
+                
                 if (absoluteFix) {
                     de=0; dn=1; 
                 } else {
@@ -1260,8 +1296,15 @@
                 snapOn=true;
                 unsetFixedMode();
             }
+            checkBox.setState(snapOn);
         }
-
+        
+        private void toggleSnapping() {
+            snapOn = !snapOn;
+            checkBox.setState(snapOn);
+            unsetFixedMode();
+        }
+                
         private boolean isActive() {
             return active;
         }
@@ -1289,5 +1332,28 @@
             absoluteFix=true;
             lastAngle=hdg;
         }
+
+        private void setMenuCheckBox(JCheckBoxMenuItem checkBox) {
+            this.checkBox = checkBox;
+        }
+
+        private boolean isSnapOn() {
+            return snapOn;
+        }
     }
+    
+    private class SnapChangeAction extends JosmAction {
+        public SnapChangeAction() {
+             super(tr("Angle snapping"), "anglesnap", 
+ 		   tr("Switches angle snapping mode while drawing"), 
+ 		   Shortcut.registerShortcut("draw:anglesnap", tr("Draw: {0}",tr("Angle snapping")), 
+ 		   KeyEvent.VK_H, Shortcut.GROUP_EDIT), false);
+             putValue("help", ht("/Action/Draw/AngleSnap"));
+        }
+        @Override 
+        public void actionPerformed(ActionEvent e) {
+               if (snapHelper!=null) snapHelper.toggleSnapping(); 
+        }
+        
+    }
 }
