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

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

en test pas dans CVS

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