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

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

error correct on Qt3.3. Improvement for movie

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