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

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

bugged version

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