source: trunk/geant4/visualization/OpenGL/src/G4OpenGLQtViewer.cc @ 801

Last change on this file since 801 was 801, checked in by garnier, 16 years ago

r840@wl-72126: garnier | 2008-05-16 17:45:55 +0200
en test avec de nouveaux calculs...

  • Property svn:mime-type set to text/cpp
File size: 90.0 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26//
27// $Id: G4OpenGLQtViewer.cc,v 1.23 2008/04/29 16:58:04 lgarnier Exp $
28// GEANT4 tag $Name:  $
29//
30//
31// G4OpenGLQtViewer : Class to provide Qt specific
32//                     functionality for OpenGL in GEANT4
33//
34// 27/06/2003 : G.Barrand : implementation (at last !).
35
36#ifdef G4VIS_BUILD_OPENGLQT_DRIVER
37
38#define GEANT4_QT_DEBUG
39
40#include "G4OpenGLQtViewer.hh"
41
42#include <cmath>
43#include "G4ios.hh"
44#include "G4VisExtent.hh"
45#include "G4LogicalVolume.hh"
46#include "G4VSolid.hh"
47#include "G4Point3D.hh"
48#include "G4Normal3D.hh"
49#include "G4Scene.hh"
50#include "G4OpenGLQtExportDialog.hh"
51#include "G4OpenGLQtMovieDialog.hh"
52#include "G4UnitsTable.hh"
53#include "G4Qt.hh"
54#include "G4UImanager.hh"
55#include "G4UIcommandTree.hh"
56#include <qlayout.h>
57#include <qdialog.h>
58#include <qprocess.h>
59#include <qapplication.h>
60
61#if QT_VERSION >= 0x040000
62#include <qmenu.h>
63#include <qimagewriter.h>
64#else
65#include <qaction.h>
66#include <qwidgetlist.h>
67#include <qpopupmenu.h>
68#include <qimage.h>
69#endif
70
71#include <qapplication.h>
72#include <qmessagebox.h>
73#include <qfiledialog.h>
74#include <qprinter.h>
75#include <qdatetime.h>
76#include <qpainter.h>
77#include <qgl.h> // include <qglwidget.h>
78#include <qdialog.h>
79#include <qevent.h> //include <qcontextmenuevent.h>
80#include <qdatetime.h>
81
82//////////////////////////////////////////////////////////////////////////////
83/**
84   Implementation of virtual method of G4VViewer
85*/
86void G4OpenGLQtViewer::SetView (
87)
88//////////////////////////////////////////////////////////////////////////////
89//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
90{
91  //   if(!fHDC) return;
92  //   if(!fHGLRC) return;
93  //   ::wglMakeCurrent(fHDC,fHGLRC);
94  //  fWindow->makeCurrent();
95  G4OpenGLViewer::SetView ();
96}
97
98void G4OpenGLQtViewer::ClearView (
99)
100//////////////////////////////////////////////////////////////////////////////
101//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
102{
103  G4OpenGLViewer::ClearView ();
104  // glLoadIdentity();
105  //   glRotatef(fRotationAngleX, 1.0, 0.0, 0.0);
106//    glRotatef(fRotationAngleY, 0.0, 1.0, 0.0);
107//    glRotatef(fRotationAngleZ, 0.0, 0.0, 1.0);
108//    fRotationAngleZ +=fDeltaRotationAngleZ;
109//    fRotationAngleY +=fDeltaRotationAngleY;
110//    fRotationAngleX +=fDeltaRotationAngleX;
111}
112
113/**
114 * Set the viewport of the scene
115 */
116void G4OpenGLQtViewer::setupViewport(int aWidth, int aHeight)
117{
118  int side = aWidth;
119  if (aHeight < aWidth) side = aHeight;
120  glViewport((aWidth - side) / 2, (aHeight - side) / 2, side, side);
121 
122  glMatrixMode(GL_PROJECTION);
123  glLoadIdentity();
124  glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0);
125  glMatrixMode(GL_MODELVIEW);
126}
127
128
129//////////////////////////////////////////////////////////////////////////////
130/**
131   Implementation of virtual method of G4VViewer
132*/
133void G4OpenGLQtViewer::ShowView (
134)
135//////////////////////////////////////////////////////////////////////////////
136//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
137{
138#ifdef GEANT4_QT_DEBUG
139  printf("G4OpenGLQtViewer::ShowView  +++++++++++++++++++++\n");
140#endif
141  if (!GLWindow) {
142    G4cerr << "Visualization window not defined, please choose one before\n" << G4endl;
143  } else {
144#if QT_VERSION < 0x040000
145    GLWindow->setActiveWindow();
146#else
147    GLWindow->activateWindow();
148#endif
149#ifdef GEANT4_QT_DEBUG
150    printf("G4OpenGLQtViewer::ShowView -----------------------\n");
151#endif
152  }
153  glFlush ();
154  //   // Empty the Windows message queue :
155  //   MSG event;
156  //   while ( ::PeekMessage(&event, NULL, 0, 0, PM_REMOVE) ) {
157  //     ::TranslateMessage(&event);
158  //     ::DispatchMessage (&event);
159  //   }
160}
161
162
163
164//////////////////////////////////////////////////////////////////////////////
165void G4OpenGLQtViewer::CreateGLQtContext (
166)
167//////////////////////////////////////////////////////////////////////////////
168//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
169{
170#ifdef GEANT4_QT_DEBUG
171  printf("G4OpenGLQtViewer::CreateGLQtContext \n");
172#endif
173}
174
175
176//////////////////////////////////////////////////////////////////////////////
177void G4OpenGLQtViewer::CreateMainWindow (
178 QGLWidget* glWidget
179)
180//////////////////////////////////////////////////////////////////////////////
181//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
182{
183
184  if(fWindow) return; //Done.
185#ifdef GEANT4_QT_DEBUG
186  printf("G4OpenGLQtViewer::CreateMainWindow glWidget\n");
187#endif
188
189  // launch Qt if not
190  G4Qt* interactorManager = G4Qt::getInstance ();
191  //  G4UImanager* UI = G4UImanager::GetUIpointer();
192
193  fWindow = glWidget ;
194  //  fWindow->makeCurrent();
195
196  // create window
197  if (((QApplication*)interactorManager->GetMainInteractor())) {
198    // look for the main window
199    bool found = false;
200#if QT_VERSION < 0x040000
201    // theses lines does nothing exept this one "GLWindow = new QDialog(0..."
202    // but if I comment them, it doesn't work...
203    QWidgetList  *list = QApplication::allWidgets();
204    QWidgetListIt it( *list );         // iterate over the widgets
205    QWidget * widget;
206    while ( (widget=it.current()) != 0 ) {  // for each widget...
207      ++it;
208      if ((found== false) && (widget->inherits("QMainWindow"))) {
209        GLWindow = new QDialog(0,0,FALSE,Qt::WStyle_Title | Qt::WStyle_SysMenu | Qt::WStyle_MinMax );
210        found = true;
211      }
212    }
213    delete list;                      // delete the list, not the widgets
214#else
215    foreach (QWidget *widget, QApplication::allWidgets()) {
216      if ((found== false) && (widget->inherits("QMainWindow"))) {
217        GLWindow = new QDialog(0,Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
218        found = true;
219      }
220    }
221#endif
222
223#if QT_VERSION < 0x040000
224    glWidget->reparent(GLWindow,0,QPoint(0,0)); 
225#else
226    glWidget->setParent(GLWindow); 
227#endif
228
229    if (found==false) {
230#ifdef GEANT4_QT_DEBUG
231      printf("G4OpenGLQtViewer::CreateMainWindow case Qapp exist, but not found\n");
232#endif
233      GLWindow = new QDialog();
234    }
235  } else {
236#ifdef GEANT4_QT_DEBUG
237    printf("G4OpenGLQtViewer::CreateMainWindow case Qapp exist\n");
238#endif
239    GLWindow = new QDialog();
240  }
241
242  QHBoxLayout *mainLayout = new QHBoxLayout(GLWindow);
243
244  mainLayout->addWidget(fWindow);
245
246#if QT_VERSION < 0x040000
247  GLWindow->setCaption( tr( "QGl Viewer" ));
248#else
249  GLWindow->setLayout(mainLayout);
250  GLWindow->setWindowTitle(tr("QGl Viewer"));
251#endif
252  GLWindow->resize(300, 300);
253  GLWindow->move(900,300);
254  GLWindow->show();
255 
256  // delete the pointer if close this
257  //  GLWindow->setAttribute(Qt::WA_DeleteOnClose);
258
259#if QT_VERSION >= 0x040000
260//   QObject ::connect(GLWindow,
261//                     SIGNAL(rejected()),
262//                     this,
263//                     SLOT(dialogClosed()));
264#endif
265
266  WinSize_x = 400;
267  WinSize_y = 400;
268  if (WinSize_x < fVP.GetWindowSizeHintX ())
269    WinSize_x = fVP.GetWindowSizeHintX ();
270  if (WinSize_y < fVP.GetWindowSizeHintY ())
271    WinSize_y = fVP.GetWindowSizeHintY ();
272
273  if(!fWindow) return;
274#ifdef GEANT4_QT_DEBUG
275  printf("G4OpenGLQtViewer::CreateMainWindow glWidget END\n");
276#endif
277
278  if (!fContextMenu)
279    createPopupMenu();
280
281}
282
283#if QT_VERSION >= 0x040000
284/**  Close the dialog and set the pointer to NULL
285 */
286// void G4OpenGLQtViewer::dialogClosed() {
287// #ifdef GEANT4_QT_DEBUG
288//   printf("G4OpenGLQtViewer::dialogClosed END\n");
289// #endif
290//   //  GLWindow = NULL;
291// }
292#endif
293
294//////////////////////////////////////////////////////////////////////////////
295G4OpenGLQtViewer::G4OpenGLQtViewer (
296                                    G4OpenGLSceneHandler& scene
297                                    )
298  :G4VViewer (scene, -1)
299  ,G4OpenGLViewer (scene)
300  ,fWindow(0)
301  ,fRecordFrameNumber(0)
302  ,fContextMenu(0)
303  ,fMouseAction(STYLE1)
304  ,fDeltaRotation(1)
305  ,fDeltaSceneTranslation(0.01)
306  ,fDeltaDepth(0.01)
307  ,fDeltaZoom(0.05)
308  ,fDeltaMove(0.05)
309  ,fHoldKeyEvent(false)
310  ,fHoldMoveEvent(false)
311  ,fHoldRotateEvent(false)
312  ,fAutoMove(false)
313  ,fEncoderPath("")
314  ,fTempFolderPath("")
315  ,fMovieTempFolderPath("")
316  ,fSaveFileName("")
317  ,fParameterFileName("mpeg_encode_parameter_file.par")
318  ,fMovieParametersDialog(NULL)
319  ,fRecordingStep(WAIT)
320  ,fProcess(NULL)
321  ,fLaunchSpinDelay(100)
322  ,fRotationAngleX(0)
323  ,fRotationAngleY(0)
324  ,fDeltaRotationAngleX(0)
325  ,fDeltaRotationAngleY(0)
326{
327
328  // launch Qt if not
329  G4Qt* interactorManager = G4Qt::getInstance ();
330
331  fLastPos3 = QPoint(-1,-1);   
332  fLastPos2 = QPoint(-1,-1);   
333  fLastPos1 = QPoint(-1,-1);   
334 
335  initMovieParameters();
336
337  fLastEventTime = new QTime();
338
339#ifdef GEANT4_QT_DEBUG
340  printf("G4OpenGLQtViewer::G4OpenGLQtViewer END\n");
341#endif
342}
343
344//////////////////////////////////////////////////////////////////////////////
345G4OpenGLQtViewer::~G4OpenGLQtViewer (
346)
347//////////////////////////////////////////////////////////////////////////////
348//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
349{
350#if QT_VERSION < 0x040000
351  G4cout <<removeTempFolder().ascii() <<G4endl;
352#else
353  G4cout <<removeTempFolder().toStdString().c_str() <<G4endl;
354#endif
355
356#ifdef GEANT4_QT_DEBUG
357  printf("G4OpenGLQtViewer::~G4OpenGLQtViewer \n");
358#endif
359}
360
361
362/**
363   Create a popup menu for the widget. This menu is activated by right-mouse click
364*/
365void G4OpenGLQtViewer::createPopupMenu()    {
366
367#if QT_VERSION < 0x040000
368  fContextMenu = new QPopupMenu( GLWindow,"All" );
369#else
370  fContextMenu = new QMenu("All");
371#endif
372
373#if QT_VERSION < 0x040000
374  QPopupMenu *mMouseAction = new QPopupMenu( fContextMenu );
375  fContextMenu->insertItem("&Mouse actions",mMouseAction);
376#if QT_VERSION < 0x030200
377  fRotateAction =  new QAction("&Rotate","&Rotate",CTRL+Key_R,mMouseAction,0,true);
378  fMoveAction =  new QAction("&Move","&Move",CTRL+Key_M,mMouseAction,0,true);
379  fPickAction =  new QAction("&Pick","&Pick",CTRL+Key_P,mMouseAction,0,true);
380  QAction * shortcutsAction =  new QAction("&Show shortcuts","&Show shortcuts",CTRL+Key_S,mMouseAction,0,true);
381#else
382  fRotateAction =  new QAction("&Rotate",CTRL+Key_R,mMouseAction);
383  fMoveAction =  new QAction("&Move",CTRL+Key_M,mMouseAction);
384  fPickAction =  new QAction("&Pick",CTRL+Key_P,mMouseAction);
385  QAction *shortcutsAction =  new QAction("&Show shortcuts",CTRL+Key_S,mMouseAction);
386#endif
387  fRotateAction->addTo(mMouseAction);
388  fMoveAction->addTo(mMouseAction);
389  fPickAction->addTo(mMouseAction);
390  shortcutsAction->addTo(mMouseAction);
391
392  fRotateAction->setToggleAction(true);
393  fMoveAction->setToggleAction(true);
394  fPickAction->setToggleAction(true);
395  shortcutsAction->setToggleAction(true);
396
397  fRotateAction->setOn(true);
398  fMoveAction->setOn(false);
399  fPickAction->setOn(false);
400  shortcutsAction->setOn(false);
401
402
403  QObject ::connect(fRotateAction,
404                    SIGNAL(activated()),
405                    this,
406                    SLOT(actionMouseRotate()));
407
408  QObject ::connect(fMoveAction,
409                    SIGNAL(activated()),
410                    this,
411                    SLOT(actionMouseMove()));
412
413  QObject ::connect(fPickAction,
414                    SIGNAL(activated()),
415                    this,
416                    SLOT(actionMousePick()));
417
418  QObject ::connect(shortcutsAction,
419                    SIGNAL(activated()),
420                    this,
421                    SLOT(showShortcuts()));
422
423#else
424  QMenu *mMouseAction = fContextMenu->addMenu("&Mouse actions");
425
426  fRotateAction = mMouseAction->addAction("Rotate");
427  fMoveAction = mMouseAction->addAction("Move");
428  fPickAction = mMouseAction->addAction("Pick");
429  QAction *shortcutsAction = mMouseAction->addAction("Show shortcuts");
430
431  fRotateAction->setCheckable(true);
432  fMoveAction->setCheckable(false);
433  fPickAction->setCheckable(false);
434  shortcutsAction->setCheckable(false);
435
436  fRotateAction->setChecked(true);
437  fMoveAction->setChecked(false);
438  fPickAction->setChecked(false);
439  shortcutsAction->setChecked(false);
440
441  QObject ::connect(fRotateAction,
442                    SIGNAL(triggered(bool)),
443                    this,
444                    SLOT(actionMouseRotate()));
445
446  QObject ::connect(fMoveAction,
447                    SIGNAL(triggered(bool)),
448                    this,
449                    SLOT(actionMouseMove()));
450
451  QObject ::connect(fPickAction,
452                    SIGNAL(triggered(bool)),
453                    this,
454                    SLOT(actionMousePick()));
455
456  QObject ::connect(shortcutsAction,
457                    SIGNAL(triggered(bool)),
458                    this,
459                    SLOT(showShortcuts()));
460#endif
461
462#if QT_VERSION < 0x040000
463  // === Style Menu ===
464  QPopupMenu *mStyle = new QPopupMenu(fContextMenu);
465
466  QPopupMenu *mRepresentation = new QPopupMenu(fContextMenu);
467
468  QPopupMenu *mProjection = new QPopupMenu(fContextMenu);
469
470#if QT_VERSION < 0x030200
471  QAction *polyhedron = new QAction("&Polyhedron","&Polyhedron",CTRL+Key_P,mRepresentation,0,true);
472  QAction *nurbs = new QAction("&NURBS","&NURBS",CTRL+Key_N,mRepresentation,0,true);
473
474  QAction *ortho = new QAction("&Orthographic","&Orthographic",CTRL+Key_O,mProjection,0,true);
475  QAction *perspective = new QAction("&Perspective","&Perspective",CTRL+Key_P,mProjection,0,true);
476#else
477  QAction *polyhedron = new QAction("&Polyhedron",CTRL+Key_P,mRepresentation);
478  QAction *nurbs = new QAction("&NURBS",CTRL+Key_N,mRepresentation);
479
480  QAction *ortho = new QAction("&Orthographic",CTRL+Key_O,mProjection);
481  QAction *perspective = new QAction("&Perspective",CTRL+Key_P,mProjection);
482  polyhedron->setToggleAction(true);
483  nurbs->setToggleAction(true);
484  ortho->setToggleAction(true);
485  perspective->setToggleAction(true);
486#endif
487  polyhedron->addTo(mRepresentation);
488  nurbs->addTo(mRepresentation);
489
490  ortho->addTo(mProjection);
491  perspective->addTo(mProjection);
492
493  mStyle->insertItem("&Representation",mRepresentation);
494  mStyle->insertItem("&Projection",mProjection);
495  fContextMenu->insertItem("&Style",mStyle);
496
497
498#else
499  // === Style Menu ===
500  QMenu *mStyle = fContextMenu->addMenu("&Style");
501
502  QMenu *mRepresentation = mStyle->addMenu("&Representation");
503  QMenu *mProjection = mStyle->addMenu("&Projection");
504  QAction *polyhedron = mRepresentation->addAction("Polyhedron");
505  QAction *nurbs = mRepresentation->addAction("NURBS");
506
507  QAction *ortho = mProjection->addAction("Orthographic");
508  QAction *perspective = mProjection->addAction("Persepective");
509#endif
510
511  // INIT mRepresentation
512  G4ViewParameters::RepStyle style;
513  style = fVP.GetRepStyle();
514  if (style == G4ViewParameters::polyhedron) {
515    createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(bool)),1);
516  } else if (style == G4ViewParameters::nurbs) {
517    createRadioAction(polyhedron,nurbs,SLOT(toggleRepresentation(bool)),2);
518  } else {
519    mRepresentation->clear();
520  }
521
522  // INIT mProjection
523  if (fVP.GetFieldHalfAngle() == 0) {
524    createRadioAction(ortho, perspective,SLOT(toggleProjection(bool)),1);
525  } else {
526    createRadioAction(ortho, perspective,SLOT(toggleProjection(bool)),2);
527  }
528
529#if QT_VERSION < 0x040000
530  // === Drawing Menu ===
531  QPopupMenu *mDrawing = new QPopupMenu(fContextMenu);
532  fContextMenu->insertItem("&Drawing",mDrawing);
533
534#if QT_VERSION < 0x030200
535  fDrawingWireframe = new QAction("&Wireframe","&Wireframe",CTRL+Key_W,mDrawing,0,true);
536  fDrawingLineRemoval = new QAction("&Hidden line removal","&Hidden line removal",CTRL+Key_L,mDrawing,0,true);
537  fDrawingSurfaceRemoval = new QAction("&Hidden surface removal","&Hidden surface removal",CTRL+Key_S,mDrawing,0,true);
538  fDrawingLineSurfaceRemoval = new QAction("&Hidden line and surface removal","&Hidden line and surface removal",CTRL+Key_R,mDrawing,0,true);
539#else
540  fDrawingWireframe = new QAction("&Wireframe",CTRL+Key_W,mDrawing);
541  fDrawingLineRemoval = new QAction("&Hidden line removal",CTRL+Key_L,mDrawing);
542  fDrawingSurfaceRemoval = new QAction("&Hidden surface removal",CTRL+Key_S,mDrawing);
543  fDrawingLineSurfaceRemoval = new QAction("&Hidden line and surface removal",CTRL+Key_R,mDrawing);
544#endif
545  fDrawingWireframe->setToggleAction(true);
546  fDrawingLineRemoval->setToggleAction(true);
547  fDrawingSurfaceRemoval->setToggleAction(true);
548  fDrawingLineSurfaceRemoval->setToggleAction(true);
549
550  fDrawingWireframe->addTo(mDrawing);
551  fDrawingLineRemoval->addTo(mDrawing);
552  fDrawingSurfaceRemoval->addTo(mDrawing);
553  fDrawingLineSurfaceRemoval->addTo(mDrawing);
554
555
556#else
557  // === Drawing Menu ===
558  QMenu *mDrawing = mStyle->addMenu("&Drawing");
559
560  fDrawingWireframe = mDrawing->addAction("Wireframe");
561  fDrawingWireframe->setCheckable(true);
562
563  fDrawingLineRemoval = mDrawing->addAction("Hidden line removal");
564  fDrawingLineRemoval->setCheckable(true);
565
566  fDrawingSurfaceRemoval = mDrawing->addAction("Hidden Surface removal");
567  fDrawingSurfaceRemoval->setCheckable(true);
568
569  fDrawingLineSurfaceRemoval = mDrawing->addAction("Hidden line and surface removal");
570  fDrawingLineSurfaceRemoval->setCheckable(true);
571#endif
572  // INIT Drawing
573  G4ViewParameters::DrawingStyle d_style;
574  d_style = fVP.GetDrawingStyle();
575 
576#if QT_VERSION < 0x040000
577  if (d_style == G4ViewParameters::wireframe) {
578    fDrawingWireframe->setOn(true);
579  } else if (d_style == G4ViewParameters::hlr) {
580    fDrawingLineRemoval->setOn(true);
581  } else if (d_style == G4ViewParameters::hsr) {
582    fDrawingSurfaceRemoval->setOn(true);
583  } else if (d_style == G4ViewParameters::hlhsr) {
584    fDrawingLineSurfaceRemoval->setOn(true);
585  } else {
586    mDrawing->clear();
587  }
588#ifdef GEANT4_QT_DEBUG
589  printf("G4OpenGLQtViewer:: fDrawingWireframe 1\n");
590#endif
591  QObject ::connect(fDrawingWireframe,
592                    SIGNAL(activated()),
593                    this,
594                    SLOT(actionDrawingWireframe()));
595#ifdef GEANT4_QT_DEBUG
596  printf("G4OpenGLQtViewer:: fDrawingWireframe 2\n");
597#endif
598  QObject ::connect(fDrawingLineRemoval,
599                    SIGNAL(activated()),
600                    this,
601                    SLOT(actionDrawingLineRemoval()));
602  QObject ::connect(fDrawingSurfaceRemoval,
603                    SIGNAL(activated()),
604                    this,
605                    SLOT(actionDrawingSurfaceRemoval()));
606  QObject ::connect(fDrawingLineSurfaceRemoval,
607                    SIGNAL(activated()),
608                    this,
609                    SLOT(actionDrawingLineSurfaceRemoval()));
610#else
611  if (d_style == G4ViewParameters::wireframe) {
612    fDrawingWireframe->setChecked(true);
613  } else if (d_style == G4ViewParameters::hlr) {
614    fDrawingLineRemoval->setChecked(true);
615  } else if (d_style == G4ViewParameters::hsr) {
616    fDrawingSurfaceRemoval->setChecked(true);
617  } else if (d_style == G4ViewParameters::hlhsr) {
618    fDrawingLineSurfaceRemoval->setChecked(true);
619  } else {
620    mDrawing->clear();
621  }
622  QObject ::connect(fDrawingWireframe,
623                    SIGNAL(triggered(bool)),
624                    this,
625                    SLOT(actionDrawingWireframe()));
626  QObject ::connect(fDrawingLineRemoval,
627                    SIGNAL(triggered(bool)),
628                    this,
629                    SLOT(actionDrawingLineRemoval()));
630  QObject ::connect(fDrawingSurfaceRemoval,
631                    SIGNAL(triggered(bool)),
632                    this,
633                    SLOT(actionDrawingSurfaceRemoval()));
634  QObject ::connect(fDrawingLineSurfaceRemoval,
635                    SIGNAL(triggered(bool)),
636                    this,
637                    SLOT(actionDrawingLineSurfaceRemoval()));
638#endif
639
640
641
642#if QT_VERSION < 0x040000
643  QPopupMenu *mBackground = new QPopupMenu(mStyle);
644  mStyle->insertItem("&Background color",mBackground);
645
646#if QT_VERSION < 0x030200
647  QAction *white = new QAction("&White","&White",CTRL+Key_W,mBackground,0,true);
648  QAction *black =  new QAction("&Black","&Black",CTRL+Key_B,mBackground,0,true);
649#else
650  QAction *white = new QAction("&White",CTRL+Key_W,mBackground);
651  QAction *black =  new QAction("&Black",CTRL+Key_B,mBackground);
652  white->setToggleAction(true);
653  black->setToggleAction(true);
654#endif
655  white->addTo(mBackground);
656  black->addTo(mBackground);
657
658#else
659  QMenu *mBackground = mStyle->addMenu("&Background color");
660  QAction *white = mBackground->addAction("White");
661  QAction *black = mBackground->addAction("Black");
662
663#endif
664  if (background.GetRed() == 1. &&
665      background.GetGreen() == 1. &&
666      background.GetBlue() == 1.) {
667    createRadioAction(white,black,SLOT(toggleBackground(bool)),1);
668  } else {
669    createRadioAction(white,black,SLOT(toggleBackground(bool)),2);
670  }
671
672
673#if QT_VERSION < 0x040000
674  // === Action Menu ===
675  QPopupMenu *mActions = new QPopupMenu(fContextMenu);
676  fContextMenu->insertItem("&Actions",mActions);
677
678#if QT_VERSION < 0x030200
679  QAction *createEPS =  new QAction("&Save as ...","&Save as ...",CTRL+Key_S,mActions,0,true);
680#else
681  QAction *createEPS =  new QAction("&Save as ...",CTRL+Key_S,mActions);
682#endif
683  createEPS->addTo(mActions);
684  QObject ::connect(createEPS,
685                    SIGNAL(activated()),
686                    this,
687                    SLOT(actionSaveImage()));
688
689#else
690  // === Action Menu ===
691  QMenu *mActions = fContextMenu->addMenu("&Actions");
692  QAction *createEPS = mActions->addAction("Save as ...");
693  QObject ::connect(createEPS,
694                    SIGNAL(triggered()),
695                    this,
696                    SLOT(actionSaveImage()));
697#endif
698
699#if QT_VERSION < 0x040000
700#if QT_VERSION < 0x030200
701  QAction *movieParameters =  new QAction("&Movie parameters...","&Make movie ...",CTRL+Key_M,mActions,0,true);
702#else
703  QAction *movieParameters =  new QAction("&Movie parameters...",CTRL+Key_M,mActions);
704#endif
705  movieParameters->addTo(mActions);
706  QObject ::connect(movieParameters,
707                    SIGNAL(activated()),
708                    this,
709                    SLOT(actionMovieParameters()));
710
711#else
712  // === Action Menu ===
713  QAction *movieParameters = mActions->addAction("Movie parameters...");
714  QObject ::connect(movieParameters,
715                    SIGNAL(triggered()),
716                    this,
717                    SLOT(actionMovieParameters()));
718#endif
719
720
721
722
723#if QT_VERSION < 0x040000
724  // === Special Menu ===
725  QPopupMenu *mSpecial = new QPopupMenu(fContextMenu);
726  fContextMenu->insertItem("S&pecial",mSpecial);
727
728  QPopupMenu *mTransparency = new QPopupMenu(mSpecial);
729  mSpecial->insertItem("Transparency",mTransparency);
730
731#if QT_VERSION < 0x030200
732  QAction *transparencyOn = new QAction("&On","&On",CTRL+Key_O,mTransparency,0,true);
733  QAction *transparencyOff = new QAction("&Off","&Off",CTRL+Key_F,mTransparency,0,true);
734#else
735  QAction *transparencyOn = new QAction("&On",CTRL+Key_O,mTransparency);
736  QAction *transparencyOff = new QAction("&Off",CTRL+Key_F,mTransparency);
737  transparencyOn->setToggleAction(true);
738  transparencyOff->setToggleAction(true);
739#endif
740  transparencyOn->addTo(mTransparency);
741  transparencyOff->addTo(mTransparency);
742
743#else
744  // === Special Menu ===
745  QMenu *mSpecial = fContextMenu->addMenu("S&pecial");
746  QMenu *mTransparency = mSpecial->addMenu("Transparency");
747  QAction *transparencyOn = mTransparency->addAction("On");
748  QAction *transparencyOff = mTransparency->addAction("Off");
749#endif
750
751  if (transparency_enabled == false) {
752    createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(bool)),2);
753  } else if (transparency_enabled == true) {
754    createRadioAction(transparencyOn,transparencyOff,SLOT(toggleTransparency(bool)),1);
755  } else {
756    mSpecial->clear();
757  }
758
759
760#if QT_VERSION < 0x040000
761  QPopupMenu *mAntialiasing = new QPopupMenu(mSpecial);
762  mSpecial->insertItem("Antialiasing",mAntialiasing);
763
764#if QT_VERSION < 0x030200
765  QAction *antialiasingOn = new QAction("&On","&On",CTRL+Key_O,mAntialiasing,0,true);
766  QAction *antialiasingOff = new QAction("&Off","&Off",CTRL+Key_F,mAntialiasing,0,true);
767#else
768  QAction *antialiasingOn = new QAction("&On",CTRL+Key_O,mAntialiasing);
769  QAction *antialiasingOff = new QAction("&Off",CTRL+Key_F,mAntialiasing);
770  antialiasingOn->setToggleAction(true);
771  antialiasingOff->setToggleAction(true);
772#endif
773  antialiasingOn->addTo(mAntialiasing);
774  antialiasingOff->addTo(mAntialiasing);
775
776#else
777  QMenu *mAntialiasing = mSpecial->addMenu("Antialiasing");
778  QAction *antialiasingOn = mAntialiasing->addAction("On");
779  QAction *antialiasingOff = mAntialiasing->addAction("Off");
780#endif
781
782  if (antialiasing_enabled == false) {
783    createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(bool)),2);
784  } else if (antialiasing_enabled == true) {
785    createRadioAction(antialiasingOn,antialiasingOff,SLOT(toggleAntialiasing(bool)),1);
786  } else {
787    mAntialiasing->clear();
788  }
789
790#if QT_VERSION < 0x040000
791  QPopupMenu *mHaloing = new QPopupMenu(mSpecial);
792  mSpecial->insertItem("Haloing",mHaloing);
793
794#if QT_VERSION < 0x030200
795  QAction *haloingOn = new QAction("&On","&On",CTRL+Key_O,mHaloing,0,true);
796  QAction *haloingOff = new QAction("&Off","&Off",CTRL+Key_F,mHaloing,0,true);
797#else
798  QAction *haloingOn = new QAction("&On",CTRL+Key_O,mHaloing);
799  QAction *haloingOff = new QAction("&Off",CTRL+Key_F,mHaloing);
800  haloingOn->setToggleAction(true);
801  haloingOff->setToggleAction(true);
802#endif
803  haloingOn->addTo(mHaloing);
804  haloingOff->addTo(mHaloing);
805#else
806  QMenu *mHaloing = mSpecial->addMenu("Haloing");
807  QAction *haloingOn = mHaloing->addAction("On");
808  QAction *haloingOff = mHaloing->addAction("Off");
809#endif
810  if (haloing_enabled == false) {
811    createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(bool)),2);
812  } else if (haloing_enabled == true) {
813    createRadioAction(haloingOn,haloingOff,SLOT(toggleHaloing(bool)),1);
814  } else {
815    mHaloing->clear();
816  }
817
818#if QT_VERSION < 0x040000
819  QPopupMenu *mAux = new QPopupMenu(mSpecial);
820  mSpecial->insertItem("Auxiliairy edges",mAux);
821
822#if QT_VERSION < 0x030200
823  QAction *auxOn = new QAction("&On","&On",CTRL+Key_O,mAux,0,true);
824  QAction *auxOff = new QAction("&Off","&Off",CTRL+Key_F,mAux,0,true);
825#else
826  QAction *auxOn = new QAction("&On",CTRL+Key_O,mAux);
827  QAction *auxOff = new QAction("&Off",CTRL+Key_F,mAux);
828  auxOn->setToggleAction(true);
829  auxOff->setToggleAction(true);
830#endif
831  auxOn->addTo(mAux);
832  auxOff->addTo(mAux);
833
834#else
835  QMenu *mAux = mSpecial->addMenu("Auxiliary edges");
836  QAction *auxOn = mAux->addAction("On");
837  QAction *auxOff = mAux->addAction("Off");
838#endif
839  if (!fVP.IsAuxEdgeVisible()) {
840    createRadioAction(auxOn,auxOff,SLOT(toggleAux(bool)),1);
841  } else {
842    createRadioAction(auxOn,auxOff,SLOT(toggleAux(bool)),2);
843  }
844
845
846
847#if QT_VERSION < 0x040000
848  QPopupMenu *mFullScreen = new QPopupMenu(mSpecial);
849  mSpecial->insertItem("Full screen",mFullScreen);
850
851#if QT_VERSION < 0x030200
852  fFullScreenOn = new QAction("&On","&On",CTRL+Key_O,mFullScreen,0,true);
853  fFullScreenOff = new QAction("&Off","&Off",CTRL+Key_F,mFullScreen,0,true);
854#else
855  fFullScreenOn = new QAction("&On",CTRL+Key_O,mFullScreen);
856  fFullScreenOff = new QAction("&Off",CTRL+Key_F,mFullScreen);
857  fFullScreenOn->setToggleAction(true);
858  fFullScreenOff->setToggleAction(true);
859#endif
860  fFullScreenOn->addTo(mFullScreen);
861  fFullScreenOff->addTo(mFullScreen);
862#else
863  QMenu *mFullScreen = mSpecial->addMenu("&Full screen");
864  fFullScreenOn = mFullScreen->addAction("On");
865  fFullScreenOff = mFullScreen->addAction("Off");
866#endif
867  createRadioAction(fFullScreenOn,fFullScreenOff,SLOT(toggleFullScreen(bool)),2);
868
869}
870
871void G4OpenGLQtViewer::manageContextMenuEvent(QContextMenuEvent *e)
872{
873  if (!GLWindow) {
874    G4cerr << "Visualization window not defined, please choose one before" << G4endl;
875  } else {
876 
877    if (!fContextMenu)
878      createPopupMenu();
879   
880    // launch menu
881    if ( fContextMenu ) {
882      fContextMenu->exec( e->globalPos() );
883      //    delete fContextMenu;
884    }
885  }
886  e->accept();
887}
888
889
890/**
891   Create a radio button menu. The two menu will be connected. When click on one,
892   eatch state will be invert and callback method will be called.
893   @param action1 first action to connect
894   @param action2 second action to connect
895   @param method callback method
896   @param nCheck: 1 : first action will be set true. 2 : second action will be set true
897*/
898#if QT_VERSION < 0x040000
899void G4OpenGLQtViewer::createRadioAction(QAction *action1,QAction *action2, const std::string& method,unsigned int nCheck) {
900
901  if (action1->parent()->inherits("QPopupMenu")){
902    ((QPopupMenu*)action1->parent())->setCheckable(true);
903    ((QPopupMenu*)action2->parent())->setCheckable(true);
904  }
905  action1->setOn(false);
906   action2->setOn(false);
907
908  if (nCheck ==1)
909    action1->setOn(true);
910  else
911    action2->setOn(true);
912   
913  //FIXME : Should not work on Qt3
914  QObject ::connect(action1, SIGNAL(activated()),action2, SLOT(toggle()));
915  QObject ::connect(action2, SIGNAL(activated()),action1, SLOT(toggle()));
916
917  QObject ::connect(action1, SIGNAL(toggled(bool)),this, method.c_str());
918}
919
920#else
921void G4OpenGLQtViewer::createRadioAction(QAction *action1,QAction *action2, const std::string& method,unsigned int nCheck) {
922
923  action1->setCheckable(true);
924  action2->setCheckable(true);
925
926  if (nCheck ==1)
927    action1->setChecked (true);
928  else
929    action2->setChecked (true);
930   
931  QObject ::connect(action1, SIGNAL(triggered(bool)),action2, SLOT(toggle()));
932  QObject ::connect(action2, SIGNAL(triggered(bool)),action1, SLOT(toggle()));
933
934  QObject ::connect(action1, SIGNAL(toggled(bool)),this, method.c_str());
935
936}
937#endif
938
939/**
940   Slot activate when mouseAction->rotate menu is set
941 */
942void G4OpenGLQtViewer::actionMouseRotate() {
943  emit toggleMouseAction(STYLE1);
944}
945
946
947/**
948   Slot activate when mouseAction->rotate menu is set
949 */
950void G4OpenGLQtViewer::actionMouseMove() {
951  emit toggleMouseAction(STYLE2);
952}
953
954
955/**
956   Slot activate when mouseAction->zoom menu is set
957 */
958void G4OpenGLQtViewer::actionMousePick() {
959#ifdef GEANT4_QT_DEBUG
960  printf("G4OpenGLQtViewer::actionMousePick \n");
961#endif
962  emit toggleMouseAction(STYLE3);
963}
964
965
966/**
967   Slot activate when drawing->wireframe menu is set
968 */
969void G4OpenGLQtViewer::actionDrawingWireframe() {
970  emit toggleDrawingAction(1);
971}
972
973/**
974   Slot activate when drawing->line removal menu is set
975 */
976void G4OpenGLQtViewer::actionDrawingLineRemoval() {
977  emit toggleDrawingAction(2);
978}
979
980/**
981   Slot activate when drawing->surface removal menu is set
982 */
983void G4OpenGLQtViewer::actionDrawingSurfaceRemoval() {
984  emit toggleDrawingAction(3);
985}
986
987/**
988   Slot activate when drawing->wireframe menu is set
989 */
990void G4OpenGLQtViewer::actionDrawingLineSurfaceRemoval() {
991  emit toggleDrawingAction(4);
992}
993
994
995/**
996   Slot activated when mouse action is toggle
997   @param aAction : STYLE1, STYLE2, STYLE3
998 */
999void G4OpenGLQtViewer::toggleMouseAction(mouseActions aAction) {
1000 
1001  if ((aAction == STYLE1) || //initialize all
1002      (aAction == STYLE2) ||
1003      (aAction == STYLE3))  {
1004#if QT_VERSION < 0x040000
1005    fRotateAction->setOn (false);
1006    fMoveAction->setOn (false);
1007    fPickAction->setOn (false);
1008#else
1009    fRotateAction->setChecked (false);
1010    fMoveAction->setChecked (false);
1011    fPickAction->setChecked (false);
1012#endif
1013    fVP.SetPicking(false);
1014    fMouseAction = aAction;
1015  }
1016  // rotate
1017  if (aAction == STYLE1) {  // rotate
1018    showShortcuts();
1019#if QT_VERSION < 0x040000
1020    fRotateAction->setOn (true);
1021#else
1022    fRotateAction->setChecked (true);
1023#endif
1024  } else  if (aAction == STYLE2) { //move
1025#if QT_VERSION < 0x040000
1026    fMoveAction->setOn (true);
1027#else
1028    fMoveAction->setChecked (true);
1029#endif
1030  } else  if (aAction == STYLE3) { //pick
1031#if QT_VERSION < 0x040000
1032    fPickAction->setOn (true);
1033#else
1034    fPickAction->setChecked (true);
1035#endif
1036    fVP.SetPicking(true);
1037  }
1038}
1039
1040/**
1041   Show shortcuts for this mouse action
1042 */
1043void G4OpenGLQtViewer::showShortcuts() {
1044  if (fMouseAction == STYLE1) {  // rotate
1045    G4cout << "Click and move mouse to rotate volume " << G4endl;
1046    G4cout << "Press left/right arrows to move volume left/right" << G4endl;
1047    G4cout << "Press up/down arrows to move volume up/down" << G4endl;
1048    G4cout << "Press ALT+up/down arrows to move volume toward/forward" << G4endl;
1049    G4cout << "Press SHIFT+left/right arrows to rotate volume left/right" << G4endl;
1050    G4cout << "Press SHIFT+up/down arrows to rotate volume up/down" << G4endl;
1051    G4cout << "Press ALT+/- to slow/speed auto rotation/move" << G4endl;
1052    G4cout << "In video mode : " << G4endl;
1053    G4cout << " Press SPACE to Start/Pause video recording " << G4endl;
1054    G4cout << " Press RETURN to Stop video recording " << G4endl;
1055  } else  if (fMouseAction == STYLE2) { //move
1056    G4cout << "Move camera point of view with mouse" << G4endl;
1057    G4cout << "Press left/right arrows to move volume left/right" << G4endl;
1058    G4cout << "Press up/down arrows to move volume up/down" << G4endl;
1059    G4cout << "Press ALT+up/down arrows to move volume toward/forward" << G4endl;
1060    G4cout << "Press SHIFT+left/right arrows to rotate volume left/right" << G4endl;
1061    G4cout << "Press SHIFT+up/down arrows to rotate volume up/down" << G4endl;
1062    G4cout << "Press +/- to zoom into volume" << G4endl;
1063    G4cout << "Press ALT+/- to slow/speed auto rotation/move" << G4endl;
1064    G4cout << "In video mode : " << G4endl;
1065    G4cout << " Press SPACE to Start/Pause video recording " << G4endl;
1066    G4cout << " Press RETURN to Stop video recording " << G4endl;
1067  } else  if (fMouseAction == STYLE3) { //pick
1068    G4cout << "Click and pick " << G4endl;
1069  }
1070
1071}
1072
1073
1074
1075/**
1076   Slot activated when drawing menu is toggle
1077   Warning : When G4OpenGLStoredQtViewer::DrawView() method call,
1078   KernelVisitDecision () will be call and will set the fNeedKernelVisit
1079   to 1. See G4XXXStoredViewer::CompareForKernelVisit for explanations.
1080   It will cause a redraw of the view
1081   @param aAction : 1 wireframe, 2 line removal, 3 surface removal, 4 line & surface removal
1082   @see G4OpenGLStoredQtViewer::DrawView
1083   @see G4XXXStoredViewer::CompareForKernelVisit
1084 */
1085void G4OpenGLQtViewer::toggleDrawingAction(int aAction) {
1086
1087  G4ViewParameters::DrawingStyle d_style;
1088 
1089
1090  // initialize
1091  if ((aAction >0) && (aAction <5)) {
1092#if QT_VERSION < 0x040000
1093    fDrawingWireframe->setOn(false);
1094    fDrawingLineRemoval->setOn(false);
1095    fDrawingSurfaceRemoval->setOn(false);
1096    fDrawingLineSurfaceRemoval->setOn(false);
1097#else
1098    fDrawingWireframe->setChecked (false);
1099    fDrawingLineRemoval->setChecked (false);
1100    fDrawingSurfaceRemoval->setChecked (false);
1101    fDrawingLineSurfaceRemoval->setChecked (false);
1102#endif
1103  }
1104  if (aAction ==1) {
1105#if QT_VERSION < 0x040000
1106    fDrawingWireframe->setOn(true);
1107#else
1108    fDrawingWireframe->setChecked (true);
1109#endif
1110
1111    d_style = G4ViewParameters::wireframe;
1112
1113  } else  if (aAction ==2) {
1114#if QT_VERSION < 0x040000
1115    fDrawingLineRemoval->setOn(true);
1116#else
1117    fDrawingLineRemoval->setChecked (true);
1118#endif
1119
1120    d_style = G4ViewParameters::hlr;
1121
1122  } else  if (aAction ==3) {
1123#if QT_VERSION < 0x040000
1124    fDrawingSurfaceRemoval->setOn(true);
1125#else
1126    fDrawingSurfaceRemoval->setChecked (true);
1127#endif
1128
1129    d_style = G4ViewParameters::hsr;
1130
1131  } else  if (aAction ==4) {
1132#if QT_VERSION < 0x040000
1133    fDrawingLineSurfaceRemoval->setOn(true);
1134#else
1135    fDrawingLineSurfaceRemoval->setChecked (true);
1136#endif
1137    d_style = G4ViewParameters::hlhsr;
1138  }
1139  fVP.SetDrawingStyle(d_style);
1140
1141  updateQWidget();
1142}
1143
1144
1145/**
1146   SLOT Activate by a click on the representation menu
1147   Warning : When G4OpenGLStoredQtViewer::DrawView() method call,
1148   KernelVisitDecision () will be call and will set the fNeedKernelVisit
1149   to 1. See G4XXXStoredViewer::CompareForKernelVisit for explanations.
1150   It will cause a redraw of the view
1151   @param check : 1 polyhedron, 0 nurbs
1152   @see G4OpenGLStoredQtViewer::DrawView
1153   @see G4XXXStoredViewer::CompareForKernelVisit
1154*/
1155void G4OpenGLQtViewer::toggleRepresentation(bool check) {
1156
1157  G4ViewParameters::RepStyle style;
1158  if (check == 1) {
1159    style = G4ViewParameters::polyhedron;
1160  } else {
1161    style = G4ViewParameters::nurbs;
1162  }
1163  fVP.SetRepStyle (style);
1164
1165  updateQWidget();
1166}
1167
1168/**
1169   SLOT Activate by a click on the projection menu
1170   Warning : When G4OpenGLStoredQtViewer::DrawView() method call,
1171   KernelVisitDecision () will be call and will set the fNeedKernelVisit
1172   to 1. See G4XXXStoredViewer::CompareForKernelVisit for explanations.
1173   It will cause a redraw of the view
1174   @param check : 1 orthographic, 2 perspective
1175   @see G4OpenGLStoredQtViewer::DrawView
1176   @see G4XXXStoredViewer::CompareForKernelVisit
1177*/
1178void G4OpenGLQtViewer::toggleProjection(bool check) {
1179
1180  if (check == 1) {
1181    fVP.SetFieldHalfAngle (0);
1182  } else {
1183
1184    // look for the default parameter hidden in G4UIcommand parameters
1185    G4UImanager* UI = G4UImanager::GetUIpointer();
1186    if(UI==NULL)
1187      return;
1188    G4UIcommandTree * treeTop = UI->GetTree();
1189
1190    // find command
1191    G4UIcommand* command = treeTop->FindPath("/vis/viewer/set/projection");
1192    if (!command)
1193      return;
1194
1195    // find param
1196    G4UIparameter * angleParam = NULL;
1197    for(G4int i=0;  i<command->GetParameterEntries(); i++)
1198    {
1199      if( command->GetParameter(i)->GetParameterName() == "field-half-angle" ) {
1200        angleParam = command->GetParameter(i);
1201      }
1202    }
1203    if (!angleParam)
1204      return;
1205
1206    // find unit
1207    G4UIparameter * unitParam = NULL;
1208    for(G4int i=0;  i<command->GetParameterEntries(); i++)
1209    {
1210      if( command->GetParameter(i)->GetParameterName() == "unit" ) {
1211        unitParam = command->GetParameter(i);
1212      }
1213    }
1214    if (!unitParam)
1215      return;
1216
1217    G4double defaultValue = command->ConvertToDouble(angleParam->GetDefaultValue())
1218                            * G4UnitDefinition::GetValueOf(unitParam->GetDefaultValue());
1219    if (defaultValue > 89.5 || defaultValue <= 0.0) {
1220      G4cerr << "Field half angle should be 0 < angle <= 89.5 degrees. Check your default Field half angle parameter";
1221    } else {
1222      G4cout << "Perspective view has been set to default value. Field half angle="<<angleParam->GetDefaultValue() <<" " << G4endl;
1223      fVP.SetFieldHalfAngle (defaultValue);
1224      SetView ();
1225    }
1226  } 
1227  updateQWidget();
1228}
1229
1230
1231/**
1232   SLOT Activate by a click on the background menu
1233@param check : 1 white, 0 black
1234*/
1235void G4OpenGLQtViewer::toggleBackground(bool check) {
1236
1237  //   //I need to revisit the kernel if the background colour changes and
1238  //   //hidden line removal is enabled, because hlr drawing utilises the
1239  //   //background colour in its drawing...
1240  //   // (Note added by JA 13/9/2005) Background now handled in view
1241  //   // parameters.  A kernel visit is triggered on change of background.
1242  if (check == 1) {
1243    ((G4ViewParameters&)this->GetViewParameters()).
1244      SetBackgroundColour(G4Colour(1.,1.,1.));  // White
1245  } else {
1246    ((G4ViewParameters&)this->GetViewParameters()).
1247      SetBackgroundColour(G4Colour(0.,0.,0.));  // Black
1248  }
1249  updateQWidget();
1250}
1251
1252/**
1253   SLOT Activate by a click on the transparency menu
1254@param check : 1 , 0
1255*/
1256void G4OpenGLQtViewer::toggleTransparency(bool check) {
1257 
1258  if (check) {
1259    transparency_enabled = false;
1260  } else {
1261    transparency_enabled = true;
1262  }
1263  SetNeedKernelVisit (true);
1264  updateQWidget();
1265}
1266
1267/**
1268   SLOT Activate by a click on the antialiasing menu
1269@param check : 1 , 0
1270*/
1271void G4OpenGLQtViewer::toggleAntialiasing(bool check) {
1272
1273  if (!check) {
1274    antialiasing_enabled = false;
1275    glDisable (GL_LINE_SMOOTH);
1276    glDisable (GL_POLYGON_SMOOTH);
1277  } else {
1278    antialiasing_enabled = true;
1279    glEnable (GL_LINE_SMOOTH);
1280    glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
1281    glEnable (GL_POLYGON_SMOOTH);
1282    glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST);
1283  }
1284
1285  updateQWidget();
1286}
1287
1288/**
1289   SLOT Activate by a click on the haloing menu
1290@param check : 1 , 0
1291*/
1292//FIXME : I SEE NOTHING...
1293void G4OpenGLQtViewer::toggleHaloing(bool check) {
1294  if (check) {
1295    haloing_enabled = false;
1296  } else {
1297    haloing_enabled = true;
1298  }
1299
1300  updateQWidget();
1301
1302}
1303
1304/**
1305   SLOT Activate by a click on the auxiliaire edges menu
1306@param check : 1 , 0
1307*/
1308void G4OpenGLQtViewer::toggleAux(bool check) {
1309  if (check) {
1310    fVP.SetAuxEdgeVisible(false);
1311  } else {
1312    fVP.SetAuxEdgeVisible(true);
1313  }
1314  SetNeedKernelVisit (true);
1315  updateQWidget();
1316
1317}
1318
1319/**
1320   SLOT Activate by a click on the full screen menu
1321*/
1322void G4OpenGLQtViewer::toggleFullScreen(bool check) {
1323  if (check != GLWindow->isFullScreen()) { //toggle
1324#if QT_VERSION >= 0x030200
1325    GLWindow->setWindowState(GLWindow->windowState() ^ Qt::WindowFullScreen);
1326#else
1327    G4cerr << "This version of Qt could not do fullScreen. Resizing the widget is the only solution available." << G4endl;
1328#endif
1329  }
1330}
1331
1332
1333void G4OpenGLQtViewer::savePPMToTemp() {
1334  if (fMovieTempFolderPath == "") {
1335    return;
1336  }
1337  QString fileName ="Test"+QString::number(fRecordFrameNumber)+".ppm";
1338  QString filePath =fMovieTempFolderPath+fileName;
1339
1340  QImage image;
1341  image = fWindow->grabFrameBuffer();
1342  bool res = false;
1343 
1344#if QT_VERSION < 0x040000
1345  res = image.save(filePath,"PPM");
1346#else
1347  res = image.save(filePath,0);
1348#endif
1349  if (res == false) {
1350    resetRecording();
1351    setRecordingInfos("Can't save tmp file "+filePath);
1352    return;
1353  }
1354 
1355  setRecordingInfos("File "+fileName+" saved");
1356  fRecordFrameNumber++;
1357}
1358
1359
1360
1361void G4OpenGLQtViewer::actionSaveImage() {
1362  QString filters;
1363#if QT_VERSION < 0x040000
1364  QStrList listFormat=QImageIO::outputFormats();
1365  char *tmp=listFormat.first();
1366  while (tmp!=0) {
1367    filters += QString(tmp) + ";;";
1368    tmp=listFormat.next();
1369  }
1370#else
1371  QList<QByteArray> formats =  QImageWriter::supportedImageFormats ();
1372  for (int i = 0; i < formats.size(); ++i) {
1373    filters +=formats.at(i) + ";;";
1374  }
1375#endif
1376  filters += "eps;;";
1377  filters += "ps;;";
1378  filters += "pdf";
1379  QString* selectedFormat = new QString();
1380#if QT_VERSION < 0x040000
1381  QString nomFich =  QFileDialog::getSaveFileName ( ".",
1382                                                    filters,
1383                                                    GLWindow,
1384                                                    "Save file dialog",
1385                                                    tr("Save as ..."),
1386                                                    selectedFormat );
1387#else
1388  QString nomFich =  QFileDialog::getSaveFileName ( GLWindow,
1389                                                    tr("Save as ..."),
1390                                                    ".",
1391                                                    filters,
1392                                                    selectedFormat );
1393#endif
1394  // bmp jpg jpeg png ppm xbm xpm
1395  if (nomFich == "") {
1396    return;
1397  }
1398#if QT_VERSION < 0x040000
1399  nomFich += "."+QString(selectedFormat->ascii());
1400  QString format = selectedFormat->lower();
1401#else
1402  nomFich += "."+QString(selectedFormat->toStdString().c_str());
1403  QString format = selectedFormat->toLower();
1404#endif
1405  G4OpenGLQtExportDialog* exportDialog= new G4OpenGLQtExportDialog(GLWindow,format,fWindow->height(),fWindow->width());
1406  if(  exportDialog->exec()) {
1407
1408    QImage image;
1409    bool res = false;
1410    if ((exportDialog->getWidth() !=fWindow->width()) ||
1411        (exportDialog->getHeight() !=fWindow->height())) {
1412      if (format != QString("eps")) {
1413      G4cerr << "Export->Change Size : This function is not implemented, to export in another size, please resize your frame to what you need" << G4endl;
1414     
1415      //    rescaleImage(exportDialog->getWidth(),exportDialog->getHeight());// re-scale image
1416      //      QGLWidget* glResized = fWindow;
1417
1418      // FIXME :
1419      // L.Garnier : I've try to implement change size function, but the problem is
1420      // the renderPixmap function call the QGLWidget to resize and it doesn't draw
1421      // the content of this widget... It only draw the background.
1422
1423      //      fWindow->renderPixmap (exportDialog->getWidth()*2,exportDialog->getHeight()*2,true );
1424
1425      //      QPixmap pixmap = fWindow->renderPixmap ();
1426     
1427      //      image = pixmap->toImage();
1428      //      glResized->resize(exportDialog->getWidth()*2,exportDialog->getHeight()*2);
1429      //      image = glResized->grabFrameBuffer();
1430      }     
1431    } else {
1432      image = fWindow->grabFrameBuffer();
1433    }   
1434    if (format == QString("eps")) {
1435      if (exportDialog->getVectorEPS()) {
1436        res = generateVectorEPS(nomFich,exportDialog->getWidth(),exportDialog->getHeight(),image);
1437      } else {
1438        res = generateEPS(nomFich,exportDialog->getNbColor(),image);
1439      }
1440    } else if ((format == "ps") || (format == "pdf")) {
1441      res = generatePS_PDF(nomFich,exportDialog->getNbColor(),image);
1442    } else if ((format == "tif") ||
1443               (format == "tiff") ||
1444               (format == "jpg") ||
1445               (format == "jpeg") ||
1446               (format == "png") ||
1447               (format == "pbm") ||
1448               (format == "pgm") ||
1449               (format == "ppm") ||
1450               (format == "bmp") ||
1451               (format == "xbm") ||
1452               (format == "xpm")) {
1453#if QT_VERSION < 0x040000
1454      res = image.save(nomFich,selectedFormat->ascii(),exportDialog->getSliderValue());
1455#else
1456      res = image.save(nomFich,0,exportDialog->getSliderValue());
1457#endif
1458    } else {
1459      G4cerr << "This version of G4UI Could not generate the selected format" << G4endl;
1460    }
1461    if (res == false) {
1462#if QT_VERSION < 0x040000
1463      G4cerr << "Error while saving file... "<<nomFich.ascii()<<"" << G4endl;
1464#else
1465      G4cerr << "Error while saving file... "<<nomFich.toStdString().c_str()<< G4endl;
1466#endif
1467    } else {
1468#if QT_VERSION < 0x040000
1469      G4cout << "File "<<nomFich.ascii()<<" has been saved " << G4endl;
1470#else
1471      G4cout << "File "<<nomFich.toStdString().c_str()<<" has been saved " << G4endl;
1472#endif
1473    }
1474   
1475  } else { // cancel selected
1476    return;
1477  }
1478 
1479#ifdef GEANT4_QT_DEBUG
1480  printf("G4OpenGLQtViewer::actionSaveImage() \n");
1481#endif
1482}
1483
1484
1485void G4OpenGLQtViewer::actionMovieParameters() {
1486
1487  showMovieParametersDialog();
1488#ifdef GEANT4_QT_DEBUG
1489  printf("G4OpenGLQtViewer::actionMovieParameters() \n");
1490#endif
1491}
1492
1493
1494void G4OpenGLQtViewer::showMovieParametersDialog() {
1495  if (!fMovieParametersDialog) {
1496    fMovieParametersDialog= new G4OpenGLQtMovieDialog(this,GLWindow);
1497    displayRecordingStatus();
1498    if (getEncoderPath() == "") {
1499      setRecordingInfos("mpeg_encode is needed to encode in video format. It is available here: http://bmrc.berkeley.edu/frame/research/mpeg/");
1500    }
1501  }
1502  fMovieParametersDialog->show();
1503}
1504
1505
1506/*
1507// http://www.google.com/codesearch?hl=en&q=+jpg+Qt+quality+QDialog+show:FZkUoth8oiw:TONpW2mR-_c:tyTfrKMO-xI&sa=N&cd=2&ct=rc&cs_p=http://soft.proindependent.com/src/qtiplot-0.8.9.zip&cs_f=qtiplot-0.8.9/qtiplot/src/application.cpp#a0
1508
1509void Graph::exportToSVG(const QString& fname)
1510{
1511  // enable workaround for Qt3 misalignments
1512  QwtPainter::setSVGMode(true);
1513  QPicture picture;
1514  QPainter p(&picture);
1515  d_plot->print(&p, d_plot->rect());
1516  p.end();
1517
1518  picture.save(fname, "svg");
1519}
1520*/
1521
1522
1523
1524
1525/**
1526   Save the current mouse press point
1527   @param p mouse click point
1528*/
1529#if QT_VERSION < 0x040000
1530void G4OpenGLQtViewer::G4MousePressEvent(QPoint p)
1531#else
1532void G4OpenGLQtViewer::G4MousePressEvent(QPoint p)
1533#endif
1534{
1535  fAutoMove = false; // stop automove
1536  fLastPos1 = p;
1537  fLastPos2 = fLastPos1;
1538  fLastPos3 = fLastPos2;
1539  fLastEventTime->start();
1540  if (fMouseAction == STYLE2){  // pick
1541    Pick(p.x(),p.y());
1542  }
1543}
1544
1545/**
1546*/
1547void G4OpenGLQtViewer::G4MouseReleaseEvent()
1548{
1549#ifdef GEANT4_QT_DEBUG
1550  printf("G4OpenGLQtViewer::mouseRealease() %d,%d  %d,%d  %d,%d\n",fLastPos1.x(),fLastPos1.y(),fLastPos2.x(),fLastPos2.y(),fLastPos3.x(),fLastPos3.y());
1551#endif
1552  fSpinningDelay = fLastEventTime->elapsed();
1553  QPoint delta = (fLastPos3-fLastPos1);
1554  if ((delta.x() == 0) && (delta.y() == 0)) {
1555#ifdef GEANT4_QT_DEBUG
1556  printf("G4OpenGLQtViewer::mouseRealease() EXIT 1 \n");
1557#endif
1558    return;
1559  }
1560  if (fSpinningDelay < fLaunchSpinDelay ) {
1561    fAutoMove = true;
1562    QTime lastMoveTime;
1563    lastMoveTime.start();
1564    // try to addapt speed move/rotate looking to drawing speed
1565    int cycles = 4;
1566    while (fAutoMove) {
1567      //      if ( lastMoveTime.elapsed() > (fSpinningDelay / (cycles/2))) {
1568        if (fMouseAction == STYLE1) {  // rotate
1569          rotateQtScene(((float)delta.x())/cycles,((float)delta.y())/cycles);
1570        } else if (fMouseAction == STYLE2) {  // move
1571          moveScene(-((float)delta.x())/cycles,-((float)delta.y())/cycles,0,true);
1572        }
1573        lastMoveTime.start();
1574        cycles = 1 ;
1575        //      }
1576      ((QApplication*)G4Qt::getInstance ())->processEvents();
1577#ifdef GEANT4_QT_DEBUG
1578        printf("G4OpenGLQtViewer::mouseRealease() cycle :%d \n",lastMoveTime.elapsed());
1579#endif
1580      cycles ++ ;
1581    }
1582  }
1583}
1584
1585
1586/**
1587   @param pos_x mouse x position
1588   @param pos_y mouse y position
1589   @param mButtons mouse button active
1590   @param mAutoMove true: apply this move till another evnt came, false :one time move
1591*/
1592
1593#if QT_VERSION < 0x040000
1594void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::ButtonState mButtons)
1595#else
1596  void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::MouseButtons mButtons)
1597#endif
1598{
1599
1600  if (fAutoMove) {
1601    return;
1602  }
1603
1604  fLastPos3 = fLastPos2;
1605  fLastPos2 = fLastPos1;
1606  fLastPos1 = QPoint(pos_x, pos_y);
1607
1608  int deltaX = fLastPos2.x()-fLastPos1.x();
1609  int deltaY = fLastPos2.y()-fLastPos1.y();
1610
1611  if (fMouseAction == STYLE1) {  // rotate
1612    if (mButtons & Qt::LeftButton) {
1613      rotateQtScene(deltaX,deltaY);
1614    }
1615  } else if (fMouseAction == STYLE2) {  // move
1616    if (mButtons & Qt::LeftButton) {
1617      moveScene(-deltaX,-deltaY,0,true);
1618    }
1619  }
1620
1621  fLastEventTime->start();
1622}
1623
1624
1625/**
1626   Move the scene of dx, dy, dz values.
1627   @param dx delta mouse x position
1628   @param dy delta mouse y position
1629   @param mouseMove : true if even comes from a mouse move, false if even comes from key action
1630*/
1631
1632void G4OpenGLQtViewer::moveScene(float dx,float dy, float dz,bool mouseMove)
1633{
1634  if (fHoldMoveEvent)
1635    return;
1636  fHoldMoveEvent = true;
1637
1638  G4double coefTrans = 0;
1639  GLdouble coefDepth = 0;
1640  if(mouseMove) {
1641    coefTrans = ((G4double)getSceneNearWidth())/((G4double)WinSize_x);
1642    if (WinSize_y <WinSize_x) {
1643      coefTrans = ((G4double)getSceneNearWidth())/((G4double)WinSize_y);
1644    }
1645  } else {
1646    coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1647    coefDepth = getSceneDepth()*fDeltaDepth;
1648  }
1649  fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1650 
1651  updateQWidget();
1652  if (fAutoMove)
1653    ((QApplication*)G4Qt::getInstance ())->processEvents();
1654 
1655  fHoldMoveEvent = false;
1656}
1657
1658
1659/**
1660   @param dx delta mouse x position
1661   @param dy delta mouse y position
1662*/
1663
1664void G4OpenGLQtViewer::rotateQtScene(float dx, float dy)
1665{
1666  if (fHoldRotateEvent)
1667    return;
1668  fHoldRotateEvent = true;
1669
1670  rotateSceneTest2(dx,dy,fDeltaRotation);
1671  //  rotateScene(dx,0,fDeltaRotation);
1672  //  rotateScene(0,dy,fDeltaRotation);
1673
1674  updateQWidget();
1675 
1676  fHoldRotateEvent = false;
1677}
1678
1679/**
1680   @param dx delta mouse x position
1681   @param dy delta mouse y position
1682*/
1683
1684void G4OpenGLQtViewer::rotateQtCamera(float dx, float dy)
1685{
1686  if (fHoldRotateEvent)
1687    return;
1688  fHoldRotateEvent = true;
1689
1690  rotateSceneTest2(dx,dy,fDeltaRotation);
1691  //  rotateScene(dx,dy,fDeltaRotation);
1692  updateQWidget();
1693 
1694  fHoldRotateEvent = false;
1695}
1696
1697
1698void G4OpenGLQtViewer::rotateSceneTest2(float dx, float dy,float deltaRot)
1699{
1700  fDeltaRotationAngleX = dx;
1701  fDeltaRotationAngleY = dy;
1702  //  rotateScene(dx,dy,fDeltaRotation);
1703
1704  const G4Point3D targetPoint
1705    = fSceneHandler.GetScene()->GetStandardTargetPoint()
1706    + fVP.GetCurrentTargetPoint ();
1707  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1708  if(radius<=0.) radius = 1.;
1709  const G4double cameraDistance = fVP.GetCameraDistance (radius);
1710  const G4Point3D cameraPosition =
1711    targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
1712  G4Vector3D up = fVP.GetUpVector ().unit ();
1713  G4Vector3D new_dx ;
1714  G4Vector3D new_cameraPosition ;
1715  G4Vector3D new_up ;
1716  G4Vector3D delta ;
1717
1718  if ((up[1]==1) &&(up[0]==0) && (up[2]==0)) {
1719    up[1] = cameraPosition[2];
1720  }
1721  new_dx[2] = (cameraPosition[0]*up[1]-cameraPosition[1]*up[0])/100; // EN TEST 
1722  new_dx[0] = (cameraPosition[1]*up[2]-cameraPosition[2]*up[1])/100;  // EN TEST
1723  new_dx[1] = (cameraPosition[2]*up[0]-cameraPosition[0]*up[2])/100;  // EN TEST
1724
1725  delta = new_dx*dx*deltaRot + up*dy*deltaRot;
1726  new_cameraPosition = cameraPosition + delta;
1727 
1728  new_up[2] = new_cameraPosition[0]*(-delta[1])-new_cameraPosition[1]*(-delta[0]);
1729  new_up[0] = new_cameraPosition[1]*(-delta[2])-new_cameraPosition[2]*(-delta[1]);
1730  new_up[1] = new_cameraPosition[2]*(-delta[0])-new_cameraPosition[0]*(-delta[2]);
1731
1732
1733#ifdef GEANT4_QT_DEBUG
1734  printf("G4OpenGLQtViewer::Rotate2 Tp %f,%f %f up:%f %f %f dx:%f %f %f\n",
1735         targetPoint[0],targetPoint[1],targetPoint[2],up[0],up[1],up[2],new_dx[0],new_dx[1],new_dx[2]);
1736  printf("G4OpenGLQtViewer::Rotate2 Cp %f,%f %f new_up:%f %f %f delta:%f %f %f\n",
1737         new_cameraPosition[0],new_cameraPosition[1],new_cameraPosition[2],new_up[0],new_up[1],new_up[2],delta[0],delta[1],delta[2]);
1738#endif
1739
1740  fVP.SetUpVector(new_up);
1741  fVP.SetViewAndLights (new_cameraPosition);
1742}
1743
1744void G4OpenGLQtViewer::rotateSceneTest(float dx, float dy,float delta)
1745{
1746  fDeltaRotationAngleX = dx;
1747  fDeltaRotationAngleY = dy;
1748
1749  float cox = std::cos ((fRotationAngleX*M_PI)/180);
1750  float coy = std::cos ((fRotationAngleY*M_PI)/180);
1751  float coz = 1;
1752  float six = std::sin ((fRotationAngleX*M_PI)/180);
1753  float siy = std::sin ((fRotationAngleY*M_PI)/180);
1754  float siz = 0;
1755
1756  float dx2 = coy*(siz*dy+coz*dx);
1757  float dy2 = six*(siy*(siz*dy+coz*dx))+cox*(coz*dy-siz*dx);
1758  float dz2 = cox*(siy*(siz*dy+coz*dx))-six*(coz*dy-siz*dx);
1759 
1760#ifdef GEANT4_QT_DEBUG
1761  printf("G4OpenGLQtViewer::MouseMove %f,%f Rot:%f,%f new : %f %f %f\n",dx,dy,fRotationAngleX,fRotationAngleY,dx2,dy2,dz2);
1762#endif
1763
1764  fDeltaRotationAngleX = dx2;
1765  fDeltaRotationAngleY = dy2;
1766  fDeltaRotationAngleZ = dz2;
1767
1768}
1769
1770void G4OpenGLQtViewer::rotateSceneInventor(float dx, float dy,float delta)
1771{
1772  // __________________________
1773  // From Inventor
1774  // --------------------------
1775  //SoGuiExaminerViewerP::rotateCamera(SoCamera * cam,
1776  //                                   const SbVec3f & aroundaxis,
1777  //                                   const float delta)
1778
1779  // position of camera
1780  /*
1781  const G4Point3D targetPoint
1782    = fSceneHandler.GetScene()->GetStandardTargetPoint()
1783    + fVP.GetCurrentTargetPoint ();
1784  G4double radius = fSceneHandler.GetScene()->GetExtent().GetExtentRadius();
1785  if(radius<=0.) radius = 1.;
1786  const G4double cameraDistance = fVP.GetCameraDistance (radius);
1787  const G4Point3D cameraPosition =
1788    targetPoint + cameraDistance * fVP.GetViewpointDirection().unit();
1789
1790  //
1791
1792  G4Point3D currentdir = fVP.GetViewpointDirection().unit();
1793
1794  const G4Point3D focalpoint = cameraPosition +
1795    cameraDistance * currentdir;
1796
1797  // set new orientation
1798  float rotation[4];
1799  float quatRotationX[4];
1800
1801  // from SbRotation::setValue(axis,radians)
1802  this->quatRotationX[3] = (float)cos(radians/2);
1803  const float sineval = (float)sin(radians/2);
1804  G4Point3D a = axis;
1805  // we test for a null vector above
1806  (void) a.normalize();
1807  this->quatRotationX[0] = a[0] * sineval;
1808  this->quatRotationX[1] = a[1] * sineval;
1809  this->quatRotationX[2] = a[2] * sineval;
1810 
1811  // from SbRotation operator *
1812currentdir
1813  float currentdir[0], currentdir[1], currentdir[2], currentdir[3];
1814  q.getValue(currentdir[0], currentdir[1], currentdir[2], currentdir[3]);
1815
1816  this->setValue(currentdir[3]*quatRotationX[0] + currentdir[0]*quatRotationX[3] + currentdir[1]*quatRotationX[2] - currentdir[2]*quatRotationX[1],
1817                 currentdir[3]*quatRotationX[1] - currentdir[0]*quatRotationX[2] + currentdir[1]*quatRotationX[3] + currentdir[2]*quatRotationX[0],
1818                 currentdir[3]*quatRotationX[2] + currentdir[0]*quatRotationX[1] - currentdir[1]*quatRotationX[0] + currentdir[2]*quatRotationX[3],
1819                 currentdir[3]*quatRotationX[3] - currentdir[0]*quatRotationX[0] - currentdir[1]*quatRotationX[1] - currentdir[2]*quatRotationX[2]);
1820
1821
1822  //  cam->orientation = SbRotation(aroundaxis, delta) * currentorientation;
1823
1824  SbVec3f newdir;
1825  cam->orientation.getValue().multVec(DEFAULTDIRECTION, newdir);
1826  cam->position = focalpoint - cam->focalDistance.getValue() * newdir;
1827
1828  // __________________________
1829  // END From Inventor
1830  // --------------------------
1831  */
1832}
1833
1834/*
1835float[4] G4OpenGLQtViewer::makeRotationMatrix(const G4Point3D axis, const float radians)
1836{
1837  float res[4];
1838  // From <http://www.automation.hut.fi/~jaro/thesis/hyper/node9.html>.
1839
1840  res[3] = (float)cos(radians/2);
1841
1842  const float sineval = (float)sin(radians/2);
1843  SbVec3f a = axis;
1844  // we test for a null vector above
1845  (void) a.normalize();
1846  res[0] = a[0] * sineval;
1847  res[1] = a[1] * sineval;
1848  res[2] = a[2] * sineval;
1849
1850}
1851  */
1852
1853/** This is the benning of a rescale function. It does nothing for the moment
1854    @param aWidth : new width
1855    @param aHeight : new height
1856*/
1857void G4OpenGLQtViewer::rescaleImage(
1858 int aWidth
1859,int aHeight
1860){
1861#ifdef GEANT4_QT_DEBUG
1862  printf("should rescale \n");
1863#endif
1864  GLfloat* feedback_buffer;
1865  GLint returned;
1866  FILE* file;
1867 
1868//   feedback_buffer = new GLfloat[size];
1869//   glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1870//   glRenderMode (GL_FEEDBACK);
1871 
1872//   glViewport (0, 0, aWidth, aHeight);
1873//   DrawView();
1874//   returned = glRenderMode (GL_RENDER);
1875
1876}
1877
1878/**
1879   Generate Vectorial Encapsulated Postscript form image
1880   @param aFilename : name of file
1881   @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1882   @param aImage : Image to print
1883*/
1884bool G4OpenGLQtViewer::generateVectorEPS (
1885 QString aFilename
1886,int aWidth
1887,int aHeight
1888,QImage aImage
1889)
1890{
1891  // Print vectored PostScript
1892 
1893  G4int size = 5000000;
1894
1895  GLfloat* feedback_buffer;
1896  GLint returned;
1897  FILE* file;
1898 
1899  feedback_buffer = new GLfloat[size];
1900  glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1901  glRenderMode (GL_FEEDBACK);
1902 
1903  int side = aWidth;
1904  if (aHeight < aWidth) side = aHeight;
1905  glViewport((aWidth - side) / 2, (aHeight - side) / 2, side, side);
1906  DrawView();
1907
1908  returned = glRenderMode (GL_RENDER);
1909 
1910 
1911#if QT_VERSION < 0x040000
1912  file = fopen (aFilename.ascii(), "w");
1913#else
1914  file = fopen (aFilename.toStdString().c_str(), "w");
1915#endif
1916  if (file) {
1917    spewWireframeEPS (file, returned, feedback_buffer, "rendereps");
1918  } else {
1919#if QT_VERSION < 0x040000
1920    G4cerr << "Could not open "<< aFilename.ascii() << G4endl;
1921#else
1922    G4cerr << "Could not open "<< aFilename.toStdString().c_str() << G4endl;
1923#endif
1924  }
1925 
1926  delete[] feedback_buffer;
1927
1928  return true;
1929}
1930
1931/**
1932   Generate Encapsulated Postscript form image
1933   @param aFilename : name of file
1934   @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1935   @param aImage : Image to print
1936*/
1937bool G4OpenGLQtViewer::generateEPS (
1938 QString aFilename
1939,int aInColor
1940,QImage aImage
1941)
1942{
1943  // FIXME
1944#ifdef GEANT4_QT_DEBUG
1945  printf("saving EPS\n");
1946#endif
1947
1948  FILE* fp;
1949
1950  if (aImage.bits () == NULL)
1951    return false;
1952 
1953#if QT_VERSION < 0x040000
1954  fp = fopen (aFilename.ascii(), "w");
1955#else
1956  fp = fopen (aFilename.toStdString().c_str(), "w");
1957#endif
1958  if (fp == NULL) {
1959    return false;
1960  }
1961 
1962  fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
1963#if QT_VERSION < 0x040000
1964  fprintf (fp, "%%%%Title: %s\n", aFilename.ascii());
1965#else
1966  fprintf (fp, "%%%%Title: %s\n", aFilename.toStdString().c_str());
1967#endif
1968  fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
1969  fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", aImage.width(), aImage.height());
1970  fprintf (fp, "%%%%EndComments\n");
1971  fprintf (fp, "gsave\n");
1972  fprintf (fp, "/bwproc {\n");
1973  fprintf (fp, "    rgbproc\n");
1974  fprintf (fp, "    dup length 3 idiv string 0 3 0 \n");
1975  fprintf (fp, "    5 -1 roll {\n");
1976  fprintf (fp, "    add 2 1 roll 1 sub dup 0 eq\n");
1977  fprintf (fp, "    { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
1978  fprintf (fp, "       3 1 roll 5 -1 roll } put 1 add 3 0 \n");
1979  fprintf (fp, "    { 2 1 roll } ifelse\n");
1980  fprintf (fp, "    }forall\n");
1981  fprintf (fp, "    pop pop pop\n");
1982  fprintf (fp, "} def\n");
1983  fprintf (fp, "systemdict /colorimage known not {\n");
1984  fprintf (fp, "   /colorimage {\n");
1985  fprintf (fp, "       pop\n");
1986  fprintf (fp, "       pop\n");
1987  fprintf (fp, "       /rgbproc exch def\n");
1988  fprintf (fp, "       { bwproc } image\n");
1989  fprintf (fp, "   }  def\n");
1990  fprintf (fp, "} if\n");
1991  fprintf (fp, "/picstr %d string def\n", aImage.width() * aInColor);
1992  fprintf (fp, "%d %d scale\n", aImage.width(), aImage.height());
1993  fprintf (fp, "%d %d %d\n", aImage.width(), aImage.height(), 8);
1994  fprintf (fp, "[%d 0 0 %d 0 0]\n", aImage.width(), aImage.height());
1995  fprintf (fp, "{currentfile picstr readhexstring pop}\n");
1996  fprintf (fp, "false %d\n", aInColor);
1997  fprintf (fp, "colorimage\n");
1998 
1999
2000  int width = aImage.width();
2001  int height = aImage.height();
2002  int depth = aImage.depth();
2003  int size = width*height;
2004 
2005  if (depth == 1)
2006    size = (width+7)/8*height;
2007  else if (aInColor == 1)
2008    size = size*3;
2009 
2010  int i = 0;
2011  //  if ( aInColor ==1 ) {
2012  // FIXME : L. Garnier. For the moment 10 dec 2007, I could not find a way
2013  // to save correctly grayscale Image. I mean that color or grayscale image
2014  // have the same file save size !
2015 
2016  /* } else*/ if (depth == 8) {
2017    for(int y=height-1; y >=0 ; y--) {
2018      const uchar * s = aImage.scanLine(y);
2019      for(int x=0; x <width; x++) {
2020        QRgb rgb = aImage.color(s[x]);
2021        if (aInColor == 1) {
2022          fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
2023          i++;
2024        } else {
2025          fprintf (fp, " %02hx %02hx %02hx",
2026                   (unsigned char) qRed(rgb),
2027                   (unsigned char) qGreen(rgb),
2028                   (unsigned char) qBlue(rgb));
2029          i += 3;
2030        }
2031      }
2032      fprintf (fp, "\n");
2033    }
2034  } else {
2035#if QT_VERSION < 0x040000
2036    bool alpha = aImage.hasAlphaBuffer();
2037#else
2038    bool alpha = aImage.hasAlphaChannel();
2039    for(int y=height-1; y >=0 ; y--) {
2040      QRgb * s = (QRgb*)(aImage.scanLine(y));
2041      for(int x=0; x <width; x++) {
2042        QRgb rgb = (*s++);
2043        if (alpha && qAlpha(rgb) < 0x40) // 25% alpha, convert to white -
2044          rgb = qRgb(0xff, 0xff, 0xff);
2045        if (aInColor == 1) {
2046          fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
2047          i++;
2048        } else {
2049          fprintf (fp, " %02hx %02hx %02hx",
2050                   (unsigned char) qRed(rgb),
2051                   (unsigned char) qGreen(rgb),
2052                   (unsigned char) qBlue(rgb));
2053          i += 3;
2054        }
2055      }
2056      fprintf (fp, "\n");
2057    }
2058#endif
2059
2060  }
2061
2062  fprintf (fp, "grestore\n");
2063  fprintf (fp, "showpage\n");
2064  fclose (fp);
2065
2066  return true;
2067}
2068/**
2069   Generate Postscript or PDF form image
2070   @param aFilename : name of file
2071   @param aInColor : numbers of colors : 1->BW 2->RGB
2072   @param aImage : Image to print
2073*/
2074bool G4OpenGLQtViewer::generatePS_PDF (
2075 QString aFilename
2076,int aInColor
2077,QImage aImage
2078)
2079{
2080
2081#if QT_VERSION < 0x040000
2082#ifdef Q_WS_MAC || Q_WS_X11
2083  QPrinter printer;
2084  //  printer.setPageSize(pageSize);
2085  if (aInColor == 1) {
2086    printer.setColorMode(QPrinter::GrayScale);
2087  } else {
2088    printer.setColorMode(QPrinter::Color);
2089  }
2090
2091  /* FIXME : I don't know which format it will save...
2092     if (aFilename.endsWith(".ps")) {
2093     printer.setOutputFormat(QPrinter::PostScriptFormat);
2094     } else {
2095     printer.setOutputFormat(QPrinter::PdfFormat);
2096     }
2097  */
2098  printer.setOutputFileName(aFilename);
2099  //  printer.setFullPage ( true);
2100  QPainter paint(&printer);
2101  paint.drawImage (0,0,aImage );
2102  paint.end();
2103#else
2104  G4cerr << "This fonction is only supported on Mac OsX or X11 with Qt3. Full platform supported with Qt4" << G4endl;
2105#endif
2106#else
2107  QPrinter printer;
2108  //  printer.setPageSize(pageSize);
2109
2110  // FIXME : L. Garnier 4/12/07
2111  // This is not working, it does nothing. Image is staying in color mode
2112  // So I have desactivate the B/W button in GUI
2113  if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
2114#if QT_VERSION < 0x040000
2115    aImage = aImage.convertDepth(1,Qt::MonoOnly);
2116#else
2117    aImage = aImage.convertToFormat ( aImage.format(), Qt::MonoOnly);
2118#endif
2119  }
2120
2121
2122  if (aFilename.endsWith(".ps")) {
2123#if QT_VERSION > 0x040200
2124    printer.setOutputFormat(QPrinter::PostScriptFormat);
2125#endif
2126  } else {
2127#if QT_VERSION > 0x040100
2128    printer.setOutputFormat(QPrinter::PdfFormat);
2129#endif
2130  }
2131#if QT_VERSION > 0x040100
2132  printer.setOutputFileName(aFilename);
2133#endif
2134  //  printer.setFullPage ( true);
2135  QPainter paint(&printer);
2136  paint.drawImage (0,0,aImage);
2137  paint.end();
2138#endif
2139  return true;
2140}
2141
2142
2143
2144void G4OpenGLQtViewer::G4keyPressEvent (QKeyEvent * event)
2145{
2146  if (fHoldKeyEvent)
2147    return;
2148
2149  fHoldKeyEvent = true;
2150
2151#if QT_VERSION < 0x040000
2152  if ((event->key() == Qt::Key_Down) && (event->state() & Qt::AltButton )) { // go backward
2153#else
2154  if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::AltModifier )) { // go backward
2155#endif
2156   
2157    moveScene(0,0,1,false);
2158  }
2159#if QT_VERSION < 0x040000
2160  else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::AltButton)) { // go forward
2161#else
2162  else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::AltModifier)) { // go forward
2163#endif
2164    moveScene(0,0,-1,false);
2165  }
2166#if QT_VERSION < 0x040000
2167  if ((event->key() == Qt::Key_Down) && (event->state() & Qt::ShiftButton)) { // rotate phi
2168#else
2169  if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
2170#endif
2171    rotateQtCamera(0,-1);
2172  }
2173#if QT_VERSION < 0x040000
2174  else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::ShiftButton)) { // rotate phi
2175#else
2176  else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
2177#endif
2178    rotateQtCamera(0,1);
2179  }
2180#if QT_VERSION < 0x040000
2181  if ((event->key() == Qt::Key_Left) && (event->state() & Qt::ShiftButton)) { // rotate theta
2182#else
2183  if ((event->key() == Qt::Key_Left) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
2184#endif
2185    rotateQtCamera(1,0);
2186  }
2187#if QT_VERSION < 0x040000
2188  else if ((event->key() == Qt::Key_Right) && (event->state() & Qt::ShiftButton)) { // rotate theta
2189#else
2190  else if ((event->key() == Qt::Key_Right) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
2191#endif
2192    rotateQtCamera(-1,0);
2193  }
2194
2195#if QT_VERSION < 0x040000
2196  if ((event->state() & Qt::AltButton)) {
2197#else
2198  if ((event->modifiers() & Qt::AltModifier)) {
2199#endif
2200    if (event->key() == Qt::Key_Plus) {
2201      fDeltaRotation = fDeltaRotation/0.7;
2202    }
2203    else if (event->key() == Qt::Key_Minus) {
2204      fDeltaRotation = fDeltaRotation*0.7;
2205    }
2206  } else {
2207    if (event->key() == Qt::Key_Plus) {
2208      fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
2209      updateQWidget();
2210    }
2211    else if (event->key() == Qt::Key_Minus) {
2212      fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
2213      updateQWidget();
2214    }
2215  }
2216 
2217 
2218  if (event->key() == Qt::Key_Escape) { // escaped from full screen
2219#if QT_VERSION >= 0x030200
2220      toggleFullScreen(false);
2221#endif
2222  }
2223  // several case here : If return is pressed, in every case -> display the movie parameters dialog
2224  // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
2225  // If encoder not found-> does nothing.Only display a message in status box
2226  // If all ok-> generate parameter file
2227  // If ok -> put encoder button enabled
2228 
2229  if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)){ // end of video
2230   stopVideo();
2231  }
2232  if (event->key() == Qt::Key_Space){ // start/pause of video
2233   startPauseVideo();
2234  }
2235
2236  // with no modifiers
2237#if QT_VERSION < 0x040000
2238  if (event->state() == Qt::NoButton) {
2239#else
2240  if ((event->modifiers() == Qt::NoModifier) || (event->modifiers() == Qt::KeypadModifier )) {
2241#endif
2242    if (event->key() == Qt::Key_Down) { // go down
2243      moveScene(0,1,0,false);
2244    }
2245    else if (event->key() == Qt::Key_Up) {  // go up
2246      moveScene(0,-1,0,false);
2247    }
2248    if (event->key() == Qt::Key_Left) { // go left
2249      moveScene(-1,0,0,false);
2250    }
2251    else if (event->key() == Qt::Key_Right) { // go right
2252      moveScene(1,0,0,false);
2253    }
2254  }
2255  fHoldKeyEvent = false;
2256}
2257 
2258
2259/** Stop the video. Check all parameters and enable encoder button if all is ok.
2260*/
2261void G4OpenGLQtViewer::stopVideo() {
2262
2263 // if encoder parameter is wrong, display parameters dialog and return
2264  if (!fMovieParametersDialog) {
2265    showMovieParametersDialog();
2266  }
2267  setRecordingStatus(STOP);
2268
2269  if (fRecordFrameNumber >0) {
2270    // check parameters if they were modified (Re APPLY them...)
2271    // It will enable/disable encode button
2272    fMovieParametersDialog->checkAllParameters();
2273  } else {
2274    resetRecording();
2275    setRecordingInfos("No frame to encode.");
2276  }
2277}
2278
2279
2280/** Start/Pause the video..
2281*/
2282void G4OpenGLQtViewer::startPauseVideo() {
2283   
2284  // first time, if temp parameter is wrong, display parameters dialog and return
2285  if ( fRecordingStep == WAIT) {
2286    if ( fRecordFrameNumber == 0) {
2287      if (getTempFolderPath() == "") {
2288        showMovieParametersDialog();
2289        setRecordingInfos("You should specified the temp folder in order to make movie");
2290        return;
2291      } else  {
2292        // remove temp folder if it was create
2293        QString tmp = removeTempFolder();
2294        if (tmp !="") {
2295          setRecordingInfos(tmp);
2296          return;
2297        }
2298        tmp = createTempFolder();
2299        if (tmp != "") {
2300          setRecordingInfos("Can't create temp folder."+tmp);
2301          return;
2302        }
2303      }
2304    }
2305  }
2306  if (fRecordingStep == WAIT) {
2307    setRecordingStatus(START);
2308  } else if (fRecordingStep == START) {
2309    setRecordingStatus(PAUSE);
2310  } else if (fRecordingStep == PAUSE) {
2311    setRecordingStatus(CONTINUE);
2312  } else if (fRecordingStep == CONTINUE) {
2313    setRecordingStatus(PAUSE);
2314  }
2315}
2316
2317
2318void G4OpenGLQtViewer::setRecordingStatus(RECORDING_STEP step) {
2319
2320  fRecordingStep = step;
2321  displayRecordingStatus();
2322}
2323
2324
2325void G4OpenGLQtViewer::displayRecordingStatus() {
2326 
2327  QString txt = "";
2328  if (fRecordingStep == WAIT) {
2329    txt  = "Waiting to start...";
2330    fRecordFrameNumber = 0; // reset the frame number
2331  } else if (fRecordingStep == START) {
2332    txt  = "Start Recording...";
2333  } else if (fRecordingStep == PAUSE) {
2334    txt  = "Pause Recording...";
2335  } else if (fRecordingStep == CONTINUE) {
2336    txt  = "Continue Recording...";
2337  } else if (fRecordingStep == STOP) {
2338    txt  = "Stop Recording...";
2339  } else if (fRecordingStep == READY_TO_ENCODE) {
2340    txt  = "Ready to Encode...";
2341  } else if (fRecordingStep == ENCODING) {
2342    txt  = "Encoding...";
2343  } else if (fRecordingStep == FAILED) {
2344    txt  = "Failed to encode...";
2345  } else if (fRecordingStep == SUCCESS) {
2346    txt  = "File encoded successfully";
2347  } else {
2348  }
2349
2350  if (fMovieParametersDialog) {
2351    fMovieParametersDialog->setRecordingStatus(txt);
2352  } else {
2353#if QT_VERSION < 0x040000
2354    G4cout << txt.ascii() << G4endl;
2355#else
2356    G4cout << txt.toStdString().c_str() << G4endl;
2357#endif
2358  }
2359  setRecordingInfos("");
2360}
2361
2362
2363void G4OpenGLQtViewer::setRecordingInfos(QString txt) {
2364  if (fMovieParametersDialog) {
2365    fMovieParametersDialog->setRecordingInfos(txt);
2366  } else {
2367#if QT_VERSION < 0x040000
2368    G4cout << txt.ascii() << G4endl;
2369#else
2370    G4cout << txt.toStdString().c_str() << G4endl;
2371#endif
2372  }
2373}
2374
2375/** Init the movie parameters. Temp dir and encoder path
2376*/
2377void G4OpenGLQtViewer::initMovieParameters() {
2378  //init encoder
2379 
2380   //look for encoderPath
2381     fProcess = new QProcess();
2382     
2383#if QT_VERSION < 0x040000
2384     QObject ::connect(fProcess,SIGNAL(processExited ()),
2385                       this,SLOT(processLookForFinished()));
2386     fProcess->setCommunication(QProcess::DupStderr);
2387     fProcess->setArguments(QStringList("which mpeg_encode"));
2388     fProcess->start();
2389#else
2390     QObject ::connect(fProcess,SIGNAL(finished ( int)),
2391                       this,SLOT(processLookForFinished()));
2392     fProcess->setReadChannelMode(QProcess::MergedChannels);
2393     fProcess->start ("which mpeg_encode");
2394#endif
2395 
2396}
2397
2398/** @return encoder path or "" if it does not exist
2399 */
2400QString G4OpenGLQtViewer::getEncoderPath() {
2401  return fEncoderPath;
2402}
2403 
2404
2405/**
2406 * set the new encoder path
2407 * @return "" if correct. The error otherwise
2408*/
2409QString G4OpenGLQtViewer::setEncoderPath(QString path) {
2410  if (path == "") {
2411    return "File does not exist";
2412  }
2413
2414#if QT_VERSION < 0x040000
2415  path =  QDir::cleanDirPath(path);
2416#else
2417  path =  QDir::cleanPath(path);
2418#endif
2419  QFileInfo *f = new QFileInfo(path);
2420  if (!f->exists()) {
2421    return "File does not exist";
2422  } else if (f->isDir()) {
2423    return "This is a directory";
2424  } else if (!f->isExecutable()) {
2425    return "File exist but is not executable";
2426  } else if (!f->isFile()) {
2427    return "This is not a file";
2428  }
2429  fEncoderPath = path;
2430  return "";
2431}
2432
2433
2434bool G4OpenGLQtViewer::isRecording(){
2435  if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
2436    return true;
2437  }
2438  return false;
2439}
2440
2441bool G4OpenGLQtViewer::isStopped(){
2442  if (fRecordingStep == STOP) {
2443    return true;
2444  }
2445  return false;
2446}
2447
2448
2449bool G4OpenGLQtViewer::isReadyToEncode(){
2450  if (fRecordingStep == READY_TO_ENCODE) {
2451    return true;
2452  }
2453  return false;
2454}
2455
2456void G4OpenGLQtViewer::resetRecording() {
2457    setRecordingStatus(WAIT);
2458}
2459
2460/**
2461 * set the temp folder path
2462 * @return "" if correct. The error otherwise
2463*/
2464QString G4OpenGLQtViewer::setTempFolderPath(QString path) {
2465
2466  if (path == "") {
2467    return "Path does not exist";
2468  }
2469#if QT_VERSION < 0x040000
2470  path =  QDir::cleanDirPath(path);
2471#else
2472  path =  QDir::cleanPath(path);
2473#endif
2474  QFileInfo *d = new QFileInfo(path);
2475  if (!d->exists()) {
2476    return "Path does not exist";
2477  } else if (!d->isDir()) {
2478    return "This is not a directory";
2479  } else if (!d->isReadable()) {
2480    return path +" is read protected";
2481  } else if (!d->isWritable()) {
2482    return path +" is write protected";
2483  }
2484 
2485  fTempFolderPath = path;
2486  return "";
2487}
2488
2489/** @return the temp folder path or "" if it does not exist
2490 */
2491QString G4OpenGLQtViewer::getTempFolderPath() {
2492  return fTempFolderPath;
2493}
2494 
2495/**
2496 * set the save file name path
2497 * @return "" if correct. The error otherwise
2498*/
2499QString G4OpenGLQtViewer::setSaveFileName(QString path) {
2500
2501  if (path == "") {
2502    return "Path does not exist";
2503  }
2504 
2505  QFileInfo *file = new QFileInfo(path);
2506  QDir dir = file->dir();
2507#if QT_VERSION < 0x040000
2508  path =  QDir::cleanDirPath(path);
2509#else
2510  path =  QDir::cleanPath(path);
2511#endif
2512  if (file->exists()) {
2513    return "File already exist, please choose a new one";
2514  } else if (!dir.exists()) {
2515    return "Dir does not exist";
2516  } else if (!dir.isReadable()) {
2517    return path +" is read protected";
2518  }
2519 
2520  fSaveFileName = path;
2521  return "";
2522}
2523
2524/** @return the save file path
2525 */
2526QString G4OpenGLQtViewer::getSaveFileName() {
2527  return fSaveFileName ;
2528}
2529
2530/** Create a Qt_temp folder in the temp folder given
2531* The temp folder will be like this /tmp/QtMovie_12-02-2008_12_12_58/
2532* @return "" if success. Error message if not.
2533*/
2534QString G4OpenGLQtViewer::createTempFolder() {
2535  fMovieTempFolderPath = "";
2536
2537  //check
2538  QString tmp = setTempFolderPath(fTempFolderPath);
2539  if (tmp != "") {
2540    return tmp;
2541  }
2542#if QT_VERSION < 0x040000
2543  QString sep = QChar(QDir::separator());
2544#else
2545  QString sep = QString(QDir::separator());
2546#endif
2547  QString path = sep+"QtMovie_"+QDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+sep;
2548#if QT_VERSION < 0x040000
2549  QDir *d = new QDir(QDir::cleanDirPath(fTempFolderPath));
2550#else
2551  QDir *d = new QDir(QDir::cleanPath(fTempFolderPath));
2552#endif
2553  // check if it is already present
2554  if (d->exists(path)) {
2555    return "Folder "+path+" already exists.Please remove it first";
2556  }
2557  if (d->mkdir(fTempFolderPath+path)) {
2558    fMovieTempFolderPath = fTempFolderPath+path;
2559    return "";
2560  } else {
2561    return "Can't create "+fTempFolderPath+path;
2562  }
2563  return "-";
2564}
2565
2566/** Remove the Qt_temp folder in the temp folder
2567*/
2568QString G4OpenGLQtViewer::removeTempFolder() {
2569        // remove files in Qt_temp folder
2570  if (fMovieTempFolderPath == "") {
2571    return "";
2572  }
2573#if QT_VERSION < 0x040000
2574  QDir *d = new QDir(QDir::cleanDirPath(fMovieTempFolderPath));
2575#else
2576  QDir *d = new QDir(QDir::cleanPath(fMovieTempFolderPath));
2577#endif
2578  if (!d->exists()) {
2579    return "";  // already remove
2580  }
2581
2582  d->setFilter( QDir::Files );
2583  QStringList subDirList = d->entryList();
2584  int res = true;
2585  QString error = "";
2586  for (QStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
2587    const QString currentFile = *it;
2588      if (!d->remove(currentFile)) {
2589        res = false;
2590        QString file = fMovieTempFolderPath+currentFile;
2591        error +="Removing file failed : "+file;
2592      } else {
2593      }
2594  }
2595  if (res) {
2596    if (d->rmdir(fMovieTempFolderPath)) {
2597      fMovieTempFolderPath = "";
2598      return "";
2599    } else {
2600      return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
2601    }
2602
2603  }
2604  return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
2605}
2606
2607
2608
2609bool G4OpenGLQtViewer::hasPendingEvents () {
2610  return ((QApplication*)G4Qt::getInstance ())->hasPendingEvents ();
2611}
2612
2613bool G4OpenGLQtViewer::generateMpegEncoderParameters () {
2614
2615                // save the parameter file
2616  FILE* fp;
2617#if QT_VERSION < 0x040000
2618  fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).ascii(), "w");
2619#else
2620  fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).toStdString().c_str(), "w");
2621#endif
2622
2623  if (fp == NULL) {
2624    setRecordingInfos("Generation of parameter file failed");
2625    return false;
2626  }
2627
2628  fprintf (fp,"# parameter file template with lots of comments to assist you\n");
2629  fprintf (fp,"#\n");
2630  fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
2631  fprintf (fp,"# the copy\n");
2632  fprintf (fp,"#\n");
2633  fprintf (fp,"#\n");
2634  fprintf (fp,"# any line beginning with '#' is a comment\n");
2635  fprintf (fp,"#\n");
2636  fprintf (fp,"# no line should be longer than 255 characters\n");
2637  fprintf (fp,"#\n");
2638  fprintf (fp,"#\n");
2639  fprintf (fp,"# general format of each line is:\n");
2640  fprintf (fp,"#          \n");
2641  fprintf (fp,"#\n");
2642  fprintf (fp,"# lines can generally be in any order\n");
2643  fprintf (fp,"#\n");
2644  fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
2645  fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
2646  fprintf (fp,"#\n");
2647  fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
2648  fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
2649  fprintf (fp,"# the INPUT parameter.\n");
2650  fprintf (fp,"#\n");
2651  fprintf (fp,"#  MUST be in UPPER CASE\n");
2652  fprintf (fp,"#\n");
2653  fprintf (fp,"\n");
2654  fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
2655  fprintf (fp,"# for more info.\n");
2656  fprintf (fp,"\n");
2657  fprintf (fp,"PATTERN          IBBPBBPBBPBBPBBP\n");
2658#if QT_VERSION < 0x040000
2659  fprintf (fp,"OUTPUT           %s\n",getSaveFileName().ascii());
2660#else
2661  fprintf (fp,"OUTPUT           %s\n",getSaveFileName().toStdString().c_str());
2662#endif
2663  fprintf (fp,"\n");
2664  fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
2665  fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
2666  fprintf (fp,"#\n");
2667  fprintf (fp,"# You must specify the type of the input files.  The choices are:\n");
2668  fprintf (fp,"#    YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
2669  fprintf (fp,"#        (must be upper case)\n");
2670  fprintf (fp,"#\n");
2671  fprintf (fp,"BASE_FILE_FORMAT PPM\n");
2672  fprintf (fp,"\n");
2673  fprintf (fp,"#\n");
2674  fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
2675  fprintf (fp,"# YUV_SIZE       widthxheight\n");
2676  fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
2677  fprintf (fp,"# on just one machine\n");
2678  fprintf (fp,"#\n");
2679  fprintf (fp,"YUV_SIZE 352x240\n");
2680  fprintf (fp,"\n");
2681  fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
2682  fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
2683  fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2684  fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
2685  fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
2686  fprintf (fp,"# to specify the file order.\n");
2687  fprintf (fp,"\n");
2688  fprintf (fp,"INPUT_FORMAT UCB\n");
2689  fprintf (fp,"\n");
2690  fprintf (fp,"# the conversion statement\n");
2691  fprintf (fp,"#\n");
2692  fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
2693  fprintf (fp,"#\n");
2694  fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
2695  fprintf (fp,"#        INPUT_CONVERT   giftoppm *\n");
2696  fprintf (fp,"#\n");
2697  fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2698  fprintf (fp,"#        INPUT_CONVERT   cat *.Y *.U *.V\n");
2699  fprintf (fp,"#\n");
2700  fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
2701  fprintf (fp,"#        INPUT_CONVERT   goto frame *; grabppm\n");
2702  fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2703  fprintf (fp,"#\n");
2704  fprintf (fp,"INPUT_CONVERT    * \n");
2705  fprintf (fp,"\n");
2706  fprintf (fp,"# number of frames in a GOP.\n");
2707  fprintf (fp,"#\n");
2708  fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
2709  fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2710  fprintf (fp,"#\n");
2711  fprintf (fp,"# later, will add more flexible GOP signalling\n");
2712  fprintf (fp,"#\n");
2713  fprintf (fp,"GOP_SIZE 16\n");
2714  fprintf (fp,"\n");
2715  fprintf (fp,"# number of slices in a frame\n");
2716  fprintf (fp,"#\n");
2717  fprintf (fp,"# 1 is a good number.  another possibility is the number of macroblock rows\n");
2718  fprintf (fp,"# (which is the height divided by 16)\n");
2719  fprintf (fp,"#\n");
2720  fprintf (fp,"SLICES_PER_FRAME 1\n");
2721  fprintf (fp,"\n");
2722  fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2723#if QT_VERSION < 0x040000
2724  fprintf (fp,"INPUT_DIR        %s\n",fMovieTempFolderPath.ascii());
2725#else
2726  fprintf (fp,"INPUT_DIR        %s\n",fMovieTempFolderPath.toStdString().c_str());
2727#endif
2728  fprintf (fp,"\n");
2729  fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2730  fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2731  fprintf (fp,"# way of numbering them.  See the manual for more information.\n");
2732  fprintf (fp,"INPUT\n");
2733  fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2734  fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2735  fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2736  fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2737  fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2738  fprintf (fp,"# if you do, too bad!!!\n");
2739  fprintf (fp,"#\n");
2740  fprintf (fp,"#\n");
2741  fprintf (fp,"Test*.ppm        [0-%d]\n",fRecordFrameNumber-1);
2742  fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2743  fprintf (fp,"# of files\n");
2744  fprintf (fp,"END_INPUT\n");
2745  fprintf (fp,"\n");
2746  fprintf (fp,"\n");
2747  fprintf (fp,"\n");
2748  fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2749  fprintf (fp,"\n");
2750  fprintf (fp,"# FULL or HALF -- must be upper case\n");
2751  fprintf (fp,"# Should be FULL for computer generated images\n");
2752  fprintf (fp,"PIXEL            FULL\n");
2753  fprintf (fp,"\n");
2754  fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2755  fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2756  fprintf (fp,"RANGE            10\n");
2757  fprintf (fp,"\n");
2758  fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2759  fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2760  fprintf (fp,"\n");
2761  fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2762  fprintf (fp,"PSEARCH_ALG      LOGARITHMIC\n");
2763  fprintf (fp,"\n");
2764  fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2765  fprintf (fp,"#\n");
2766  fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2767  fprintf (fp,"#\n");
2768  fprintf (fp,"BSEARCH_ALG      SIMPLE\n");
2769  fprintf (fp,"\n");
2770  fprintf (fp,"#\n");
2771  fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2772  fprintf (fp,"# (values must be between 1 and 31)\n");
2773  fprintf (fp,"# These are the Qscale values for the entire frame in variable bit-rate\n");
2774  fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2775  fprintf (fp,"#\n");
2776  fprintf (fp,"\n");
2777  fprintf (fp,"# Qscale (Quantization scale) affects quality and compression,\n");
2778  fprintf (fp,"# but has very little effect on speed.\n");
2779  fprintf (fp,"\n");
2780  fprintf (fp,"IQSCALE          4\n");
2781  fprintf (fp,"PQSCALE          5\n");
2782  fprintf (fp,"BQSCALE          12\n");
2783  fprintf (fp,"\n");
2784  fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2785  fprintf (fp,"REFERENCE_FRAME  ORIGINAL\n");
2786  fprintf (fp,"\n");
2787  fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2788  fprintf (fp,"\n");
2789  fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2790  fprintf (fp,"#BIT_RATE  1000000\n");
2791  fprintf (fp,"\n");
2792  fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2793  fprintf (fp,"BUFFER_SIZE 327680\n");
2794  fprintf (fp,"\n");
2795  fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2796  fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2797  fprintf (fp,"FRAME_RATE 30\n");
2798  fprintf (fp,"\n");
2799  fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2800  fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.\n");
2801  fprintf (fp,"\n");
2802  fprintf (fp,"\n");
2803  fclose (fp);
2804
2805  setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
2806  setRecordingStatus(READY_TO_ENCODE);
2807  return true;
2808}
2809
2810void G4OpenGLQtViewer::encodeVideo()
2811{
2812  if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
2813    setRecordingStatus(ENCODING);
2814   
2815#if QT_VERSION < 0x040000
2816    QStringList args = QStringList(fEncoderPath);
2817    args.push_back(fMovieTempFolderPath+fParameterFileName);
2818    fProcess = new QProcess(args);
2819    QObject ::connect(fProcess,SIGNAL(processExited ()),
2820                      this,SLOT(processEncodeFinished()));
2821    QObject ::connect(fProcess,SIGNAL(readyReadStdout ()),
2822                      this,SLOT(processEncodeStdout()));
2823    fProcess->setCommunication(QProcess::DupStderr);
2824    fProcess->launch("");
2825#else
2826    fProcess = new QProcess();
2827#if QT_VERSION > 0x040100
2828    QObject ::connect(fProcess,SIGNAL(finished ( int,QProcess::ExitStatus)),
2829                      this,SLOT(processEncodeFinished()));
2830    QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2831                      this,SLOT(processEncodeStdout()));
2832#else
2833    QObject ::connect(fProcess,SIGNAL(finished ( int)),
2834                      this,SLOT(processEncodeFinished()));
2835    QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2836                      this,SLOT(processEncodeStdout()));
2837#endif
2838    fProcess->setReadChannelMode(QProcess::MergedChannels);
2839    fProcess->start (fEncoderPath, QStringList(fMovieTempFolderPath+fParameterFileName));
2840#endif
2841  }
2842}
2843
2844
2845// FIXME : does not work on Qt3
2846void G4OpenGLQtViewer::processEncodeStdout()
2847{
2848#if QT_VERSION > 0x040000
2849  QString tmp = fProcess->readAllStandardOutput ().data();
2850  int start = tmp.lastIndexOf("ESTIMATED TIME");
2851  tmp = tmp.mid(start,tmp.indexOf("\n",start)-start);
2852#else
2853  QString tmp = fProcess->readStdout ().data();
2854  int start = tmp.findRev("ESTIMATED TIME");
2855  tmp = tmp.mid(start,tmp.find("\n",start)-start);
2856#endif
2857  setRecordingInfos(tmp);
2858}
2859
2860
2861void G4OpenGLQtViewer::processEncodeFinished()
2862{
2863
2864  QString txt = "";
2865  txt = getProcessErrorMsg();
2866  if (txt == "") {
2867    setRecordingStatus(SUCCESS);
2868  } else {
2869    setRecordingStatus(FAILED);
2870  }
2871  setRecordingInfos(txt+removeTempFolder());
2872}
2873
2874
2875void G4OpenGLQtViewer::processLookForFinished()
2876 {
2877
2878  QString txt = getProcessErrorMsg();
2879  if (txt != "") {
2880    fEncoderPath = "";
2881  } else {
2882#if QT_VERSION > 0x040000
2883    fEncoderPath = QString(fProcess->readAllStandardOutput ().data()).trimmed();
2884#else
2885    fEncoderPath = QString(fProcess->readStdout ().data()).simplifyWhiteSpace();
2886#endif
2887    // if not found, return "not found"
2888    if (fEncoderPath.contains(" ")) {
2889      fEncoderPath = "";
2890    } else if (!fEncoderPath.contains("mpeg_encode")) {
2891      fEncoderPath = "";
2892    }
2893    setEncoderPath(fEncoderPath);
2894  }
2895  // init temp folder
2896#if QT_VERSION > 0x040000
2897  setTempFolderPath(QDir::temp ().absolutePath ());
2898#else
2899  // Let's have a try
2900  setTempFolderPath("/tmp/");
2901#endif
2902}
2903
2904
2905QString G4OpenGLQtViewer::getProcessErrorMsg()
2906{
2907  QString txt = "";
2908#if QT_VERSION < 0x040000
2909  if (!fProcess->normalExit ()) {
2910    txt = "Exist status "+ fProcess->exitStatus ();
2911  }
2912#else
2913  if (fProcess->exitCode() != 0) {
2914    switch (fProcess->error()) {
2915    case QProcess::FailedToStart:
2916      txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2917      break;
2918    case QProcess::Crashed:
2919      txt = "The process crashed some time after starting successfully.\n";
2920      break;
2921    case QProcess::Timedout:
2922      txt = "The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.\n";
2923      break;
2924    case QProcess::WriteError:
2925      txt = "An error occurred when attempting to write to the process. For example, the process may not be running, or it may have closed its input channel.\n";
2926      break;
2927    case QProcess::ReadError:
2928      txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2929      break;
2930    case QProcess::UnknownError:
2931      txt = "An unknown error occurred. This is the default return value of error().\n";
2932      break;
2933    }
2934  }
2935#endif
2936   return txt;
2937}
2938
2939/*
2940 
2941void MultiLayer::exportToSVG(const QString& fname)
2942{
2943  QPicture picture;
2944  QPainter p(&picture);
2945  for (int i=0;i<(int)graphsList->count();i++)
2946    {
2947      Graph *gr=(Graph *)graphsList->at(i);
2948      Plot *myPlot= (Plot *)gr->plotWidget();
2949     
2950      QPoint pos=gr->pos();
2951     
2952      int width=int(myPlot->frameGeometry().width());
2953      int height=int(myPlot->frameGeometry().height());
2954     
2955      myPlot->print(&p, QRect(pos,QSize(width,height)));
2956    }
2957 
2958  p.end();
2959  picture.save(fname, "svg");
2960}
2961*/
2962#endif
Note: See TracBrowser for help on using the repository browser.