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

Last change on this file since 955 was 955, checked in by garnier, 15 years ago

prepartion du tag

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