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

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

update

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