Index: trunk/geant4/visualization/OpenGL/include/G4OpenGLQtViewer.hh
===================================================================
--- trunk/geant4/visualization/OpenGL/include/G4OpenGLQtViewer.hh	(revision 695)
+++ trunk/geant4/visualization/OpenGL/include/G4OpenGLQtViewer.hh	(revision 696)
@@ -55,4 +55,6 @@
 class QImage;
 class QAction;
+class QMouseEvent;
+class QKeyEvent;
 
 class G4OpenGLSceneHandler;
@@ -78,8 +80,11 @@
   void G4MouseDoubleClickEvent(QPoint p);
 #if QT_VERSION < 0x040000
-  void G4MouseMoveEvent(int, int, Qt::ButtonState);
+  void G4MouseEvent(int, int, Qt::ButtonState);
 #else
-  void G4MouseMoveEvent(int, int, Qt::MouseButtons);
+  void G4MouseEvent(int, int, Qt::MouseButtons);
 #endif
+  void G4MouseRotateEvent(int, int);
+  void G4MouseMoveEvent(int, int, int);
+  void G4keyPressEvent (QKeyEvent * event); 
 
 
@@ -103,7 +108,12 @@
   QMenu *fContextMenu;
 #endif
-  enum mouseActions {ROTATE, MOVE, ZOOM, PICK}; 
+  enum mouseActions {STYLE1,STYLE2,STYLE3,STYLE4}; 
   mouseActions fMouseAction; // 1: rotate 0:move
-  QPoint lastPos;
+  QPoint fLastPos;
+  /* delta of scene translation. This delta is put in % of the scene view */
+  float fDeltaSceneTranslation;
+  /* delta of left right move. This delta is put in % of the scene view */
+  float fDeltaZoom;
+
 #if QT_VERSION < 0x040000
   QPopupMenu *fMouseRotate;
Index: trunk/geant4/visualization/OpenGL/include/G4OpenGLStoredQtViewer.hh
===================================================================
--- trunk/geant4/visualization/OpenGL/include/G4OpenGLStoredQtViewer.hh	(revision 695)
+++ trunk/geant4/visualization/OpenGL/include/G4OpenGLStoredQtViewer.hh	(revision 696)
@@ -69,4 +69,5 @@
   void mouseReleaseEvent(QMouseEvent *event);
   void contextMenuEvent(QContextMenuEvent *e);
+  void keyPressEvent (QKeyEvent * event); 
 
 private : 
Index: trunk/geant4/visualization/OpenGL/src/G4OpenGLQtExportDialog.cc
===================================================================
--- trunk/geant4/visualization/OpenGL/src/G4OpenGLQtExportDialog.cc	(revision 695)
+++ trunk/geant4/visualization/OpenGL/src/G4OpenGLQtExportDialog.cc	(revision 696)
@@ -30,5 +30,5 @@
 // 
 
-//#define GEANT4_QT_DEBUG
+#define GEANT4_QT_DEBUG
 #ifdef G4VIS_BUILD_OPENGLQT_DRIVER
 
Index: trunk/geant4/visualization/OpenGL/src/G4OpenGLQtViewer.cc
===================================================================
--- trunk/geant4/visualization/OpenGL/src/G4OpenGLQtViewer.cc	(revision 695)
+++ trunk/geant4/visualization/OpenGL/src/G4OpenGLQtViewer.cc	(revision 696)
@@ -36,5 +36,5 @@
 #ifdef G4VIS_BUILD_OPENGLQT_DRIVER
 
-//#define GEANT4_QT_DEBUG
+#define GEANT4_QT_DEBUG
 
 #include "G4OpenGLQtViewer.hh"
@@ -285,5 +285,7 @@
   ,fWindow(0)
   ,fContextMenu(0)
-  ,fMouseAction(ROTATE)
+  ,fMouseAction(STYLE1)
+  ,fDeltaSceneTranslation(1/100)
+  ,fDeltaZoom(2)
 {
 #ifdef GEANT4_QT_DEBUG
@@ -817,5 +819,5 @@
  */
 void G4OpenGLQtViewer::actionMouseRotate() {
-  emit toggleMouseAction(ROTATE);
+  emit toggleMouseAction(STYLE1);
 }
 
@@ -824,5 +826,5 @@
  */
 void G4OpenGLQtViewer::actionMouseMove() {
-  emit toggleMouseAction(MOVE);
+  emit toggleMouseAction(STYLE2);
 }
 
@@ -834,5 +836,5 @@
   printf("G4OpenGLQtViewer::actionMouseZoom \n");
 #endif
-  emit toggleMouseAction(ZOOM);
+  emit toggleMouseAction(STYLE3);
 }
 
