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

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

correction du ticket #120

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