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

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

en cours de debug

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