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

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

corrections sur le removeTempFolder et autres

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