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

Last change on this file since 1228 was 1228, checked in by garnier, 14 years ago

update geant4.9.3 tag

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