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

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

on bloque si l encoder est un dir+le status est mis a jour des le debut

  • Property svn:mime-type set to text/cpp
File size: 83.9 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    displayRecordingStatus();
1469  }
1470  fMovieParametersDialog->show();
1471}
1472
1473
1474/*
1475// 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
1476
1477void Graph::exportToSVG(const QString& fname)
1478{
1479  // enable workaround for Qt3 misalignments
1480  QwtPainter::setSVGMode(true);
1481  QPicture picture;
1482  QPainter p(&picture);
1483  d_plot->print(&p, d_plot->rect());
1484  p.end();
1485
1486  picture.save(fname, "svg");
1487}
1488*/
1489
1490
1491
1492
1493/**
1494   Save the current mouse press point
1495   @param p mouse click point
1496*/
1497#if QT_VERSION < 0x040000
1498void G4OpenGLQtViewer::G4MousePressEvent(QPoint p,Qt::ButtonState mButtons)
1499#else
1500void G4OpenGLQtViewer::G4MousePressEvent(QPoint p,Qt::MouseButtons mButtons)
1501#endif
1502{
1503  fAutoMove = false; // stop automove
1504  fLastPos = p;
1505  if (fMouseAction == STYLE2){  // pick
1506    Pick(p.x(),p.y());
1507  }
1508}
1509
1510
1511/**
1512   @param pos_x mouse x position
1513   @param pos_y mouse y position
1514   @param mButtons mouse button active
1515   @param mAutoMove true: apply this move till another evnt came, false :one time move
1516*/
1517
1518#if QT_VERSION < 0x040000
1519void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::ButtonState mButtons,bool mAutoMove)
1520#else
1521  void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::MouseButtons mButtons,bool mAutoMove)
1522#endif
1523{
1524  fAutoMove = mAutoMove;
1525
1526  if (!fAutoMove) {  // keep old delta if automove
1527    fDeltaPosX = fLastPos.x() - pos_x;
1528    fDeltaPosY = fLastPos.y() - pos_y;
1529  }
1530
1531  if ((fDeltaPosX == 0) && (fDeltaPosY == 0)) {
1532    fAutoMove = false;
1533  }
1534
1535  if (fMouseAction == STYLE1) {  // rotate
1536    if (mButtons & Qt::LeftButton) {
1537      rotateScene(fDeltaPosX,fDeltaPosY,fAutoMove);
1538    }
1539  } else if (fMouseAction == STYLE2) {  // move
1540    if (mButtons & Qt::LeftButton) {
1541      if (fAutoMove) {
1542        while (fAutoMove) {
1543          moveScene(-fDeltaPosX,-fDeltaPosY,0,true,true);
1544          ((QApplication*)G4Qt::getInstance ())->processEvents();
1545        }
1546      } else {
1547        moveScene(-fDeltaPosX,-fDeltaPosY,0,true,false);
1548      }
1549    }
1550  }
1551  fLastPos = QPoint(pos_x, pos_y);
1552}
1553
1554
1555/**
1556   Move the scene of dx, dy, dz values.
1557   @param dx delta mouse x position
1558   @param dy delta mouse y position
1559   @param mouseMove : true if even comes froma mouse move, false if even comes from key action
1560*/
1561
1562void G4OpenGLQtViewer::moveScene(G4double dx,G4double dy, G4double dz,bool mouseMove,bool mAutoMove)
1563{
1564  if (fHoldMoveEvent)
1565    return;
1566  fHoldMoveEvent = true;
1567
1568  if( mAutoMove == false) {
1569    fAutoMove = true;
1570  }
1571  G4double coefTrans = 0;
1572  GLdouble coefDepth = 0;
1573  while (fAutoMove) {
1574    if( mAutoMove == false) {
1575      fAutoMove = false;
1576    }
1577    if(mouseMove) {
1578      coefTrans = ((G4double)getSceneNearWidth())/((G4double)WinSize_x);
1579      if (WinSize_y <WinSize_x) {
1580        coefTrans = ((G4double)getSceneNearWidth())/((G4double)WinSize_y);
1581      }
1582    } else {
1583      coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1584      coefDepth = getSceneDepth()*fDeltaDepth;
1585    }
1586    fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1587   
1588    updateQWidget();
1589    if (fAutoMove)
1590      ((QApplication*)G4Qt::getInstance ())->processEvents();
1591  }
1592
1593  fHoldMoveEvent = false;
1594}
1595
1596
1597/**
1598   @param dx delta mouse x position
1599   @param dy delta mouse y position
1600*/
1601
1602void G4OpenGLQtViewer::rotateScene(G4double dx, G4double dy,bool mAutoRotate)
1603{
1604  if (fHoldRotateEvent)
1605    return;
1606  fHoldRotateEvent = true;
1607
1608  if( mAutoRotate == false) {
1609    fAutoMove = true;
1610  }
1611  G4Vector3D vp;
1612  G4Vector3D up;
1613 
1614  G4Vector3D xprime;
1615  G4Vector3D yprime;
1616  G4Vector3D zprime;
1617 
1618  G4double delta_alpha;
1619  G4double delta_theta;
1620 
1621  G4Vector3D new_vp;
1622  G4Vector3D new_up;
1623 
1624  G4double cosalpha;
1625  G4double sinalpha;
1626 
1627  G4Vector3D a1;
1628  G4Vector3D a2;
1629  G4Vector3D delta;
1630  G4Vector3D viewPoint;
1631
1632  while (fAutoMove) {
1633    if( mAutoRotate == false) {
1634      fAutoMove = false;
1635    }
1636   
1637    //phi spin stuff here
1638 
1639    vp = fVP.GetViewpointDirection ().unit ();
1640    up = fVP.GetUpVector ().unit ();
1641 
1642    yprime = (up.cross(vp)).unit();
1643    zprime = (vp.cross(yprime)).unit();
1644 
1645    if (fVP.GetLightsMoveWithCamera()) {
1646      delta_alpha = dy * fDeltaRotation;
1647      delta_theta = -dx * fDeltaRotation;
1648    } else {
1649      delta_alpha = -dy * fDeltaRotation;
1650      delta_theta = dx * fDeltaRotation;
1651    }   
1652 
1653    delta_alpha *= deg;
1654    delta_theta *= deg;
1655 
1656    new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
1657
1658    // to avoid z rotation flipping
1659    // to allow more than 360° rotation
1660    if (fVP.GetLightsMoveWithCamera()) {
1661      new_up = (new_vp.cross(yprime)).unit();
1662      if (new_vp.z()*vp.z() <0) {
1663        new_up.set(new_up.x(),-new_up.y(),new_up.z());
1664      }
1665    } else {
1666      new_up = up;
1667      if (new_vp.z()*vp.z() <0) {
1668        new_up.set(new_up.x(),-new_up.y(),new_up.z());
1669      }
1670    }
1671    fVP.SetUpVector(new_up);
1672    ////////////////
1673    // Rotates by fixed azimuthal angle delta_theta.
1674   
1675    cosalpha = new_up.dot (new_vp.unit());
1676    sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
1677    yprime = (new_up.cross (new_vp.unit())).unit ();
1678    xprime = yprime.cross (new_up);
1679    // Projection of vp on plane perpendicular to up...
1680    a1 = sinalpha * xprime;
1681    // Required new projection...
1682    a2 = sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
1683    // Required Increment vector...
1684    delta = a2 - a1;
1685    // So new viewpoint is...
1686    viewPoint = new_vp.unit() + delta;
1687   
1688#ifdef GEANT4_QT_DEBUG
1689//      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);
1690//      printf("up : %f %f %f\n",up.x(),up.y(),up.z());
1691//      printf("new up : %f %f %f\n",new_up.x(),new_up.y(),new_up.z());
1692//      printf("vp : %f %f %f\n",vp.x(),vp.y(),vp.z());
1693//      printf("new_vp : %f %f %f\n",new_vp.x(),new_vp.y(),new_vp.z());
1694#endif
1695    fVP.SetViewAndLights (viewPoint);
1696    updateQWidget();
1697   
1698    if (fAutoMove)
1699      ((QApplication*)G4Qt::getInstance ())->processEvents();
1700  }
1701 
1702  fHoldRotateEvent = false;
1703}
1704
1705/** This is the benning of a rescale function. It does nothing for the moment
1706    @param aWidth : new width
1707    @param aHeight : new height
1708*/
1709void G4OpenGLQtViewer::rescaleImage(
1710 int aWidth
1711,int aHeight
1712){
1713#ifdef GEANT4_QT_DEBUG
1714  printf("should rescale \n");
1715#endif
1716  GLfloat* feedback_buffer;
1717  GLint returned;
1718  FILE* file;
1719 
1720//   feedback_buffer = new GLfloat[size];
1721//   glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1722//   glRenderMode (GL_FEEDBACK);
1723 
1724//   glViewport (0, 0, aWidth, aHeight);
1725//   DrawView();
1726//   returned = glRenderMode (GL_RENDER);
1727
1728}
1729
1730/**
1731   Generate Vectorial Encapsulated Postscript form image
1732   @param aFilename : name of file
1733   @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1734   @param aImage : Image to print
1735*/
1736bool G4OpenGLQtViewer::generateVectorEPS (
1737 QString aFilename
1738,int aWidth
1739,int aHeight
1740,QImage aImage
1741)
1742{
1743  // Print vectored PostScript
1744 
1745  G4int size = 5000000;
1746
1747  GLfloat* feedback_buffer;
1748  GLint returned;
1749  FILE* file;
1750 
1751  feedback_buffer = new GLfloat[size];
1752  glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1753  glRenderMode (GL_FEEDBACK);
1754 
1755  int side = aWidth;
1756  if (aHeight < aWidth) side = aHeight;
1757  glViewport((aWidth - side) / 2, (aHeight - side) / 2, side, side);
1758  DrawView();
1759
1760  returned = glRenderMode (GL_RENDER);
1761 
1762 
1763#if QT_VERSION < 0x040000
1764  file = fopen (aFilename.ascii(), "w");
1765#else
1766  file = fopen (aFilename.toStdString().c_str(), "w");
1767#endif
1768  if (file) {
1769    spewWireframeEPS (file, returned, feedback_buffer, "rendereps");
1770  } else {
1771#if QT_VERSION < 0x040000
1772    G4cerr << "Could not open "<< aFilename.ascii() << G4endl;
1773#else
1774    G4cerr << "Could not open "<< aFilename.toStdString().c_str() << G4endl;
1775#endif
1776  }
1777 
1778  delete[] feedback_buffer;
1779
1780  return true;
1781}
1782
1783/**
1784   Generate Encapsulated Postscript form image
1785   @param aFilename : name of file
1786   @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1787   @param aImage : Image to print
1788*/
1789bool G4OpenGLQtViewer::generateEPS (
1790 QString aFilename
1791,int aInColor
1792,QImage aImage
1793)
1794{
1795  // FIXME
1796#ifdef GEANT4_QT_DEBUG
1797  printf("saving EPS\n");
1798#endif
1799
1800  FILE* fp;
1801
1802  if (aImage.bits () == NULL)
1803    return false;
1804 
1805#if QT_VERSION < 0x040000
1806  fp = fopen (aFilename.ascii(), "w");
1807#else
1808  fp = fopen (aFilename.toStdString().c_str(), "w");
1809#endif
1810  if (fp == NULL) {
1811    return false;
1812  }
1813 
1814  fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
1815#if QT_VERSION < 0x040000
1816  fprintf (fp, "%%%%Title: %s\n", aFilename.ascii());
1817#else
1818  fprintf (fp, "%%%%Title: %s\n", aFilename.toStdString().c_str());
1819#endif
1820  fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
1821  fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", aImage.width(), aImage.height());
1822  fprintf (fp, "%%%%EndComments\n");
1823  fprintf (fp, "gsave\n");
1824  fprintf (fp, "/bwproc {\n");
1825  fprintf (fp, "    rgbproc\n");
1826  fprintf (fp, "    dup length 3 idiv string 0 3 0 \n");
1827  fprintf (fp, "    5 -1 roll {\n");
1828  fprintf (fp, "    add 2 1 roll 1 sub dup 0 eq\n");
1829  fprintf (fp, "    { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
1830  fprintf (fp, "       3 1 roll 5 -1 roll } put 1 add 3 0 \n");
1831  fprintf (fp, "    { 2 1 roll } ifelse\n");
1832  fprintf (fp, "    }forall\n");
1833  fprintf (fp, "    pop pop pop\n");
1834  fprintf (fp, "} def\n");
1835  fprintf (fp, "systemdict /colorimage known not {\n");
1836  fprintf (fp, "   /colorimage {\n");
1837  fprintf (fp, "       pop\n");
1838  fprintf (fp, "       pop\n");
1839  fprintf (fp, "       /rgbproc exch def\n");
1840  fprintf (fp, "       { bwproc } image\n");
1841  fprintf (fp, "   }  def\n");
1842  fprintf (fp, "} if\n");
1843  fprintf (fp, "/picstr %d string def\n", aImage.width() * aInColor);
1844  fprintf (fp, "%d %d scale\n", aImage.width(), aImage.height());
1845  fprintf (fp, "%d %d %d\n", aImage.width(), aImage.height(), 8);
1846  fprintf (fp, "[%d 0 0 %d 0 0]\n", aImage.width(), aImage.height());
1847  fprintf (fp, "{currentfile picstr readhexstring pop}\n");
1848  fprintf (fp, "false %d\n", aInColor);
1849  fprintf (fp, "colorimage\n");
1850 
1851
1852  int width = aImage.width();
1853  int height = aImage.height();
1854  int depth = aImage.depth();
1855  int size = width*height;
1856 
1857  if (depth == 1)
1858    size = (width+7)/8*height;
1859  else if (aInColor == 1)
1860    size = size*3;
1861 
1862  int i = 0;
1863  //  if ( aInColor ==1 ) {
1864  // FIXME : L. Garnier. For the moment 10 dec 2007, I could not find a way
1865  // to save correctly grayscale Image. I mean that color or grayscale image
1866  // have the same file save size !
1867 
1868  /* } else*/ if (depth == 8) {
1869    for(int y=height-1; y >=0 ; y--) {
1870      const uchar * s = aImage.scanLine(y);
1871      for(int x=0; x <width; x++) {
1872        QRgb rgb = aImage.color(s[x]);
1873        if (aInColor == 1) {
1874          fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
1875          i++;
1876        } else {
1877          fprintf (fp, " %02hx %02hx %02hx",
1878                   (unsigned char) qRed(rgb),
1879                   (unsigned char) qGreen(rgb),
1880                   (unsigned char) qBlue(rgb));
1881          i += 3;
1882        }
1883      }
1884      fprintf (fp, "\n");
1885    }
1886  } else {
1887#if QT_VERSION < 0x040000
1888    bool alpha = aImage.hasAlphaBuffer();
1889#else
1890    bool alpha = aImage.hasAlphaChannel();
1891    for(int y=height-1; y >=0 ; y--) {
1892      QRgb * s = (QRgb*)(aImage.scanLine(y));
1893      for(int x=0; x <width; x++) {
1894        QRgb rgb = (*s++);
1895        if (alpha && qAlpha(rgb) < 0x40) // 25% alpha, convert to white -
1896          rgb = qRgb(0xff, 0xff, 0xff);
1897        if (aInColor == 1) {
1898          fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
1899          i++;
1900        } else {
1901          fprintf (fp, " %02hx %02hx %02hx",
1902                   (unsigned char) qRed(rgb),
1903                   (unsigned char) qGreen(rgb),
1904                   (unsigned char) qBlue(rgb));
1905          i += 3;
1906        }
1907      }
1908      fprintf (fp, "\n");
1909    }
1910#endif
1911
1912  }
1913
1914  fprintf (fp, "grestore\n");
1915  fprintf (fp, "showpage\n");
1916  fclose (fp);
1917
1918  return true;
1919}
1920/**
1921   Generate Postscript or PDF form image
1922   @param aFilename : name of file
1923   @param aInColor : numbers of colors : 1->BW 2->RGB
1924   @param aImage : Image to print
1925*/
1926bool G4OpenGLQtViewer::generatePS_PDF (
1927 QString aFilename
1928,int aInColor
1929,QImage aImage
1930)
1931{
1932
1933#if QT_VERSION < 0x040000
1934#ifdef Q_WS_MAC || Q_WS_X11
1935  QPrinter printer;
1936  //  printer.setPageSize(pageSize);
1937  if (aInColor == 1) {
1938    printer.setColorMode(QPrinter::GrayScale);
1939  } else {
1940    printer.setColorMode(QPrinter::Color);
1941  }
1942
1943  /* FIXME : I don't know which format it will save...
1944     if (aFilename.endsWith(".ps")) {
1945     printer.setOutputFormat(QPrinter::PostScriptFormat);
1946     } else {
1947     printer.setOutputFormat(QPrinter::PdfFormat);
1948     }
1949  */
1950  printer.setOutputFileName(aFilename);
1951  //  printer.setFullPage ( true);
1952  QPainter paint(&printer);
1953  paint.drawImage (0,0,aImage );
1954  paint.end();
1955#else
1956  G4cerr << "This fonction is only supported on Mac OsX or X11 with Qt3. Full platform supported with Qt4" << G4endl;
1957#endif
1958#else
1959  QPrinter printer;
1960  //  printer.setPageSize(pageSize);
1961
1962  // FIXME : L. Garnier 4/12/07
1963  // This is not working, it does nothing. Image is staying in color mode
1964  // So I have desactivate the B/W button in GUI
1965  if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1966#if QT_VERSION < 0x040000
1967    aImage = aImage.convertDepth(1,Qt::MonoOnly);
1968#else
1969    aImage = aImage.convertToFormat ( aImage.format(), Qt::MonoOnly);
1970#endif
1971  }
1972
1973
1974  if (aFilename.endsWith(".ps")) {
1975#if QT_VERSION > 0x040200
1976    printer.setOutputFormat(QPrinter::PostScriptFormat);
1977#endif
1978  } else {
1979#if QT_VERSION > 0x040100
1980    printer.setOutputFormat(QPrinter::PdfFormat);
1981#endif
1982  }
1983#if QT_VERSION > 0x040100
1984  printer.setOutputFileName(aFilename);
1985#endif
1986  //  printer.setFullPage ( true);
1987  QPainter paint(&printer);
1988  paint.drawImage (0,0,aImage);
1989  paint.end();
1990#endif
1991  return true;
1992}
1993
1994
1995
1996void G4OpenGLQtViewer::G4keyPressEvent (QKeyEvent * event)
1997{
1998  if (fHoldKeyEvent)
1999    return;
2000
2001  fHoldKeyEvent = true;
2002
2003#if QT_VERSION < 0x040000
2004  if ((event->key() == Qt::Key_Down) && (event->state() & Qt::AltButton )) { // go backward
2005#else
2006  if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::AltModifier )) { // go backward
2007#endif
2008   
2009    moveScene(0,0,1,false);
2010  }
2011#if QT_VERSION < 0x040000
2012  else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::AltButton)) { // go forward
2013#else
2014  else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::AltModifier)) { // go forward
2015#endif
2016    moveScene(0,0,-1,false);
2017  }
2018#if QT_VERSION < 0x040000
2019  if ((event->key() == Qt::Key_Down) && (event->state() & Qt::ShiftButton)) { // rotate phi
2020#else
2021  if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
2022#endif
2023    rotateScene(0,-1);
2024  }
2025#if QT_VERSION < 0x040000
2026  else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::ShiftButton)) { // rotate phi
2027#else
2028  else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
2029#endif
2030    rotateScene(0,1);
2031  }
2032#if QT_VERSION < 0x040000
2033  if ((event->key() == Qt::Key_Left) && (event->state() & Qt::ShiftButton)) { // rotate theta
2034#else
2035  if ((event->key() == Qt::Key_Left) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
2036#endif
2037    rotateScene(1,0);
2038  }
2039#if QT_VERSION < 0x040000
2040  else if ((event->key() == Qt::Key_Right) && (event->state() & Qt::ShiftButton)) { // rotate theta
2041#else
2042  else if ((event->key() == Qt::Key_Right) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
2043#endif
2044    rotateScene(-1,0);
2045  }
2046
2047#if QT_VERSION < 0x040000
2048  if ((event->state() & Qt::AltButton)) {
2049#else
2050  if ((event->modifiers() & Qt::AltModifier)) {
2051#endif
2052    if (event->key() == Qt::Key_Plus) {
2053      fDeltaRotation = fDeltaRotation/0.7;
2054    }
2055    else if (event->key() == Qt::Key_Minus) {
2056      fDeltaRotation = fDeltaRotation*0.7;
2057    }
2058  } else {
2059    if (event->key() == Qt::Key_Plus) {
2060      fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
2061      updateQWidget();
2062    }
2063    else if (event->key() == Qt::Key_Minus) {
2064      fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
2065      updateQWidget();
2066    }
2067  }
2068 
2069 
2070  if (event->key() == Qt::Key_Escape) { // escaped from full screen
2071#if QT_VERSION >= 0x030200
2072    if (GLWindow->isFullScreen()) {
2073#if QT_VERSION < 0x040000
2074      fFullScreenOn->activated();
2075#else
2076      fFullScreenOn->trigger();
2077#endif
2078    }
2079#endif
2080  }
2081  // several case here : If return is pressed, in every case -> display the movie parameters dialog
2082  // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
2083  // If encoder not found-> does nothing.Only display a message in status box
2084  // If all ok-> generate parameter file
2085  // If ok -> put encoder button enabled
2086 
2087  if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)){ // end of video
2088   stopVideo();
2089  }
2090  if (event->key() == Qt::Key_Space){ // start/pause of video
2091   startPauseVideo();
2092  }
2093
2094  // with no modifiers
2095#if QT_VERSION < 0x040000
2096  if (event->state() == Qt::NoButton) {
2097#else
2098  if (event->modifiers() == Qt::NoModifier) {
2099#endif
2100    if (event->key() == Qt::Key_Down) { // go down
2101      moveScene(0,1,0,false);
2102    }
2103    else if (event->key() == Qt::Key_Up) {  // go up
2104      moveScene(0,-1,0,false);
2105    }
2106    if (event->key() == Qt::Key_Left) { // go left
2107      moveScene(-1,0,0,false);
2108    }
2109    else if (event->key() == Qt::Key_Right) { // go right
2110      moveScene(1,0,0,false);
2111    }
2112  }
2113  fHoldKeyEvent = false;
2114}
2115 
2116
2117/** Stop the video. Check all parameters and enable encoder button if all is ok.
2118*/
2119void G4OpenGLQtViewer::stopVideo() {
2120
2121 // if encoder parameter is wrong, display parameters dialog and return
2122  if (!fMovieParametersDialog) {
2123    showMovieParametersDialog();
2124  }
2125  setRecordingStatus(STOP);
2126
2127  if (fRecordFrameNumber >0) {
2128    // check parameters if they were modified (Re APPLY them...)
2129    // It will enable/disable encode button
2130    fMovieParametersDialog->checkAllParameters();
2131  } else {
2132    resetRecording();
2133    setRecordingInfos("No frame to encode.");
2134  }
2135}
2136
2137
2138/** Start/Pause the video..
2139*/
2140void G4OpenGLQtViewer::startPauseVideo() {
2141   
2142  // first time, if temp parameter is wrong, display parameters dialog and return
2143  if ( fRecordingStep == WAIT) {
2144    if ( fRecordFrameNumber == 0) {
2145      if (getTempFolderPath() == "") {
2146        showMovieParametersDialog();
2147        setRecordingInfos("You should specified the temp folder in order to make movie");
2148        return;
2149      } else  {
2150        // remove temp folder if it was create
2151        QString tmp = removeTempFolder();
2152        if (tmp !="") {
2153          setRecordingInfos(tmp);
2154          return;
2155        }
2156        tmp = createTempFolder();
2157        if (tmp != "") {
2158          setRecordingInfos("Can't create temp folder."+tmp);
2159          return;
2160        }
2161      }
2162    }
2163  }
2164  if (fRecordingStep == WAIT) {
2165    setRecordingStatus(START);
2166  } else if (fRecordingStep == START) {
2167    setRecordingStatus(PAUSE);
2168  } else if (fRecordingStep == PAUSE) {
2169    setRecordingStatus(CONTINUE);
2170  } else if (fRecordingStep == CONTINUE) {
2171    setRecordingStatus(PAUSE);
2172  }
2173}
2174
2175
2176void G4OpenGLQtViewer::setRecordingStatus(RECORDING_STEP step) {
2177
2178  fRecordingStep = step;
2179  displayRecordingStatus();
2180}
2181
2182
2183void G4OpenGLQtViewer::displayRecordingStatus() {
2184 
2185  QString txt = "";
2186  if (fRecordingStep == WAIT) {
2187    txt  = "Waiting to start...";
2188    fRecordFrameNumber = 0; // reset the frame number
2189  } else if (fRecordingStep == START) {
2190    txt  = "Start Recording...";
2191  } else if (fRecordingStep == PAUSE) {
2192    txt  = "Pause Recording...";
2193  } else if (fRecordingStep == CONTINUE) {
2194    txt  = "Continue Recording...";
2195  } else if (fRecordingStep == STOP) {
2196    txt  = "Stop Recording...";
2197  } else if (fRecordingStep == READY_TO_ENCODE) {
2198    txt  = "Ready to Encode...";
2199  } else if (fRecordingStep == ENCODING) {
2200    txt  = "Encoding...";
2201  } else if (fRecordingStep == FAILED) {
2202    txt  = "Failed to encode...";
2203  } else if (fRecordingStep == SUCCESS) {
2204    txt  = "File encoded successfully";
2205  } else {
2206  }
2207
2208  if (fMovieParametersDialog) {
2209    fMovieParametersDialog->setRecordingStatus(txt);
2210  } else {
2211#if QT_VERSION < 0x040000
2212    G4cout << txt.ascii() << G4endl;
2213#else
2214    G4cout << txt.toStdString().c_str() << G4endl;
2215#endif
2216  }
2217  setRecordingInfos("");
2218}
2219
2220
2221void G4OpenGLQtViewer::setRecordingInfos(QString txt) {
2222  if (fMovieParametersDialog) {
2223    fMovieParametersDialog->setRecordingInfos(txt);
2224  } else {
2225#if QT_VERSION < 0x040000
2226    G4cout << txt.ascii() << G4endl;
2227#else
2228    G4cout << txt.toStdString().c_str() << G4endl;
2229#endif
2230  }
2231}
2232
2233/** Init the movie parameters. Temp dir and encoder path
2234*/
2235void G4OpenGLQtViewer::initMovieParameters() {
2236  //init encoder
2237 
2238   //look for encoderPath
2239     QProcess search;
2240     search.setReadChannelMode(QProcess::MergedChannels);
2241     search.start ("which mpeg_encode");
2242 
2243     if (search.waitForFinished()) {
2244       fEncoderPath = QString(QString::fromLocal8Bit(search.readAll())).trimmed();
2245       // if not found, return "not found"
2246       if (fEncoderPath.contains(" ")) {
2247         fEncoderPath = "";
2248       } else if (!fEncoderPath.contains("mpeg_encode")) {
2249         fEncoderPath = "";
2250       }
2251     }
2252     setEncoderPath(fEncoderPath);
2253// init temp folder
2254  setTempFolderPath(QDir::temp ().absolutePath ());
2255}
2256
2257/** @return encoder path or "" if it does not exist
2258 */
2259QString G4OpenGLQtViewer::getEncoderPath() {
2260  return fEncoderPath;
2261}
2262 
2263
2264/**
2265 * set the new encoder path
2266 * @return "" if correct. The error otherwise
2267*/
2268QString G4OpenGLQtViewer::setEncoderPath(QString path) {
2269  if (path == "") {
2270    return "File does not exist";
2271  }
2272  // check if it is not a dir
2273  QDir dir(path);
2274  dir.setFilter( QDir::Dirs);
2275  QStringList subDirList = dir.entryList();
2276
2277  if (!subDirList.isEmpty()) {
2278    return "This is a directory";
2279  }
2280
2281  path =  QDir::cleanPath(path);
2282  QFile *f = new QFile(path);
2283  if (!f->exists()) {
2284    return "File does not exist";
2285  }
2286  if (!(f->permissions() & QFile::ExeUser)) {
2287    return "File exist but is not executable";
2288  }
2289  fEncoderPath = path;
2290  return "";
2291}
2292
2293
2294bool G4OpenGLQtViewer::isRecording(){
2295  if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
2296    return true;
2297  }
2298  return false;
2299}
2300
2301bool G4OpenGLQtViewer::isStopped(){
2302  if (fRecordingStep == STOP) {
2303    return true;
2304  }
2305  return false;
2306}
2307
2308
2309bool G4OpenGLQtViewer::isReadyToEncode(){
2310  if (fRecordingStep == READY_TO_ENCODE) {
2311    return true;
2312  }
2313  return false;
2314}
2315
2316void G4OpenGLQtViewer::resetRecording() {
2317    setRecordingStatus(WAIT);
2318}
2319
2320/**
2321 * set the temp folder path
2322 * @return "" if correct. The error otherwise
2323*/
2324QString G4OpenGLQtViewer::setTempFolderPath(QString path) {
2325
2326  if (path == "") {
2327    return "Path does not exist";
2328  }
2329  path =  QDir::cleanPath(path);
2330  QDir *d = new QDir(path);
2331  if (!d->exists(path)) {
2332    return "Path does not exist";
2333  }
2334
2335  d->setFilter( QDir::Dirs | QDir::Readable | QDir::Writable );
2336  QStringList subDirList = d->entryList();
2337  bool found = false;
2338
2339  for (QStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
2340    const QString currentDir = *it;
2341   
2342    if (currentDir == ".") { // we found it
2343      found = true;
2344    }
2345  }
2346
2347  if (!found)
2348    return "Path exist, but is not write accessible";
2349 
2350  fTempFolderPath = path;
2351  return "";
2352}
2353
2354/** @return the temp folder path or "" if it does not exist
2355 */
2356QString G4OpenGLQtViewer::getTempFolderPath() {
2357  return fTempFolderPath;
2358}
2359 
2360/**
2361 * set the save file name path
2362 * @return "" if correct. The error otherwise
2363*/
2364QString G4OpenGLQtViewer::setSaveFileName(QString path) {
2365
2366  if (path == "") {
2367    return "Path does not exist";
2368  }
2369  // check if it is not a dir
2370  QDir tmp(path);
2371  tmp.setFilter( QDir::Dirs);
2372  QStringList subDirListTmp = tmp.entryList();
2373
2374  if (!subDirListTmp.isEmpty()) {
2375    return "This is a directory";
2376  }
2377
2378  path =  QDir::cleanPath(path);
2379  QFileInfo *fileInfo = new QFileInfo(path);
2380  QDir dir = fileInfo->absoluteDir();
2381  if (!dir.exists()) {
2382    return "Folder does not exist";
2383  }
2384
2385  dir.setFilter( QDir::Dirs | QDir::Writable );
2386  QStringList subDirList = dir.entryList();
2387  bool found = false;
2388
2389  for (QStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
2390    const QString currentDir = *it;
2391   
2392    if (currentDir == ".") { // we found it
2393      found = true;
2394    }
2395  }
2396
2397  if (!found)
2398    return "Path exist, but is not write accessible";
2399 
2400  fSaveFileName = path;
2401  return "";
2402}
2403
2404/** @return the save file path
2405 */
2406QString G4OpenGLQtViewer::getSaveFileName() {
2407  return fSaveFileName ;
2408}
2409
2410/** Create a Qt_temp folder in the temp folder given
2411* The temp folder will be like this /tmp/QtMovie_12-02-2008_12_12_58/
2412* @return "" if success. Error message if not.
2413*/
2414QString G4OpenGLQtViewer::createTempFolder() {
2415  fMovieTempFolderPath = "";
2416
2417  //check
2418  QString tmp = setTempFolderPath(fTempFolderPath);
2419  if (tmp != "") {
2420    return tmp;
2421  }
2422  QString path = QString(QDir::separator())+"QtMovie_"+QDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+QString(QDir::separator());
2423  QDir *d = new QDir(QDir::cleanPath(fTempFolderPath));
2424  // check if it is already present
2425  if (d->exists(path)) {
2426    return "Folder "+path+" already exists.Please remove it first";
2427  }
2428  if (d->mkdir(fTempFolderPath+path)) {
2429    fMovieTempFolderPath = fTempFolderPath+path;
2430    return "";
2431  } else {
2432    return "Can't create "+fTempFolderPath+path;
2433  }
2434  return "-";
2435}
2436
2437/** Remove the Qt_temp folder in the temp folder
2438*/
2439QString G4OpenGLQtViewer::removeTempFolder() {
2440        // remove files in Qt_temp folder
2441  if (fMovieTempFolderPath == "") {
2442    return "";
2443  }
2444  QDir *d = new QDir(QDir::cleanPath(fMovieTempFolderPath));
2445  if (!d->exists()) {
2446    return "";  // already remove
2447  }
2448
2449  d->setFilter( QDir::Files );
2450  QStringList subDirList = d->entryList();
2451  int res = true;
2452  QString error = "";
2453  for (QStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
2454    const QString currentFile = *it;
2455      if (!d->remove(currentFile)) {
2456        res = false;
2457        QString file = fMovieTempFolderPath+currentFile;
2458        error +="Removing file failed : "+file;
2459      } else {
2460      }
2461  }
2462  if (res) {
2463    if (d->rmdir(fMovieTempFolderPath)) {
2464      fMovieTempFolderPath = "";
2465      return "";
2466    } else {
2467      return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
2468    }
2469
2470  }
2471  return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
2472}
2473
2474
2475
2476bool G4OpenGLQtViewer::hasPendingEvents () {
2477  return ((QApplication*)G4Qt::getInstance ())->hasPendingEvents ();
2478}
2479
2480bool G4OpenGLQtViewer::generateMpegEncoderParameters () {
2481
2482                // save the parameter file
2483  FILE* fp;
2484#if QT_VERSION < 0x040000
2485  fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).ascii, "w");
2486#else
2487  fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).toStdString().c_str(), "w");
2488#endif
2489
2490  if (fp == NULL) {
2491    setRecordingInfos("Generation of parameter file failed");
2492    return false;
2493  }
2494
2495  fprintf (fp,"# parameter file template with lots of comments to assist you\n");
2496  fprintf (fp,"#\n");
2497  fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
2498  fprintf (fp,"# the copy\n");
2499  fprintf (fp,"#\n");
2500  fprintf (fp,"#\n");
2501  fprintf (fp,"# any line beginning with '#' is a comment\n");
2502  fprintf (fp,"#\n");
2503  fprintf (fp,"# no line should be longer than 255 characters\n");
2504  fprintf (fp,"#\n");
2505  fprintf (fp,"#\n");
2506  fprintf (fp,"# general format of each line is:\n");
2507  fprintf (fp,"#          \n");
2508  fprintf (fp,"#\n");
2509  fprintf (fp,"# lines can generally be in any order\n");
2510  fprintf (fp,"#\n");
2511  fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
2512  fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
2513  fprintf (fp,"#\n");
2514  fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
2515  fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
2516  fprintf (fp,"# the INPUT parameter.\n");
2517  fprintf (fp,"#\n");
2518  fprintf (fp,"#  MUST be in UPPER CASE\n");
2519  fprintf (fp,"#\n");
2520  fprintf (fp,"\n");
2521  fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
2522  fprintf (fp,"# for more info.\n");
2523  fprintf (fp,"\n");
2524  fprintf (fp,"PATTERN          IBBPBBPBBPBBPBBP\n");
2525#if QT_VERSION < 0x040000
2526  fprintf (fp,"OUTPUT           %s\n",getSaveFileName().ascii());
2527#else
2528  fprintf (fp,"OUTPUT           %s\n",getSaveFileName().toStdString().c_str());
2529#endif
2530  fprintf (fp,"\n");
2531  fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
2532  fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
2533  fprintf (fp,"#\n");
2534  fprintf (fp,"# You must specify the type of the input files.  The choices are:\n");
2535  fprintf (fp,"#    YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
2536  fprintf (fp,"#        (must be upper case)\n");
2537  fprintf (fp,"#\n");
2538  fprintf (fp,"BASE_FILE_FORMAT PPM\n");
2539  fprintf (fp,"\n");
2540  fprintf (fp,"#\n");
2541  fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
2542  fprintf (fp,"# YUV_SIZE       widthxheight\n");
2543  fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
2544  fprintf (fp,"# on just one machine\n");
2545  fprintf (fp,"#\n");
2546  fprintf (fp,"YUV_SIZE 352x240\n");
2547  fprintf (fp,"\n");
2548  fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
2549  fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
2550  fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2551  fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
2552  fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
2553  fprintf (fp,"# to specify the file order.\n");
2554  fprintf (fp,"\n");
2555  fprintf (fp,"INPUT_FORMAT UCB\n");
2556  fprintf (fp,"\n");
2557  fprintf (fp,"# the conversion statement\n");
2558  fprintf (fp,"#\n");
2559  fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
2560  fprintf (fp,"#\n");
2561  fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
2562  fprintf (fp,"#        INPUT_CONVERT   giftoppm *\n");
2563  fprintf (fp,"#\n");
2564  fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2565  fprintf (fp,"#        INPUT_CONVERT   cat *.Y *.U *.V\n");
2566  fprintf (fp,"#\n");
2567  fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
2568  fprintf (fp,"#        INPUT_CONVERT   goto frame *; grabppm\n");
2569  fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2570  fprintf (fp,"#\n");
2571  fprintf (fp,"INPUT_CONVERT    * \n");
2572  fprintf (fp,"\n");
2573  fprintf (fp,"# number of frames in a GOP.\n");
2574  fprintf (fp,"#\n");
2575  fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
2576  fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2577  fprintf (fp,"#\n");
2578  fprintf (fp,"# later, will add more flexible GOP signalling\n");
2579  fprintf (fp,"#\n");
2580  fprintf (fp,"GOP_SIZE 16\n");
2581  fprintf (fp,"\n");
2582  fprintf (fp,"# number of slices in a frame\n");
2583  fprintf (fp,"#\n");
2584  fprintf (fp,"# 1 is a good number.  another possibility is the number of macroblock rows\n");
2585  fprintf (fp,"# (which is the height divided by 16)\n");
2586  fprintf (fp,"#\n");
2587  fprintf (fp,"SLICES_PER_FRAME 1\n");
2588  fprintf (fp,"\n");
2589  fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2590#if QT_VERSION < 0x040000
2591  fprintf (fp,"INPUT_DIR        %s\n",fMovieTempFolderPath.ascii());
2592#else
2593  fprintf (fp,"INPUT_DIR        %s\n",fMovieTempFolderPath.toStdString().c_str());
2594#endif
2595  fprintf (fp,"\n");
2596  fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2597  fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2598  fprintf (fp,"# way of numbering them.  See the manual for more information.\n");
2599  fprintf (fp,"INPUT\n");
2600  fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2601  fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2602  fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2603  fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2604  fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2605  fprintf (fp,"# if you do, too bad!!!\n");
2606  fprintf (fp,"#\n");
2607  fprintf (fp,"#\n");
2608  fprintf (fp,"Test*.ppm        [0-%d]\n",fRecordFrameNumber-1);
2609  fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2610  fprintf (fp,"# of files\n");
2611  fprintf (fp,"END_INPUT\n");
2612  fprintf (fp,"\n");
2613  fprintf (fp,"\n");
2614  fprintf (fp,"\n");
2615  fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2616  fprintf (fp,"\n");
2617  fprintf (fp,"# FULL or HALF -- must be upper case\n");
2618  fprintf (fp,"# Should be FULL for computer generated images\n");
2619  fprintf (fp,"PIXEL            FULL\n");
2620  fprintf (fp,"\n");
2621  fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2622  fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2623  fprintf (fp,"RANGE            10\n");
2624  fprintf (fp,"\n");
2625  fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2626  fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2627  fprintf (fp,"\n");
2628  fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2629  fprintf (fp,"PSEARCH_ALG      LOGARITHMIC\n");
2630  fprintf (fp,"\n");
2631  fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2632  fprintf (fp,"#\n");
2633  fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2634  fprintf (fp,"#\n");
2635  fprintf (fp,"BSEARCH_ALG      SIMPLE\n");
2636  fprintf (fp,"\n");
2637  fprintf (fp,"#\n");
2638  fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2639  fprintf (fp,"# (values must be between 1 and 31)\n");
2640  fprintf (fp,"# These are the Qscale values for the entire frame in variable bit-rate\n");
2641  fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2642  fprintf (fp,"#\n");
2643  fprintf (fp,"\n");
2644  fprintf (fp,"# Qscale (Quantization scale) affects quality and compression,\n");
2645  fprintf (fp,"# but has very little effect on speed.\n");
2646  fprintf (fp,"\n");
2647  fprintf (fp,"IQSCALE          4\n");
2648  fprintf (fp,"PQSCALE          5\n");
2649  fprintf (fp,"BQSCALE          12\n");
2650  fprintf (fp,"\n");
2651  fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2652  fprintf (fp,"REFERENCE_FRAME  ORIGINAL\n");
2653  fprintf (fp,"\n");
2654  fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2655  fprintf (fp,"\n");
2656  fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2657  fprintf (fp,"#BIT_RATE  1000000\n");
2658  fprintf (fp,"\n");
2659  fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2660  fprintf (fp,"BUFFER_SIZE 327680\n");
2661  fprintf (fp,"\n");
2662  fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2663  fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2664  fprintf (fp,"FRAME_RATE 30\n");
2665  fprintf (fp,"\n");
2666  fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2667  fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.\n");
2668  fprintf (fp,"\n");
2669  fprintf (fp,"\n");
2670  fclose (fp);
2671
2672  setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
2673  setRecordingStatus(READY_TO_ENCODE);
2674  return true;
2675}
2676
2677void G4OpenGLQtViewer::encodeVideo()
2678{
2679#ifdef GEANT4_QT_DEBUG
2680  printf("G4OpenGLQtViewer::encodeVideo \n");
2681#endif
2682  if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
2683    setRecordingStatus(ENCODING);
2684    fProcess = new QProcess();
2685    fProcess->start (fEncoderPath, QStringList(fMovieTempFolderPath+fParameterFileName));
2686#if QT_VERSION > 0x040100
2687        QObject ::connect(fProcess,SIGNAL(finished ( int,QProcess::ExitStatus)),
2688                      this,SLOT(processFinished( int)));
2689        QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2690                      this,SLOT(processStdout()));
2691#else
2692#if QT_VERSION > 0x040000
2693        QObject ::connect(fProcess,SIGNAL(finished ( int)),
2694                      this,SLOT(processFinished( int)));
2695        QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2696                      this,SLOT(processStdout()));
2697#else
2698        QObject ::connect(fProcess,SIGNAL(finished ( int)),
2699                      this,SLOT(processFinished( int)));
2700        QObject ::connect(fProcess,SIGNAL(readyReadStdOut ()),
2701                      this,SLOT(processStdout()));
2702#endif
2703#endif
2704  }
2705#ifdef GEANT4_QT_DEBUG
2706  printf("G4OpenGLQtViewer::encodeVideo END\n");
2707#endif
2708}
2709
2710
2711void G4OpenGLQtViewer::processStdout()
2712{
2713#if QT_VERSION > 0x040000
2714  QString tmp = fProcess->readAllStandardOutput ().data();
2715#else
2716  QString tmp = fProcess->readStdout ().data();
2717#endif
2718  int start = tmp.lastIndexOf("ESTIMATED TIME");
2719  tmp = tmp.mid(start,tmp.indexOf("\n",start)-start);
2720  setRecordingInfos(tmp);
2721}
2722
2723
2724void G4OpenGLQtViewer::processFinished(int exitCode)
2725{
2726#ifdef GEANT4_QT_DEBUG
2727  printf("processFinished \n");
2728#endif
2729
2730  QString txt = "";
2731  if (!exitCode) {
2732    setRecordingStatus(SUCCESS);
2733  } else {
2734        switch (fProcess->error()) {
2735          case QProcess::FailedToStart:
2736        txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2737                break;
2738          case QProcess::Crashed:
2739        txt = "The process crashed some time after starting successfully.\n";
2740                break;
2741          case QProcess::Timedout:
2742        txt = "The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.\n";
2743                break;
2744          case QProcess::WriteError:
2745        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";
2746            break;
2747          case QProcess::ReadError:
2748        txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2749            break;
2750          case QProcess::UnknownError:
2751        txt = "An unknown error occurred. This is the default return value of error().\n";
2752                break;
2753    }
2754    setRecordingStatus(FAILED);
2755  }
2756  setRecordingInfos(txt+removeTempFolder());
2757#ifdef GEANT4_QT_DEBUG
2758  printf("processFinished END\n");
2759#endif
2760}
2761
2762/*
2763 
2764void MultiLayer::exportToSVG(const QString& fname)
2765{
2766  QPicture picture;
2767  QPainter p(&picture);
2768  for (int i=0;i<(int)graphsList->count();i++)
2769    {
2770      Graph *gr=(Graph *)graphsList->at(i);
2771      Plot *myPlot= (Plot *)gr->plotWidget();
2772     
2773      QPoint pos=gr->pos();
2774     
2775      int width=int(myPlot->frameGeometry().width());
2776      int height=int(myPlot->frameGeometry().height());
2777     
2778      myPlot->print(&p, QRect(pos,QSize(width,height)));
2779    }
2780 
2781  p.end();
2782  picture.save(fname, "svg");
2783}
2784*/
2785#endif
Note: See TracBrowser for help on using the repository browser.