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

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

pre-tag revision and some improvments

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