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

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

fix warnings

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