Index: src/org/jmol/viewer/MouseManager.java
===================================================================
--- src/org/jmol/viewer/MouseManager.java	(revision 9249)
+++ src/org/jmol/viewer/MouseManager.java	(working copy)
@@ -23,9 +23,11 @@
  */
 package org.jmol.viewer;
 
-
+import org.openscience.jmol.app.ImageSelection;
 import java.awt.Rectangle;
 import java.awt.Event;
+import java.awt.Toolkit;
+import javax.vecmath.Point3f;
 
 import org.jmol.modelset.Measurement;
 import org.jmol.util.Logger;
@@ -46,6 +48,7 @@
   boolean drawMode = false;
   boolean measuresEnabled = true;
   boolean hoverActive = false;
+  int selectedAtomIndex = -1;
 
   boolean rubberbandSelectionMode = false;
   int xAnchor, yAnchor;
@@ -93,8 +96,129 @@
     }
   }
 
+  /* ------------------- */
+  /*
+  public void keyPressed(KeyEvent e) { }
+  public void keyReleased(KeyEvent e) { }
+  */
+
+  private int display_mode=0;
+  private String[] display_commands=
+    {"spacefill off;wireframe on",
+     "spacefill off;wireframe 0.25",
+     "wireframe 0.18;spacefill 25%",
+     "spacefill 75%;wireframe off"};
+  private String[] edit_atoms=
+    {"C", "H", "O", "N", "S", "X"};
+  private int edit_atom=0;
+  private boolean vector_mode=false;
+  private boolean vibration_mode=false;
+  private boolean spin_mode=false;
+  private boolean movie_mode=false;
+  private String  bgcolor="black";
+
+  public void keyTyped(KeyEvent e)
+  {
+    //char keyChar = (char) keycode;
+    char keyChar = e.getKeyChar();
+    if (keyChar == 'h' || keyChar == 'H') {
+       System.err.println("oops");
+       return;
+    }
+    if (keyChar == KeyEvent.CHAR_UNDEFINED)
+       return;
+    switch(keyChar) {
+    case 'c':
+    case 'C':
+       edit_atom++;
+       edit_atom %=6;
+       //viewer.setStatusUserAction("Atom "+edit_atoms[edit_atom]+" is selected.");
+       break;
+    case 'a':
+    case 'A':
+       viewer.script("select *; set measure angstroms");
+       viewer.repaintView();
+       break;
+    case 'm':
+    case 'M':
+       if (vector_mode) {
+         if (vibration_mode) {
+           vibration_mode=false;
+           viewer.script("vibration off");
+         } else {
+           vibration_mode=true;
+           viewer.script("vibration on");
+         }
+         viewer.repaintView();
+         break;
+       }
+       if (movie_mode) {
+           movie_mode=false;
+           viewer.script("anim off");
+       } else {
+           movie_mode=true;
+           viewer.script("anim mode palindrome 2 2;anim on");
+       }
+       viewer.repaintView();
+       break;
+    case 'd':
+    case 'D':
+       display_mode++;
+       display_mode %=4;
+       viewer.script(display_commands[display_mode]);
+       viewer.script("set defaultLoadScript \"" + display_commands[display_mode] + "\"");
+       viewer.repaintView();
+       break;
+    case '.':
+    case '>':
+       viewer.script("frame next");
+       break;
+    case ',':
+    case '<':
+       viewer.script("frame prev");
+       break;
+    case 'r':
+    case 'R':
+       if (spin_mode) {
+           spin_mode=false;
+           viewer.script("spin off");
+       } else {
+           spin_mode=true;
+           viewer.script("spin on");
+       }
+       viewer.repaintView();
+       break;
+    case 'v':
+    case 'V':
+       if (vector_mode) {
+           vector_mode=false;
+           viewer.script("vectors off");
+       } else {
+           vector_mode=true;
+           viewer.script("vectors on");
+       }
+       viewer.repaintView();
+       break;
+
+    case 'y':
+    case 'Y':
+       ImageSelection imgSel = new ImageSelection(viewer.getScreenImage());
+       Toolkit.getDefaultToolkit().getSystemClipboard().setContents(imgSel, null);
+       break;
+    case 'b':
+    case 'B':
+       if (bgcolor == "black") bgcolor="white";
+       else bgcolor="black";
+       viewer.setStringProperty("backgroundColor", bgcolor);
+       viewer.repaint();
+       break;
+    }
+  }
+
+/*
   public void keyTyped(KeyEvent ke) {
   }
+ */
 
   public void keyPressed(KeyEvent ke) {
     if (!viewer.getNavigationMode())
@@ -224,10 +348,13 @@
        * need to support multiple selections, but we will
        * cross that bridge when we come to it
        ****************************************************************/
-    case CTRL_LEFT: // on MacOSX this brings up popup
-    case RIGHT: // with multi-button mice, this will too
+    case RIGHT: // with multi-button mice
       viewer.popupMenu(x, y);
-      return;
+      break;
+    case CTRL_LEFT: // Add a atom or on MacOSX this brings up popup
+    case ALT_LEFT:
+      selectedAtomIndex = viewer.findNearestAtomIndex(x, y);
+      break;
     }
   }
 
@@ -255,6 +382,63 @@
     if (logMouseEvents && Logger.debugging)
       Logger.debug("mouseReleased("+x+","+y+","+modifiers+")");
     viewer.setInMotion(false);
