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

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

Update pour les Tabs

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