@@ -844,5 +846,5 @@
   printf("G4OpenGLQtViewer::actionMousePick \n");
 #endif
-  emit toggleMouseAction(PICK);
+  emit toggleMouseAction(STYLE4);
 }
 
@@ -878,9 +880,14 @@
 /**
    Slot activated when mouse action is toggle
-   @param aAction : ROTATE, MOVE, ZOOM
+   @param aAction : STYLE1, STYLE2, STYLE3
  */
 void G4OpenGLQtViewer::toggleMouseAction(mouseActions aAction) {
   
-  if (aAction == ROTATE) {
+  if (aAction == STYLE1) {
+    G4cout << "Clic and move mouse to rotate Volume \n" << G4endl;
+    G4cout << "Press left/right arrows to move camera left/right\n" << G4endl;
+    G4cout << "Press up/down arrows to move camera toward/forward\n" << G4endl;
+    G4cout << "Press SHIFT+up/down arrows to move camera up/down\n" << G4endl;
+    G4cout << "Press +/- to zoom into volume\n" << G4endl;
 #if QT_VERSION < 0x040000
     fMouseRotate->setItemChecked (0,true);
@@ -894,7 +901,8 @@
     fMousePick->setChecked (false);
 #endif
-    fMouseAction = ROTATE;
+    fMouseAction = STYLE1;
     fVP.SetPicking(false);
-  } else  if (aAction == MOVE) {
+  } else  if (aAction == STYLE2) {
+    G4cout << "Clic and move mouse to move Volume \n" << G4endl;
 #if QT_VERSION < 0x040000
     fMouseRotate->setItemChecked (0,false);
@@ -908,7 +916,8 @@
     fMousePick->setChecked (false);
 #endif
-    fMouseAction = MOVE;
+    fMouseAction = STYLE2;
     fVP.SetPicking(false);
-  } else  if (aAction == ZOOM) {
+  } else  if (aAction == STYLE3) {
+    G4cout << "Clic and move mouse to rotate Volume \n" << G4endl;
 #if QT_VERSION < 0x040000
     fMouseRotate->setItemChecked (0,false);
@@ -922,7 +931,7 @@
     fMousePick->setChecked (false);
 #endif
-    fMouseAction = ZOOM;
+    fMouseAction = STYLE3;
     fVP.SetPicking(false);
-  } else  if (aAction == PICK) {
+  } else  if (aAction == STYLE4) {
 #if QT_VERSION < 0x040000
     fMouseRotate->setItemChecked (0,false);
@@ -937,5 +946,5 @@
 #endif
     fVP.SetPicking(true);
-    fMouseAction = PICK;
+    fMouseAction = STYLE4;
   }
 
@@ -1313,9 +1322,10 @@
 void G4OpenGLQtViewer::G4MousePressEvent(QPoint p)
 {
-  lastPos = p;
-  if (fMouseAction == PICK){  // pick
+  fLastPos = p;
+  if (fMouseAction == STYLE4){  // pick
     Pick(p.x(),p.y());
   }
 }
+
 
 /**
@@ -1326,98 +1336,118 @@
 
 #if QT_VERSION < 0x040000
-void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::ButtonState mButtons)
-#else
-void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::MouseButtons mButtons)
+void G4OpenGLQtViewer::G4MouseEvent(int pos_x, int pos_y,Qt::ButtonState mButtons)
+#else
+void G4OpenGLQtViewer::G4MouseEvent(int pos_x, int pos_y,Qt::MouseButtons mButtons)
 #endif
 {
-  int dx = pos_x - lastPos.x();
-  int dy = pos_y - lastPos.y();
-  if (fMouseAction == ROTATE) {  // rotate
+  int dx = pos_x - fLastPos.x();
+  int dy = pos_y - fLastPos.y();
+  if (fMouseAction == STYLE1) {  // rotate
     if (mButtons & Qt::LeftButton) {
-      //phi spin stuff here
-      
-      G4Vector3D vp = fVP.GetViewpointDirection ().unit ();
-      G4Vector3D up = fVP.GetUpVector ().unit ();
-      
-      G4Vector3D yprime = (up.cross(vp)).unit();
-      G4Vector3D zprime = (vp.cross(yprime)).unit();
-      
-      G4double delta_alpha;
-      G4double delta_theta;
-      
-      if (fVP.GetLightsMoveWithCamera()) {
-        delta_alpha = dy;
-        delta_theta = -dx;
-      } else {
-        delta_alpha = -dy;
-        delta_theta = dx;
-      }    
-
-      delta_alpha *= deg;
-      delta_theta *= deg;
-
-      G4Vector3D new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
-      
-      G4Vector3D new_up;
-      if (fVP.GetLightsMoveWithCamera()) {
-        new_up = (new_vp.cross(yprime)).unit();
-        fVP.SetUpVector(new_up);
-      } else {
-        new_up = up;
-      }
-      ////////////////
-      // Rotates by fixed azimuthal angle delta_theta.
-
-      G4double cosalpha = new_up.dot (new_vp.unit());
-      G4double sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
-      yprime = (new_up.cross (new_vp.unit())).unit ();
-      G4Vector3D xprime = yprime.cross (new_up);
-      // Projection of vp on plane perpendicular to up...
-      G4Vector3D a1 = sinalpha * xprime;
-      // Required new projection...
-      G4Vector3D a2 =
-        sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
-      // Required Increment vector...
-      G4Vector3D delta = a2 - a1;
-      // So new viewpoint is...
-      G4Vector3D viewPoint = new_vp.unit() + delta;
-
-      fVP.SetViewAndLights (viewPoint);
-      updateQWidget();
-      
-    } else if (mButtons & Qt::RightButton) {
-      // NEVER DONE BECAUSE OF MOUSE MENU
-      //       setXRotation(xRot + dy/2);
-      //       setZRotation(zRot + dx/2);
-      //       updateQWidget();
+      G4MouseRotateEvent(dx,dy);
     }
-  } else   if (fMouseAction == MOVE){  // move
+  } else   if (fMouseAction == STYLE2){  // move
     if (mButtons & Qt::LeftButton) {
-      
-      float dx = pos_x - lastPos.x();
-      float dy = pos_y - lastPos.y();
-      
-      G4Point3D stp
-        = GetSceneHandler()->GetScene()->GetStandardTargetPoint();
-      
-      G4Point3D tp = stp + fVP.GetCurrentTargetPoint ();
-      
-      const G4Vector3D& upVector = fVP.GetUpVector ();
-      const G4Vector3D& vpVector = fVP.GetViewpointDirection ();
-      
-      G4Vector3D unitRight = (upVector.cross (vpVector)).unit();
-      G4Vector3D unitUp    = (vpVector.cross (unitRight)).unit();
-      
-      tp += -dx * unitRight + dy * unitUp;
-      fVP.SetCurrentTargetPoint (tp - stp);
-      
-      updateQWidget();
+      G4MouseMoveEvent(dx,dy,0);
     }
-  } else   if (fMouseAction == ZOOM){  // zoom
+  } else   if (fMouseAction == STYLE3){  // zoom
     if (mButtons & Qt::LeftButton) {
       G4cerr << "Zoom not implemented for the moment\n" << G4endl;
     }
   }
-  lastPos = QPoint(pos_x, pos_y);
+  fLastPos = QPoint(pos_x, pos_y);
+}
+
+/**
+   @param dx delta mouse x position
+   @param dy delta mouse y position
+*/
+
+void G4OpenGLQtViewer::G4MouseMoveEvent(int dx, int dy, int dz)
+{
+  G4Point3D stp
+    = GetSceneHandler()->GetScene()->GetStandardTargetPoint();
+  
+  G4Point3D tp = stp + fVP.GetCurrentTargetPoint ();
+  
+  const G4Vector3D& upVector = fVP.GetUpVector ();
+  const G4Vector3D& vpVector = fVP.GetViewpointDirection ();
+  
+  G4Vector3D unitRight = (upVector.cross (vpVector)).unit();
+  G4Vector3D unitUp    = (vpVector.cross (unitRight)).unit();
+  
+#ifdef GEANT4_QT_DEBUG
+  G4cout << fVP<<G4endl;
+  printf("Mouse event Target Point : %f %f %f\n",tp.x(),tp.y(),tp.z());
+  printf("Mouse event upVector : %f %f %f\n",upVector.x(),upVector.y(),upVector.z());
+  printf("Mouse event vpVector Point : %f %f %f\n",vpVector.x(),vpVector.y(),vpVector.z());
+  printf("Mouse event unitRight Point : %f %f %f\n",unitRight.x(),unitRight.y(),unitRight.z());
+  printf("Mouse event unitUp Point : %f %f %f\n",unitUp.x(),unitUp.y(),unitUp.z());
+#endif
+  tp += -dx * unitRight + dy * unitUp + dz * vpVector;
+  fVP.SetCurrentTargetPoint (tp - stp);
+  
+  updateQWidget();
+}
+
+
+/**
+   @param dx delta mouse x position
+   @param dy delta mouse y position
+*/
+
+void G4OpenGLQtViewer::G4MouseRotateEvent(int dx, int dy)
+{
+  //phi spin stuff here
+  
+  G4Vector3D vp = fVP.GetViewpointDirection ().unit ();
+  G4Vector3D up = fVP.GetUpVector ().unit ();
+  
+  G4Vector3D yprime = (up.cross(vp)).unit();
+  G4Vector3D zprime = (vp.cross(yprime)).unit();
+  
+  G4double delta_alpha;
+  G4double delta_theta;
+  
+  if (fVP.GetLightsMoveWithCamera()) {
+    delta_alpha = dy;
+    delta_theta = -dx;
+  } else {
+    delta_alpha = -dy;
+    delta_theta = dx;
+  }    
+  
+  delta_alpha *= deg;
+  delta_theta *= deg;
+  
+  G4Vector3D new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
+  
+  G4Vector3D new_up;
+  if (fVP.GetLightsMoveWithCamera()) {
+    new_up = (new_vp.cross(yprime)).unit();
+    fVP.SetUpVector(new_up);
+  } else {
+    new_up = up;
+  }
+  ////////////////
+  // Rotates by fixed azimuthal angle delta_theta.
+  
+  G4double cosalpha = new_up.dot (new_vp.unit());
+  G4double sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
+  yprime = (new_up.cross (new_vp.unit())).unit ();
+  G4Vector3D xprime = yprime.cross (new_up);
+  // Projection of vp on plane perpendicular to up...
+  G4Vector3D a1 = sinalpha * xprime;
+  // Required new projection...
+  G4Vector3D a2 =
+    sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
+  // Required Increment vector...
+  G4Vector3D delta = a2 - a1;
+  // So new viewpoint is...
+  G4Vector3D viewPoint = new_vp.unit() + delta;
+  
+  fVP.SetViewAndLights (viewPoint);
+  updateQWidget();
+  
 }
 
@@ -1712,6 +1742,39 @@
 #endif
 
+void G4OpenGLQtViewer::G4keyPressEvent (QKeyEvent * event) 
+{
+#ifdef GEANT4_QT_DEBUG
+  printf("G4OpenGLQtViewer::keyPressEvent count:%d autoRepeat:%d key:%d\n",event->count(),event->isAutoRepeat(),event->key());
+#endif
+  if (event->key() == Qt::Key_Down)
+    {
+      G4MouseMoveEvent(0,0,-1);
+    }
+  if (event->key() == Qt::Key_Up)
+    {
+      G4MouseMoveEvent(0,0,1);
+    }
+  if (event->key() == Qt::Key_Left)
+    {
+      G4MouseMoveEvent(-1,0,0);
+    }
+  if (event->key() == Qt::Key_Right)
+    {
+      G4MouseMoveEvent(1,0,0);
+    }
+  if (event->key() == Qt::Key_Plus) 
+    {
+      fVP.SetZoomFactor(fVP.GetZoomFactor()*fDeltaZoom); 
+      updateQWidget();
+    }
+  if (event->key() == Qt::Key_Minus)
+    {
+      fVP.SetZoomFactor(fVP.GetZoomFactor()/fDeltaZoom); 
+      updateQWidget();
+    }
+}
+
 /*
-
+  
 void MultiLayer::exportToSVG(const QString& fname)
 {
Index: trunk/geant4/visualization/OpenGL/src/G4OpenGLStoredQtViewer.cc
===================================================================
--- trunk/geant4/visualization/OpenGL/src/G4OpenGLStoredQtViewer.cc	(revision 695)
+++ trunk/geant4/visualization/OpenGL/src/G4OpenGLStoredQtViewer.cc	(revision 696)
@@ -52,4 +52,5 @@
   QGLWidget(QGLFormat(QGL::SampleBuffers))             // FIXME : gerer le pb du parent !
 {
+  setFocusPolicy(Qt::StrongFocus); // enable keybord events
   nbPaint =0;
   hasToRepaint =false;
@@ -311,4 +312,9 @@
 }
 
+void G4OpenGLStoredQtViewer::keyPressEvent (QKeyEvent * event) 
+{
+  G4keyPressEvent(event);
+}
+
 /**
  * This function was build in order to make a zoom on double clic event.
@@ -336,7 +342,7 @@
 
 #if QT_VERSION < 0x040000
-  G4MouseMoveEvent(event->x(),event->y(),event->state());
+  G4MouseEvent(event->x(),event->y(),event->state());
 #else
-  G4MouseMoveEvent(event->x(),event->y(),event->buttons());
+  G4MouseEvent(event->x(),event->y(),event->buttons());
 #endif
 }
