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

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

en test pour les refresh, ne marche pas bien

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