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

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

r842@wl-72126: garnier | 2008-05-20 18:34:31 +0200
ca ne marche pas, les calculs sont approximatifs et a moitie faux

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