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

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

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

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