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

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

debugging

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