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

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

r844@wl-72126: garnier | 2008-05-20 19:09:54 +0200
retour a la case depart

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