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

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

update ti head

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