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

Last change on this file since 731 was 731, checked in by garnier, 17 years ago

debut de la boite de dialog pour les param video

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