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

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

for qt3

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