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

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

preparation to integrate Vis in UI for Qt

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