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

Last change on this file since 916 was 916, checked in by garnier, 15 years ago

renommage et suppression de EPS dans Qt

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