+
+    if (previousPressedX == previousDragX && previousPressedY == previousDragY) {
+      switch (previousPressedModifiers & BUTTON_MODIFIER_MASK) {
+      case CTRL_LEFT:
+        viewer.popupMenu(x, y);
+        break;
+      }
+    } else {
+      switch (previousPressedModifiers & BUTTON_MODIFIER_MASK) {
+      case CTRL_LEFT:
+        int atomIndex = viewer.findNearestAtomIndex(x, y);
+        if (atomIndex == selectedAtomIndex) {
+          viewer.popupMenu(x, y);
+          break;
+        }
+        if (selectedAtomIndex >= 0) {
+          String defaultScript = viewer.getDefaultLoadScript();
+          if (atomIndex < 0) { // add a Carbon atom XXX
+            Point3f p,p1, scrn;
+            scrn = new Point3f();
+            p1 = new Point3f();
+            p = viewer.getAtomPoint3f(selectedAtomIndex);
+            viewer.transformPoint(p, scrn);
+            scrn.x = x;
+            scrn.y = y;
+            viewer.unTransformPoint(scrn, p1);
+
+            atomIndex = viewer.getAtomCount();
+
+            String myatom="1\n\n" + edit_atoms[edit_atom] + " "+p1.x+" "+p1.y+" "+p1.z+"\n";
+            //System.out.println(myatom+ ":" + selectedAtomIndex + "," + atomIndex);
+            viewer.script("set appendnew false");
+            viewer.loadInline(myatom,true);
+            viewer.script("connect (atomindex="+ selectedAtomIndex+
+              ") (atomindex=" + atomIndex+")");
+            System.out.println("connect (atomindex="+ selectedAtomIndex+
+              ") (atomindex=" + atomIndex+")");
+            //viewer.script("set bondRadiusMilliAngstroms 150");
+	    if (defaultScript.length() > 0) viewer.script(defaultScript); // XXX
+          } else { // connect a bond
+            // how can I toggle between single,double,triple ?
+            viewer.script("set appendnew false");
+            viewer.script("connect (atomindex="+ selectedAtomIndex+
+              ") (atomindex=" + atomIndex+")");
+            //viewer.script("set bondRadiusMilliAngstroms 150");
+	    if (defaultScript.length() > 0) viewer.script(defaultScript);
+          }
+        } else {
+          // add a new atom too ? XXX
+        }
+        break;
+      default:
+        break;
+      }
+    }
+
+    selectedAtomIndex=-1;
     viewer.setCursor(Viewer.CURSOR_DEFAULT);
   }
 
@@ -317,6 +501,13 @@
     int nearestAtomIndex = (drawMode ? -1 : viewer.findNearestAtomIndex(x, y));
     if (nearestAtomIndex >= 0 && !viewer.isInSelectionSubset(nearestAtomIndex))
         nearestAtomIndex = -1;
+
+    switch (modifiers & BUTTON_MODIFIER_MASK) {
+    case ALT_LEFT:
+      selectedAtomIndex=nearestAtomIndex;
+      System.out.println("mouseClicked:Alt"+selectedAtomIndex);
+      break;
+    }
     if (clickCount == 1)
       mouseSingleClick(x, y, modifiers, nearestAtomIndex);
     else if (clickCount == 2)
@@ -390,10 +581,31 @@
     if (!viewer.getInMotion())
       viewer.setCursor(Viewer.CURSOR_MOVE);
     viewer.setInMotion(true);
-    if (pressedCount == 1)
-      mouseSinglePressDrag(deltaX, deltaY, modifiers);
-    else if (pressedCount == 2)
-      mouseDoublePressDrag(deltaX, deltaY, modifiers);
+    switch (modifiers & BUTTON_MODIFIER_MASK) {
+    case CTRL_LEFT:
+      break;
+    case ALT_LEFT:
+      if (selectedAtomIndex >= 0) {
+        Point3f p, scrn;
+        scrn = new Point3f();
+        p = viewer.getAtomPoint3f(selectedAtomIndex);
+        viewer.transformPoint(p, scrn);
+        scrn.x += deltaX;
+        scrn.y += deltaY;
+
+        viewer.unTransformPoint(scrn, p);
+        viewer.setAtomCoord(selectedAtomIndex, p.x, p.y, p.z);
+        viewer.repaint();
+        break;
+      }
+
+    default:
+      if (pressedCount == 1)
+        mouseSinglePressDrag(deltaX, deltaY, modifiers);
+      else if (pressedCount == 2)
+        mouseDoublePressDrag(deltaX, deltaY, modifiers);
+      break;
+    }
   }
 
   void mouseSinglePressDrag(int deltaX, int deltaY, int modifiers) {
@@ -419,8 +631,10 @@
       if (Math.abs(deltaY) > 5 * Math.abs(deltaX))
         viewer.zoomBy(deltaY);
       //      if (deltaX < 0 && deltaY > deltaX || deltaX > 0 && deltaY < deltaX)
-      if (Math.abs(deltaX) > 5 * Math.abs(deltaY))
+      if (Math.abs(deltaX) > 5 * Math.abs(deltaY)) {
+        if (yCurrent > viewer.getScreenHeight()/2) deltaX*=-1;
         viewer.rotateZBy(-deltaX);
+      }
       break;
     case SHIFT_RIGHT: // the one-button Mac folks won't get this gesture
       viewer.rotateZBy((Math.abs(deltaY) > 5 * Math.abs(deltaX) 
