source: trunk/source/visualization/OpenGL/src/G4OpenGLQtViewer.cc @ 898

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

x,y position should be ok

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