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

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

debug visu

  • Property svn:mime-type set to text/cpp
File size: 82.8 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26//
27// $Id: G4OpenGLQtViewer.cc,v 1.46 2010/01/06 15:05:29 lgarnier Exp $
28// GEANT4 tag $Name:  $
29//
30//
31// G4OpenGLQtViewer : Class to provide Qt specific
32//                     functionality for OpenGL in GEANT4
33//
34// 27/06/2003 : G.Barrand : implementation (at last !).
35
36#ifdef G4VIS_BUILD_OPENGLQT_DRIVER
37
38#include "G4OpenGLQtViewer.hh"
39#include "G4VViewer.hh"
40#include "G4VSceneHandler.hh"
41#include "G4OpenGLSceneHandler.hh"
42
43#include "G4ios.hh"
44#include "G4VisExtent.hh"
45#include "G4LogicalVolume.hh"
46#include "G4VSolid.hh"
47#include "G4Point3D.hh"
48#include "G4Normal3D.hh"
49#include "G4Scene.hh"
50#include "G4OpenGLQtExportDialog.hh"
51#include "G4OpenGLQtMovieDialog.hh"
52#include "G4UnitsTable.hh"
53#include "G4Qt.hh"
54#include "G4UImanager.hh"
55#include "G4UIcommandTree.hh"
56#include <qlayout.h>
57#include <qdialog.h>
58#include <qprocess.h>
59#include <qapplication.h>
60#include <qdesktopwidget.h>
61
62#if QT_VERSION >= 0x040000
63#include <qmenu.h>
64#include <qimagewriter.h>
65#else
66#include <qaction.h>
67#include <qwidgetlist.h>
68#include <qpopupmenu.h>
69#include <qimage.h>
70#endif
71
72#include <qapplication.h>
73#include <qmessagebox.h>
74#include <qfiledialog.h>
75#include <qprinter.h>
76#include <qdatetime.h>
77#include <qpainter.h>
78#include <qgl.h> // include <qglwidget.h>
79#include <qdialog.h>
80#include <qevent.h> //include <qcontextmenuevent.h>
81
82
83//////////////////////////////////////////////////////////////////////////////
84/**
85   Implementation of virtual method of G4VViewer
86*/
87void G4OpenGLQtViewer::SetView (
88)
89//////////////////////////////////////////////////////////////////////////////
90//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
91{
92  G4OpenGLViewer::SetView ();
93}
94
95
96
97
98//////////////////////////////////////////////////////////////////////////////
99void G4OpenGLQtViewer::CreateMainWindow (
100 QGLWidget* glWidget
101 ,QString name
102)
103//////////////////////////////////////////////////////////////////////////////
104//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
105{
106
107  if(fWindow) return; //Done.
108
109  fWindow = glWidget ;
110  //  fWindow->makeCurrent();
111
112#ifdef G4DEBUG_VIS_OGL
113  printf("G4OpenGLQtViewer::CreateMainWindow :: ++++++++++++++ add new TAB %s  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  glFlush ();
1439
1440  // L. Garnier 10/2009 : Not necessary and cause problems on mac OS X 10.6
1441  //  fWindow->swapBuffers ();
1442}
1443
1444/**
1445   Save the current mouse press point
1446   @param p mouse click point
1447*/
1448void G4OpenGLQtViewer::G4MousePressEvent(QMouseEvent *event)
1449{
1450#if QT_VERSION < 0x040000
1451  if ((event->button() & Qt::LeftButton)
1452      && !((event->state() & Qt::ShiftButton)
1453           || (event->state() & Qt::ControlButton)
1454           || (event->state() & Qt::AltButton)
1455           || (event->state() & Qt::MetaButton))) {
1456#else
1457  if ((event->buttons() & Qt::LeftButton)
1458      && !((event->modifiers() & Qt::ShiftModifier)
1459           || (event->modifiers() & Qt::ControlModifier)
1460           || (event->modifiers() & Qt::AltModifier)
1461           || (event->modifiers() & Qt::MetaModifier))) {
1462#endif
1463    fWindow->setMouseTracking(true);
1464    fAutoMove = false; // stop automove
1465    fLastPos1 = event->pos();
1466    fLastPos2 = fLastPos1;
1467    fLastPos3 = fLastPos2;
1468    fLastEventTime->start();
1469    if (fMouseAction == STYLE3){  // pick
1470      Pick(event->pos().x(),event->pos().y());
1471    }
1472  }
1473}
1474
1475/**
1476*/
1477void G4OpenGLQtViewer::G4MouseReleaseEvent()
1478{
1479  fSpinningDelay = fLastEventTime->elapsed();
1480  QPoint delta = (fLastPos3-fLastPos1);
1481  if ((delta.x() == 0) && (delta.y() == 0)) {
1482    return;
1483  }
1484  if (fSpinningDelay < fLaunchSpinDelay ) {
1485    fAutoMove = true;
1486    QTime lastMoveTime;
1487    lastMoveTime.start();
1488    // try to addapt speed move/rotate looking to drawing speed
1489    int cycles = 4;
1490    while (fAutoMove) {
1491      //      if ( lastMoveTime.elapsed() > (fSpinningDelay / (cycles/2))) {
1492        if (fMouseAction == STYLE1) {  // rotate
1493          rotateQtScene(((float)delta.x())/cycles,((float)delta.y())/cycles);
1494        } else if (fMouseAction == STYLE2) {  // move
1495          moveScene(-((float)delta.x())/cycles,-((float)delta.y())/cycles,0,true);
1496        }
1497        lastMoveTime.start();
1498        cycles = 1 ;
1499      ((QApplication*)G4Qt::getInstance ())->processEvents();
1500      cycles ++ ;
1501    }
1502  }
1503  fWindow->setMouseTracking(false);
1504
1505}
1506
1507
1508void G4OpenGLQtViewer::G4MouseDoubleClickEvent()
1509{
1510  fWindow->setMouseTracking(true);
1511}
1512
1513
1514/**
1515   @param pos_x mouse x position
1516   @param pos_y mouse y position
1517   @param mButtons mouse button active
1518   @param mAutoMove true: apply this move till another evnt came, false :one time move
1519*/
1520
1521void G4OpenGLQtViewer::G4MouseMoveEvent(QMouseEvent *event)
1522{
1523 
1524#if QT_VERSION < 0x040000
1525  Qt::ButtonState mButtons = event->state();
1526#else
1527  Qt::MouseButtons mButtons = event->buttons();
1528#endif
1529
1530  if (fAutoMove) {
1531    return;
1532  }
1533
1534  fLastPos3 = fLastPos2;
1535  fLastPos2 = fLastPos1;
1536  fLastPos1 = QPoint(event->x(), event->y());
1537
1538  int deltaX = fLastPos2.x()-fLastPos1.x();
1539  int deltaY = fLastPos2.y()-fLastPos1.y();
1540
1541  if (fMouseAction == STYLE1) {  // rotate
1542    if (mButtons & Qt::LeftButton) {
1543      rotateQtScene(deltaX,deltaY);
1544    }
1545  } else if (fMouseAction == STYLE2) {  // move
1546    if (mButtons & Qt::LeftButton) {
1547      moveScene(-deltaX,-deltaY,0,true);
1548    }
1549  }
1550
1551  fLastEventTime->start();
1552}
1553
1554
1555/**
1556   Move the scene of dx, dy, dz values.
1557   @param dx delta mouse x position
1558   @param dy delta mouse y position
1559   @param mouseMove : true if even comes from a mouse move, false if even comes from key action
1560*/
1561
1562void G4OpenGLQtViewer::moveScene(float dx,float dy, float dz,bool mouseMove)
1563{
1564  if (fHoldMoveEvent)
1565    return;
1566  fHoldMoveEvent = true;
1567
1568  G4double coefTrans = 0;
1569  GLdouble coefDepth = 0;
1570  if(mouseMove) {
1571    coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinWidth());
1572    if (getWinHeight() <getWinWidth()) {
1573      coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinHeight());
1574    }
1575  } else {
1576    coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1577    coefDepth = getSceneDepth()*fDeltaDepth;
1578  }
1579  fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1580  emit moveX(-dx*coefTrans);
1581  emit moveY(dy*coefTrans);
1582  emit moveZ(dz*coefTrans);
1583 
1584  updateQWidget();
1585  if (fAutoMove)
1586    ((QApplication*)G4Qt::getInstance ())->processEvents();
1587 
1588  fHoldMoveEvent = false;
1589}
1590
1591
1592/**
1593   @param dx delta mouse x position
1594   @param dy delta mouse y position
1595*/
1596
1597void G4OpenGLQtViewer::rotateQtScene(float dx, float dy)
1598{
1599  if (fHoldRotateEvent)
1600    return;
1601  fHoldRotateEvent = true;
1602 
1603  if( dx != 0) {
1604    rotateScene(dx,0,fDeltaRotation);
1605    emit rotateTheta(dx);
1606  }
1607  if( dy != 0) {
1608    rotateScene(0,dy,fDeltaRotation);
1609    emit rotatePhi(dy);
1610  }
1611  updateQWidget();
1612 
1613  fHoldRotateEvent = false;
1614}
1615
1616/**
1617   @param dx delta mouse x position
1618   @param dy delta mouse y position
1619*/
1620
1621void G4OpenGLQtViewer::rotateQtCamera(float dx, float dy)
1622{
1623  if (fHoldRotateEvent)
1624    return;
1625  fHoldRotateEvent = true;
1626
1627  rotateScene(dx,dy,fDeltaRotation);
1628  emit rotateTheta(dx);
1629  emit rotatePhi(dy);
1630  updateQWidget();
1631 
1632  fHoldRotateEvent = false;
1633}
1634
1635
1636
1637
1638/** This is the benning of a rescale function. It does nothing for the moment
1639    @param aWidth : new width
1640    @param aHeight : new height
1641*/
1642void G4OpenGLQtViewer::rescaleImage(
1643 int /* aWidth */
1644,int /* aHeight */
1645){
1646  //  GLfloat* feedback_buffer;
1647  //  GLint returned;
1648  //  FILE* file;
1649 
1650//   feedback_buffer = new GLfloat[size];
1651//   glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1652//   glRenderMode (GL_FEEDBACK);
1653 
1654//   DrawView();
1655//   returned = glRenderMode (GL_RENDER);
1656
1657}
1658
1659
1660
1661/**
1662   Generate Postscript or PDF form image
1663   @param aFilename : name of file
1664   @param aInColor : numbers of colors : 1->BW 2->RGB
1665   @param aImage : Image to print
1666*/
1667bool G4OpenGLQtViewer::printPDF (
1668 const std::string aFilename
1669,int aInColor
1670,QImage aImage
1671)
1672{
1673
1674#if QT_VERSION < 0x040000
1675#if defined(Q_WS_MAC) || defined(Q_WS_X11)
1676  QPrinter printer;
1677  //  printer.setPageSize(pageSize);
1678  if (aInColor == 1) {
1679    printer.setColorMode(QPrinter::GrayScale);
1680  } else {
1681    printer.setColorMode(QPrinter::Color);
1682  }
1683
1684  /* FIXME : I don't know which format it will save...
1685     if (aFilename.endsWith(".ps")) {
1686     printer.setOutputFormat(QPrinter::PostScriptFormat);
1687     } else {
1688     printer.setOutputFormat(QPrinter::PdfFormat);
1689     }
1690  */
1691  printer.setOutputFileName(aFilename);
1692  //  printer.setFullPage ( true);
1693  QPainter paint(&printer);
1694  paint.drawImage (0,0,aImage );
1695  paint.end();
1696#else
1697  G4cerr << "This fonction is only supported on Mac OsX or X11 with Qt3. Full platform supported with Qt4" << G4endl;
1698  // FIXME
1699  // L.Garnier 6 May 2009 : Only to fix compilation warnings
1700  if (aFilename.empty()) {
1701    aInColor = 0;
1702    aImage = 0;
1703  }
1704  // END_OF FIXME
1705#endif
1706#else
1707  QPrinter printer;
1708  //  printer.setPageSize(pageSize);
1709
1710  // FIXME : L. Garnier 4/12/07
1711  // This is not working, it does nothing. Image is staying in color mode
1712  // So I have desactivate the B/W button in GUI
1713  if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1714#if QT_VERSION < 0x040000
1715    aImage = aImage.convertDepth(1,Qt::MonoOnly);
1716#else
1717    aImage = aImage.convertToFormat ( aImage.format(), Qt::MonoOnly);
1718#endif
1719  }
1720
1721
1722  if (aFilename.substr(aFilename.size()-3) == ".ps") {
1723#if QT_VERSION > 0x040200
1724    printer.setOutputFormat(QPrinter::PostScriptFormat);
1725#endif
1726  } else {
1727#if QT_VERSION > 0x040100
1728    printer.setOutputFormat(QPrinter::PdfFormat);
1729#endif
1730  }
1731#if QT_VERSION > 0x040100
1732  printer.setOutputFileName(QString(aFilename.c_str()));
1733#endif
1734  //  printer.setFullPage ( true);
1735  QPainter paint(&printer);
1736  paint.drawImage (0,0,aImage);
1737  paint.end();
1738#endif
1739  return true;
1740}
1741
1742
1743void G4OpenGLQtViewer::G4wheelEvent (QWheelEvent * event)
1744{
1745  fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.GetZoomFactor()*(event->delta())/1200));
1746  updateQWidget();
1747}
1748
1749
1750void G4OpenGLQtViewer::G4keyPressEvent (QKeyEvent * event)
1751{
1752  if (fHoldKeyEvent)
1753    return;
1754
1755  fHoldKeyEvent = true;
1756
1757#if QT_VERSION < 0x040000
1758  if ((event->key() == Qt::Key_Down) && (event->state() & Qt::AltButton )) { // go backward
1759#else
1760  if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::AltModifier )) { // go backward
1761#endif
1762   
1763    moveScene(0,0,1,false);
1764  }
1765#if QT_VERSION < 0x040000
1766  else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::AltButton)) { // go forward
1767#else
1768  else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::AltModifier)) { // go forward
1769#endif
1770    moveScene(0,0,-1,false);
1771  }
1772#if QT_VERSION < 0x040000
1773  if ((event->key() == Qt::Key_Down) && (event->state() & Qt::ShiftButton)) { // rotate phi
1774#else
1775  if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
1776#endif
1777    rotateQtCamera(0,-1);
1778  }
1779#if QT_VERSION < 0x040000
1780  else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::ShiftButton)) { // rotate phi
1781#else
1782  else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
1783#endif
1784    rotateQtCamera(0,1);
1785  }
1786#if QT_VERSION < 0x040000
1787  if ((event->key() == Qt::Key_Left) && (event->state() & Qt::ShiftButton)) { // rotate theta
1788#else
1789  if ((event->key() == Qt::Key_Left) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
1790#endif
1791    rotateQtCamera(1,0);
1792  }
1793#if QT_VERSION < 0x040000
1794  else if ((event->key() == Qt::Key_Right) && (event->state() & Qt::ShiftButton)) { // rotate theta
1795#else
1796  else if ((event->key() == Qt::Key_Right) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
1797#endif
1798    rotateQtCamera(-1,0);
1799  }
1800
1801#if QT_VERSION < 0x040000
1802  if ((event->state() & Qt::AltButton)) {
1803#else
1804  if ((event->modifiers() & Qt::AltModifier)) {
1805#endif
1806    if (event->key() == Qt::Key_Plus) {
1807      fDeltaRotation = fDeltaRotation/0.7;
1808    }
1809    else if (event->key() == Qt::Key_Minus) {
1810      fDeltaRotation = fDeltaRotation*0.7;
1811    }
1812  } else {
1813    if (event->key() == Qt::Key_Plus) {
1814      fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
1815      updateQWidget();
1816    }
1817    else if (event->key() == Qt::Key_Minus) {
1818      fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
1819      updateQWidget();
1820    }
1821  }
1822 
1823 
1824  if (event->key() == Qt::Key_Escape) { // escaped from full screen
1825#if QT_VERSION >= 0x030200
1826      toggleFullScreen(false);
1827#endif
1828  }
1829  // several case here : If return is pressed, in every case -> display the movie parameters dialog
1830  // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
1831  // If encoder not found-> does nothing.Only display a message in status box
1832  // If all ok-> generate parameter file
1833  // If ok -> put encoder button enabled
1834 
1835  if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)){ // end of video
1836   stopVideo();
1837  }
1838  if (event->key() == Qt::Key_Space){ // start/pause of video
1839   startPauseVideo();
1840  }
1841
1842  // with no modifiers
1843#if QT_VERSION < 0x040000
1844  if (event->state() == Qt::NoButton) {
1845#else
1846  if ((event->modifiers() == Qt::NoModifier) || (event->modifiers() == Qt::KeypadModifier )) {
1847#endif
1848    if (event->key() == Qt::Key_Down) { // go down
1849      moveScene(0,1,0,false);
1850    }
1851    else if (event->key() == Qt::Key_Up) {  // go up
1852      moveScene(0,-1,0,false);
1853    }
1854    if (event->key() == Qt::Key_Left) { // go left
1855      moveScene(-1,0,0,false);
1856    }
1857    else if (event->key() == Qt::Key_Right) { // go right
1858      moveScene(1,0,0,false);
1859    }
1860  }
1861  fHoldKeyEvent = false;
1862}
1863 
1864
1865/** Stop the video. Check all parameters and enable encoder button if all is ok.
1866*/
1867void G4OpenGLQtViewer::stopVideo() {
1868
1869 // if encoder parameter is wrong, display parameters dialog and return
1870  if (!fMovieParametersDialog) {
1871    showMovieParametersDialog();
1872  }
1873  setRecordingStatus(STOP);
1874
1875  if (fRecordFrameNumber >0) {
1876    // check parameters if they were modified (Re APPLY them...)
1877    if (!(fMovieParametersDialog->checkEncoderSwParameters())) {
1878      setRecordingStatus(BAD_ENCODER);
1879    }  else if (!(fMovieParametersDialog->checkSaveFileNameParameters())) {
1880      setRecordingStatus(BAD_OUTPUT);
1881    }
1882  } else {
1883    resetRecording();
1884    setRecordingInfos("No frame to encode.");
1885  }
1886}
1887
1888/** Stop the video. Check all parameters and enable encoder button if all is ok.
1889*/
1890void G4OpenGLQtViewer::saveVideo() {
1891
1892  // if encoder parameter is wrong, display parameters dialog and return
1893  if (!fMovieParametersDialog) {
1894    showMovieParametersDialog();
1895  }
1896
1897  fMovieParametersDialog->checkEncoderSwParameters();
1898  fMovieParametersDialog->checkSaveFileNameParameters();
1899 
1900  if (fRecordingStep == STOP) {
1901    setRecordingStatus(SAVE);
1902    generateMpegEncoderParameters();
1903    encodeVideo();
1904  }
1905}
1906
1907
1908/** Start/Pause the video..
1909*/
1910void G4OpenGLQtViewer::startPauseVideo() {
1911   
1912  // first time, if temp parameter is wrong, display parameters dialog and return
1913
1914  if (( fRecordingStep == WAIT)) {
1915    if ( fRecordFrameNumber == 0) {
1916      if (getTempFolderPath() == "") { // BAD_OUTPUT
1917        showMovieParametersDialog();
1918        setRecordingInfos("You should specified the temp folder in order to make movie");
1919        return;
1920      } else  {
1921        // remove temp folder if it was create
1922        QString tmp = removeTempFolder();
1923        if (tmp !="") {
1924          setRecordingInfos(tmp);
1925          return;
1926        }
1927        tmp = createTempFolder();
1928        if (tmp != "") {
1929          setRecordingInfos("Can't create temp folder."+tmp);
1930          return;
1931        }
1932      }
1933    }
1934  }
1935  if ((fRecordingStep == WAIT)) {
1936    setRecordingStatus(START);
1937  } else if (fRecordingStep == START) {
1938    setRecordingStatus(PAUSE);
1939  } else if (fRecordingStep == PAUSE) {
1940    setRecordingStatus(CONTINUE);
1941  } else if (fRecordingStep == CONTINUE) {
1942    setRecordingStatus(PAUSE);
1943  }
1944}
1945
1946void G4OpenGLQtViewer::setRecordingStatus(RECORDING_STEP step) {
1947
1948  fRecordingStep = step;
1949  displayRecordingStatus();
1950}
1951
1952
1953void G4OpenGLQtViewer::displayRecordingStatus() {
1954 
1955  QString txtStatus = "";
1956  if (fRecordingStep == WAIT) {
1957    txtStatus  = "Waiting to start...";
1958    fRecordFrameNumber = 0; // reset the frame number
1959  } else if (fRecordingStep == START) {
1960    txtStatus  = "Start Recording...";
1961  } else if (fRecordingStep == PAUSE) {
1962    txtStatus  = "Pause Recording...";
1963  } else if (fRecordingStep == CONTINUE) {
1964    txtStatus  = "Continue Recording...";
1965  } else if (fRecordingStep == STOP) {
1966    txtStatus  = "Stop Recording...";
1967  } else if (fRecordingStep == READY_TO_ENCODE) {
1968    txtStatus  = "Ready to Encode...";
1969  } else if (fRecordingStep == ENCODING) {
1970    txtStatus  = "Encoding...";
1971  } else if (fRecordingStep == FAILED) {
1972    txtStatus  = "Failed to encode...";
1973  } else if ((fRecordingStep == BAD_ENCODER)
1974         || (fRecordingStep == BAD_OUTPUT)
1975             || (fRecordingStep == BAD_TMP)) {
1976    txtStatus  = "Correct above errors first";
1977  } else if (fRecordingStep == SUCCESS) {
1978    txtStatus  = "File encoded successfully";
1979  } else {
1980  }
1981
1982  if (fMovieParametersDialog) {
1983    fMovieParametersDialog->setRecordingStatus(txtStatus);
1984  } else {
1985#if QT_VERSION < 0x040000
1986    G4cout << txtStatus.ascii() << G4endl;
1987#else
1988    G4cout << txtStatus.toStdString().c_str() << G4endl;
1989#endif
1990  }
1991  setRecordingInfos("");
1992}
1993
1994
1995void G4OpenGLQtViewer::setRecordingInfos(QString txt) {
1996  if (fMovieParametersDialog) {
1997    fMovieParametersDialog->setRecordingInfos(txt);
1998  } else {
1999#if QT_VERSION < 0x040000
2000    G4cout << txt.ascii() << G4endl;
2001#else
2002    G4cout << txt.toStdString().c_str() << G4endl;
2003#endif
2004  }
2005}
2006
2007/** Init the movie parameters. Temp dir and encoder path
2008*/
2009void G4OpenGLQtViewer::initMovieParameters() {
2010  //init encoder
2011 
2012   //look for encoderPath
2013     fProcess = new QProcess();
2014     
2015#if QT_VERSION < 0x040000
2016     QObject ::connect(fProcess,SIGNAL(processExited ()),
2017                       this,SLOT(processLookForFinished()));
2018     fProcess->setCommunication(QProcess::DupStderr);
2019     fProcess->setArguments(QStringList("which mpeg_encode"));
2020     fProcess->start();
2021#else
2022     QObject ::connect(fProcess,SIGNAL(finished ( int)),
2023                       this,SLOT(processLookForFinished()));
2024     fProcess->setReadChannelMode(QProcess::MergedChannels);
2025     fProcess->start ("which mpeg_encode");
2026#endif
2027 
2028}
2029
2030/** @return encoder path or "" if it does not exist
2031 */
2032QString G4OpenGLQtViewer::getEncoderPath() {
2033  return fEncoderPath;
2034}
2035 
2036
2037/**
2038 * set the new encoder path
2039 * @return "" if correct. The error otherwise
2040*/
2041QString G4OpenGLQtViewer::setEncoderPath(QString path) {
2042  if (path == "") {
2043    return "File does not exist";
2044  }
2045
2046#if QT_VERSION < 0x040000
2047  path =  QDir::cleanDirPath(path);
2048#else
2049  path =  QDir::cleanPath(path);
2050#endif
2051  QFileInfo *f = new QFileInfo(path);
2052  if (!f->exists()) {
2053    return "File does not exist";
2054  } else if (f->isDir()) {
2055    return "This is a directory";
2056  } else if (!f->isExecutable()) {
2057    return "File exist but is not executable";
2058  } else if (!f->isFile()) {
2059    return "This is not a file";
2060  }
2061  fEncoderPath = path;
2062
2063  if ((fRecordingStep == BAD_ENCODER)) {
2064    setRecordingStatus(STOP);
2065  }
2066  return "";
2067}
2068
2069
2070bool G4OpenGLQtViewer::isRecording(){
2071  if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
2072    return true;
2073  }
2074  return false;
2075}
2076
2077bool G4OpenGLQtViewer::isPaused(){
2078  if (fRecordingStep == PAUSE) {
2079    return true;
2080  }
2081  return false;
2082}
2083
2084bool G4OpenGLQtViewer::isEncoding(){
2085  if (fRecordingStep == ENCODING) {
2086    return true;
2087  }
2088  return false;
2089}
2090
2091bool G4OpenGLQtViewer::isWaiting(){
2092  if (fRecordingStep == WAIT) {
2093    return true;
2094  }
2095  return false;
2096}
2097
2098bool G4OpenGLQtViewer::isStopped(){
2099  if (fRecordingStep == STOP) {
2100    return true;
2101  }
2102  return false;
2103}
2104
2105bool G4OpenGLQtViewer::isFailed(){
2106  if (fRecordingStep == FAILED) {
2107    return true;
2108  }
2109  return false;
2110}
2111
2112bool G4OpenGLQtViewer::isSuccess(){
2113  if (fRecordingStep == SUCCESS) {
2114    return true;
2115  }
2116  return false;
2117}
2118
2119bool G4OpenGLQtViewer::isBadEncoder(){
2120  if (fRecordingStep == BAD_ENCODER) {
2121    return true;
2122  }
2123  return false;
2124}
2125bool G4OpenGLQtViewer::isBadTmp(){
2126  if (fRecordingStep == BAD_TMP) {
2127    return true;
2128  }
2129  return false;
2130}
2131bool G4OpenGLQtViewer::isBadOutput(){
2132  if (fRecordingStep == BAD_OUTPUT) {
2133    return true;
2134  }
2135  return false;
2136}
2137
2138void G4OpenGLQtViewer::setBadEncoder(){
2139  fRecordingStep = BAD_ENCODER;
2140  displayRecordingStatus();
2141}
2142void G4OpenGLQtViewer::setBadTmp(){
2143  fRecordingStep = BAD_TMP;
2144  displayRecordingStatus();
2145}
2146void G4OpenGLQtViewer::setBadOutput(){
2147  fRecordingStep = BAD_OUTPUT;
2148  displayRecordingStatus();
2149}
2150
2151void G4OpenGLQtViewer::setWaiting(){
2152  fRecordingStep = WAIT;
2153  displayRecordingStatus();
2154}
2155
2156
2157bool G4OpenGLQtViewer::isReadyToEncode(){
2158  if (fRecordingStep == READY_TO_ENCODE) {
2159    return true;
2160  }
2161  return false;
2162}
2163
2164void G4OpenGLQtViewer::resetRecording() {
2165    setRecordingStatus(WAIT);
2166}
2167
2168/**
2169 * set the temp folder path
2170 * @return "" if correct. The error otherwise
2171*/
2172QString G4OpenGLQtViewer::setTempFolderPath(QString path) {
2173
2174  if (path == "") {
2175    return "Path does not exist";
2176  }
2177#if QT_VERSION < 0x040000
2178  path =  QDir::cleanDirPath(path);
2179#else
2180  path =  QDir::cleanPath(path);
2181#endif
2182  QFileInfo *d = new QFileInfo(path);
2183  if (!d->exists()) {
2184    return "Path does not exist";
2185  } else if (!d->isDir()) {
2186    return "This is not a directory";
2187  } else if (!d->isReadable()) {
2188    return path +" is read protected";
2189  } else if (!d->isWritable()) {
2190    return path +" is write protected";
2191  }
2192 
2193  if ((fRecordingStep == BAD_TMP)) {
2194    setRecordingStatus(WAIT);
2195  }
2196  fTempFolderPath = path;
2197  return "";
2198}
2199
2200/** @return the temp folder path or "" if it does not exist
2201 */
2202QString G4OpenGLQtViewer::getTempFolderPath() {
2203  return fTempFolderPath;
2204}
2205 
2206/**
2207 * set the save file name path
2208 * @return "" if correct. The error otherwise
2209*/
2210QString G4OpenGLQtViewer::setSaveFileName(QString path) {
2211
2212  if (path == "") {
2213    return "Path does not exist";
2214  }
2215 
2216  QFileInfo *file = new QFileInfo(path);
2217  QDir dir = file->dir();
2218#if QT_VERSION < 0x040000
2219  path =  QDir::cleanDirPath(path);
2220#else
2221  path =  QDir::cleanPath(path);
2222#endif
2223  if (file->exists()) {
2224    return "File already exist, please choose a new one";
2225  } else if (!dir.exists()) {
2226    return "Dir does not exist";
2227  } else if (!dir.isReadable()) {
2228    return path +" is read protected";
2229  }
2230 
2231  if ((fRecordingStep == BAD_OUTPUT)) {
2232    setRecordingStatus(STOP);
2233  }
2234  fSaveFileName = path;
2235  return "";
2236}
2237
2238/** @return the save file path
2239 */
2240QString G4OpenGLQtViewer::getSaveFileName() {
2241  return fSaveFileName ;
2242}
2243
2244/** Create a Qt_temp folder in the temp folder given
2245* The temp folder will be like this /tmp/QtMovie_12-02-2008_12_12_58/
2246* @return "" if success. Error message if not.
2247*/
2248QString G4OpenGLQtViewer::createTempFolder() {
2249  fMovieTempFolderPath = "";
2250  //check
2251  QString tmp = setTempFolderPath(fTempFolderPath);
2252  if (tmp != "") {
2253    return tmp;
2254  }
2255#if QT_VERSION < 0x040000
2256  QString sep = QChar(QDir::separator());
2257#else
2258  QString sep = QString(QDir::separator());
2259#endif
2260  QString path = sep+"QtMovie_"+QDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+sep;
2261#if QT_VERSION < 0x040000
2262  QDir *d = new QDir(QDir::cleanDirPath(fTempFolderPath));
2263#else
2264  QDir *d = new QDir(QDir::cleanPath(fTempFolderPath));
2265#endif
2266  // check if it is already present
2267  if (d->exists(path)) {
2268    return "Folder "+path+" already exists.Please remove it first";
2269  }
2270  if (d->mkdir(fTempFolderPath+path)) {
2271    fMovieTempFolderPath = fTempFolderPath+path;
2272    return "";
2273  } else {
2274    return "Can't create "+fTempFolderPath+path;
2275  }
2276  return "-";
2277}
2278
2279/** Remove the Qt_temp folder in the temp folder
2280*/
2281QString G4OpenGLQtViewer::removeTempFolder() {
2282        // remove files in Qt_temp folder
2283  if (fMovieTempFolderPath == "") {
2284    return "";
2285  }
2286#if QT_VERSION < 0x040000
2287  QDir *d = new QDir(QDir::cleanDirPath(fMovieTempFolderPath));
2288#else
2289  QDir *d = new QDir(QDir::cleanPath(fMovieTempFolderPath));
2290#endif
2291  if (!d->exists()) {
2292    return "";  // already remove
2293  }
2294
2295  d->setFilter( QDir::Files );
2296  QStringList subDirList = d->entryList();
2297  int res = true;
2298  QString error = "";
2299  for (QStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
2300    const QString currentFile = *it;
2301      if (!d->remove(currentFile)) {
2302        res = false;
2303        QString file = fMovieTempFolderPath+currentFile;
2304        error +="Removing file failed : "+file;
2305      } else {
2306      }
2307  }
2308  if (res) {
2309    if (d->rmdir(fMovieTempFolderPath)) {
2310      fMovieTempFolderPath = "";
2311      return "";
2312    } else {
2313      return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
2314    }
2315
2316  }
2317  return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
2318}
2319
2320
2321
2322bool G4OpenGLQtViewer::hasPendingEvents () {
2323  return ((QApplication*)G4Qt::getInstance ())->hasPendingEvents ();
2324}
2325
2326bool G4OpenGLQtViewer::generateMpegEncoderParameters () {
2327
2328                // save the parameter file
2329  FILE* fp;
2330#if QT_VERSION < 0x040000
2331  fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).ascii(), "w");
2332#else
2333  fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).toStdString().c_str(), "w");
2334#endif
2335
2336  if (fp == NULL) {
2337    setRecordingInfos("Generation of parameter file failed");
2338    return false;
2339  }
2340
2341  fprintf (fp,"# parameter file template with lots of comments to assist you\n");
2342  fprintf (fp,"#\n");
2343  fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
2344  fprintf (fp,"# the copy\n");
2345  fprintf (fp,"#\n");
2346  fprintf (fp,"#\n");
2347  fprintf (fp,"# any line beginning with '#' is a comment\n");
2348  fprintf (fp,"#\n");
2349  fprintf (fp,"# no line should be longer than 255 characters\n");
2350  fprintf (fp,"#\n");
2351  fprintf (fp,"#\n");
2352  fprintf (fp,"# general format of each line is:\n");
2353  fprintf (fp,"#          \n");
2354  fprintf (fp,"#\n");
2355  fprintf (fp,"# lines can generally be in any order\n");
2356  fprintf (fp,"#\n");
2357  fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
2358  fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
2359  fprintf (fp,"#\n");
2360  fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
2361  fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
2362  fprintf (fp,"# the INPUT parameter.\n");
2363  fprintf (fp,"#\n");
2364  fprintf (fp,"#  MUST be in UPPER CASE\n");
2365  fprintf (fp,"#\n");
2366  fprintf (fp,"\n");
2367  fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
2368  fprintf (fp,"# for more info.\n");
2369  fprintf (fp,"\n");
2370  fprintf (fp,"PATTERN          IBBPBBPBBPBBPBBP\n");
2371#if QT_VERSION < 0x040000
2372  fprintf (fp,"OUTPUT           %s\n",getSaveFileName().ascii());
2373#else
2374  fprintf (fp,"OUTPUT           %s\n",getSaveFileName().toStdString().c_str());
2375#endif
2376  fprintf (fp,"\n");
2377  fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
2378  fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
2379  fprintf (fp,"#\n");
2380  fprintf (fp,"# You must specify the type of the input files.  The choices are:\n");
2381  fprintf (fp,"#    YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
2382  fprintf (fp,"#        (must be upper case)\n");
2383  fprintf (fp,"#\n");
2384  fprintf (fp,"BASE_FILE_FORMAT PPM\n");
2385  fprintf (fp,"\n");
2386  fprintf (fp,"#\n");
2387  fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
2388  fprintf (fp,"# YUV_SIZE       widthxheight\n");
2389  fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
2390  fprintf (fp,"# on just one machine\n");
2391  fprintf (fp,"#\n");
2392  fprintf (fp,"YUV_SIZE 352x240\n");
2393  fprintf (fp,"\n");
2394  fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
2395  fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
2396  fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2397  fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
2398  fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
2399  fprintf (fp,"# to specify the file order.\n");
2400  fprintf (fp,"\n");
2401  fprintf (fp,"INPUT_FORMAT UCB\n");
2402  fprintf (fp,"\n");
2403  fprintf (fp,"# the conversion statement\n");
2404  fprintf (fp,"#\n");
2405  fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
2406  fprintf (fp,"#\n");
2407  fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
2408  fprintf (fp,"#        INPUT_CONVERT   giftoppm *\n");
2409  fprintf (fp,"#\n");
2410  fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2411  fprintf (fp,"#        INPUT_CONVERT   cat *.Y *.U *.V\n");
2412  fprintf (fp,"#\n");
2413  fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
2414  fprintf (fp,"#        INPUT_CONVERT   goto frame *; grabppm\n");
2415  fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2416  fprintf (fp,"#\n");
2417  fprintf (fp,"INPUT_CONVERT    * \n");
2418  fprintf (fp,"\n");
2419  fprintf (fp,"# number of frames in a GOP.\n");
2420  fprintf (fp,"#\n");
2421  fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
2422  fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2423  fprintf (fp,"#\n");
2424  fprintf (fp,"# later, will add more flexible GOP signalling\n");
2425  fprintf (fp,"#\n");
2426  fprintf (fp,"GOP_SIZE 16\n");
2427  fprintf (fp,"\n");
2428  fprintf (fp,"# number of slices in a frame\n");
2429  fprintf (fp,"#\n");
2430  fprintf (fp,"# 1 is a good number.  another possibility is the number of macroblock rows\n");
2431  fprintf (fp,"# (which is the height divided by 16)\n");
2432  fprintf (fp,"#\n");
2433  fprintf (fp,"SLICES_PER_FRAME 1\n");
2434  fprintf (fp,"\n");
2435  fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2436#if QT_VERSION < 0x040000
2437  fprintf (fp,"INPUT_DIR        %s\n",fMovieTempFolderPath.ascii());
2438#else
2439  fprintf (fp,"INPUT_DIR        %s\n",fMovieTempFolderPath.toStdString().c_str());
2440#endif
2441  fprintf (fp,"\n");
2442  fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2443  fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2444  fprintf (fp,"# way of numbering them.  See the manual for more information.\n");
2445  fprintf (fp,"INPUT\n");
2446  fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2447  fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2448  fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2449  fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2450  fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2451  fprintf (fp,"# if you do, too bad!!!\n");
2452  fprintf (fp,"#\n");
2453  fprintf (fp,"#\n");
2454  fprintf (fp,"Test*.ppm        [0-%d]\n",fRecordFrameNumber-1);
2455  fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2456  fprintf (fp,"# of files\n");
2457  fprintf (fp,"END_INPUT\n");
2458  fprintf (fp,"\n");
2459  fprintf (fp,"\n");
2460  fprintf (fp,"\n");
2461  fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2462  fprintf (fp,"\n");
2463  fprintf (fp,"# FULL or HALF -- must be upper case\n");
2464  fprintf (fp,"# Should be FULL for computer generated images\n");
2465  fprintf (fp,"PIXEL            FULL\n");
2466  fprintf (fp,"\n");
2467  fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2468  fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2469  fprintf (fp,"RANGE            10\n");
2470  fprintf (fp,"\n");
2471  fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2472  fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2473  fprintf (fp,"\n");
2474  fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2475  fprintf (fp,"PSEARCH_ALG      LOGARITHMIC\n");
2476  fprintf (fp,"\n");
2477  fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2478  fprintf (fp,"#\n");
2479  fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2480  fprintf (fp,"#\n");
2481  fprintf (fp,"BSEARCH_ALG      SIMPLE\n");
2482  fprintf (fp,"\n");
2483  fprintf (fp,"#\n");
2484  fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2485  fprintf (fp,"# (values must be between 1 and 31)\n");
2486  fprintf (fp,"# These are the Qscale values for the entire frame in variable bit-rate\n");
2487  fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2488  fprintf (fp,"#\n");
2489  fprintf (fp,"\n");
2490  fprintf (fp,"# Qscale (Quantization scale) affects quality and compression,\n");
2491  fprintf (fp,"# but has very little effect on speed.\n");
2492  fprintf (fp,"\n");
2493  fprintf (fp,"IQSCALE          4\n");
2494  fprintf (fp,"PQSCALE          5\n");
2495  fprintf (fp,"BQSCALE          12\n");
2496  fprintf (fp,"\n");
2497  fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2498  fprintf (fp,"REFERENCE_FRAME  ORIGINAL\n");
2499  fprintf (fp,"\n");
2500  fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2501  fprintf (fp,"\n");
2502  fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2503  fprintf (fp,"#BIT_RATE  1000000\n");
2504  fprintf (fp,"\n");
2505  fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2506  fprintf (fp,"BUFFER_SIZE 327680\n");
2507  fprintf (fp,"\n");
2508  fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2509  fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2510  fprintf (fp,"FRAME_RATE 30\n");
2511  fprintf (fp,"\n");
2512  fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2513  fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.\n");
2514  fprintf (fp,"\n");
2515  fprintf (fp,"\n");
2516  fclose (fp);
2517
2518  setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
2519  setRecordingStatus(READY_TO_ENCODE);
2520  return true;
2521}
2522
2523void G4OpenGLQtViewer::encodeVideo()
2524{
2525  if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
2526    setRecordingStatus(ENCODING);
2527   
2528#if QT_VERSION < 0x040000
2529    QStringList args = QStringList(fEncoderPath);
2530    args.push_back(fMovieTempFolderPath+fParameterFileName);
2531    fProcess = new QProcess(args);
2532    QObject ::connect(fProcess,SIGNAL(processExited ()),
2533                      this,SLOT(processEncodeFinished()));
2534    QObject ::connect(fProcess,SIGNAL(readyReadStdout ()),
2535                      this,SLOT(processEncodeStdout()));
2536    fProcess->setCommunication(QProcess::DupStderr);
2537    fProcess->launch("");
2538#else
2539    fProcess = new QProcess();
2540#if QT_VERSION > 0x040100
2541    QObject ::connect(fProcess,SIGNAL(finished ( int,QProcess::ExitStatus)),
2542                      this,SLOT(processEncodeFinished()));
2543    QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2544                      this,SLOT(processEncodeStdout()));
2545#else
2546    QObject ::connect(fProcess,SIGNAL(finished ( int)),
2547                      this,SLOT(processEncodeFinished()));
2548    QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2549                      this,SLOT(processEncodeStdout()));
2550#endif
2551    fProcess->setReadChannelMode(QProcess::MergedChannels);
2552    fProcess->start (fEncoderPath, QStringList(fMovieTempFolderPath+fParameterFileName));
2553#endif
2554  }
2555}
2556
2557
2558// FIXME : does not work on Qt3
2559void G4OpenGLQtViewer::processEncodeStdout()
2560{
2561#if QT_VERSION > 0x040000
2562  QString tmp = fProcess->readAllStandardOutput ().data();
2563  int start = tmp.lastIndexOf("ESTIMATED TIME");
2564  tmp = tmp.mid(start,tmp.indexOf("\n",start)-start);
2565#else
2566  QString tmp = fProcess->readStdout ().data();
2567  int start = tmp.findRev("ESTIMATED TIME");
2568  tmp = tmp.mid(start,tmp.find("\n",start)-start);
2569#endif
2570  setRecordingInfos(tmp);
2571}
2572
2573
2574void G4OpenGLQtViewer::processEncodeFinished()
2575{
2576
2577  QString txt = "";
2578  txt = getProcessErrorMsg();
2579  if (txt == "") {
2580    setRecordingStatus(SUCCESS);
2581  } else {
2582    setRecordingStatus(FAILED);
2583  }
2584  //  setRecordingInfos(txt+removeTempFolder());
2585}
2586
2587
2588void G4OpenGLQtViewer::processLookForFinished()
2589 {
2590
2591  QString txt = getProcessErrorMsg();
2592  if (txt != "") {
2593    fEncoderPath = "";
2594  } else {
2595#if QT_VERSION > 0x040000
2596    fEncoderPath = QString(fProcess->readAllStandardOutput ().data()).trimmed();
2597#else
2598    fEncoderPath = QString(fProcess->readStdout ().data()).simplifyWhiteSpace();
2599#endif
2600    // if not found, return "not found"
2601    if (fEncoderPath.contains(" ")) {
2602      fEncoderPath = "";
2603    } else if (!fEncoderPath.contains("mpeg_encode")) {
2604      fEncoderPath = "";
2605    }
2606    setEncoderPath(fEncoderPath);
2607  }
2608  // init temp folder
2609#if QT_VERSION > 0x040000
2610  setTempFolderPath(QDir::temp ().absolutePath ());
2611#else
2612  // Let's have a try
2613  setTempFolderPath("/tmp/");
2614#endif
2615}
2616
2617
2618QString G4OpenGLQtViewer::getProcessErrorMsg()
2619{
2620  QString txt = "";
2621#if QT_VERSION < 0x040000
2622  if (!fProcess->normalExit ()) {
2623    txt = "Exist status "+ fProcess->exitStatus ();
2624  }
2625#else
2626  if (fProcess->exitCode() != 0) {
2627    switch (fProcess->error()) {
2628    case QProcess::FailedToStart:
2629      txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2630      break;
2631    case QProcess::Crashed:
2632      txt = "The process crashed some time after starting successfully.\n";
2633      break;
2634    case QProcess::Timedout:
2635      txt = "The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.\n";
2636      break;
2637    case QProcess::WriteError:
2638      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";
2639      break;
2640    case QProcess::ReadError:
2641      txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2642      break;
2643    case QProcess::UnknownError:
2644      txt = "An unknown error occurred. This is the default return value of error().\n";
2645      break;
2646    }
2647  }
2648#endif
2649   return txt;
2650}
2651
2652
2653
2654
2655QWidget *G4OpenGLQtViewer::getParentWidget()
2656{
2657  // launch Qt if not
2658  G4Qt* interactorManager = G4Qt::getInstance ();
2659  G4UImanager* UI = G4UImanager::GetUIpointer();
2660#ifdef G4DEBUG_VIS_OGL
2661  //  printf("G4OpenGLQtViewer::getParentWidget :: UImanager %d  G4Qt:%d et via GetUIQt:%d---------------------\n",UI,UI->GetSession(),interactorManager,interactorManager->GetUIVisWidget());
2662#endif
2663 
2664  bool found = false;
2665 
2666  // create window
2667  if (((QApplication*)interactorManager->GetMainInteractor())) {
2668    // look for the main window
2669#if QT_VERSION < 0x040000
2670    // theses lines does nothing exept this one "GLWindow = new QDialog(0..."
2671    // but if I comment them, it doesn't work...
2672    QWidgetList  *list = QApplication::allWidgets();
2673    QWidgetListIt it( *list );         // iterate over the widgets
2674    QWidget * widget;
2675    while ( (widget=it.current()) != 0 ) {  // for each widget...
2676      ++it;
2677      if ((found== false) && (widget->inherits("QMainWindow"))) {
2678        fGLWindow = new QDialog(0,0,FALSE,Qt::WStyle_Title | Qt::WStyle_SysMenu | Qt::WStyle_MinMax );
2679        found = true;
2680      }
2681    }
2682    delete list;                      // delete the list, not the widgets
2683#else
2684    foreach (QWidget *widget, QApplication::allWidgets()) {
2685      if ((found== false) && (widget->inherits("QMainWindow"))) {
2686        fGLWindow = new QDialog(widget,Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
2687        found = true;
2688      }
2689    }
2690#endif
2691   
2692    if (found==false) {
2693#ifdef G4DEBUG_VIS_OGL
2694      printf("G4OpenGLQtViewer::CreateMainWindow case Qapp exist, but not found\n");
2695#endif
2696      fGLWindow = new QDialog();
2697    }
2698  } else {
2699#ifdef G4DEBUG_VIS_OGL
2700    printf("G4OpenGLQtViewer::CreateMainWindow case Qapp exist\n");
2701#endif
2702    fGLWindow = new QDialog();
2703#ifdef G4DEBUG_VIS_OGL
2704    printf("G4OpenGLQtViewer::GetParentWidget fGLWindow:%d \n",fGLWindow);
2705#endif
2706  }
2707  if (found) {
2708    return fGLWindow;
2709  } else {
2710    return NULL;
2711  }
2712}
2713
2714/*
2715 
2716void MultiLayer::exportToSVG(const QString& fname)
2717{
2718  QPicture picture;
2719  QPainter p(&picture);
2720  for (int i=0;i<(int)graphsList->count();i++)
2721    {
2722      Graph *gr=(Graph *)graphsList->at(i);
2723      Plot *myPlot= (Plot *)gr->plotWidget();
2724     
2725      QPoint pos=gr->pos();
2726     
2727      int width=int(myPlot->frameGeometry().width());
2728      int height=int(myPlot->frameGeometry().height());
2729     
2730      myPlot->print(&p, QRect(pos,QSize(width,height)));
2731    }
2732 
2733  p.end();
2734  picture.save(fname, "svg");
2735}
2736*/
2737#endif
Note: See TracBrowser for help on using the repository browser.