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

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

fix for tab

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