source: trunk/geant4/visualization/OpenGL/src/G4OpenGLQtViewer.cc @ 797

Last change on this file since 797 was 797, checked in by garnier, 16 years ago

r832@wl-72126: garnier | 2008-05-13 18:30:21 +0200
mise a jour du SPINNING

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