source: trunk/source/visualization/OpenGL/src/G4OpenGLQtViewer.cc @ 870

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

see history

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