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

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

merge fini corrections en cours NE COMPILE PAS

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