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

Last change on this file since 755 was 755, checked in by garnier, 17 years ago

corrections pour Qt3 mises sous cvs

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