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

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

debut de la boite de dialog pour les param video

  • Property svn:mime-type set to text/cpp
File size: 72.3 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  ,fEncoderPath(NULL)
304{
305#ifdef GEANT4_QT_DEBUG
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(actionCreateEPS()));
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(actionCreateEPS()));
657#endif
658
659#if QT_VERSION < 0x040000
660#if QT_VERSION < 0x030200
661  QAction *createMovie =  new QAction("&Make movie ...","&Make movie ...",CTRL+Key_M,mActions,0,true);
662#else
663  QAction *createMovie =  new QAction("&Make movie ...",CTRL+Key_M,mActions);
664#endif
665  createMovie->addTo(mActions);
666  QObject ::connect(createMovie,
667                    SIGNAL(activated()),
668                    this,
669                    SLOT(actionCreateMovie()));
670
671#else
672  // === Action Menu ===
673  QAction *createMovie = mActions->addAction("Make movie ...");
674  QObject ::connect(createMovie,
675                    SIGNAL(triggered()),
676                    this,
677                    SLOT(actionCreateMovie()));
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::actionCreateEPS() {
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::actionCreateEPS() \n");
1446#endif
1447}
1448
1449
1450void G4OpenGLQtViewer::actionCreateMovie() {
1451
1452  G4OpenGLQtMovieDialog* movieDialog= new G4OpenGLQtMovieDialog(GLWindow);
1453  movieDialog->show();
1454#ifdef GEANT4_QT_DEBUG
1455  printf("G4OpenGLQtViewer::actionCreateMovie() \n");
1456#endif
1457}
1458
1459/*
1460// 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
1461
1462void Graph::exportToSVG(const QString& fname)
1463{
1464  // enable workaround for Qt3 misalignments
1465  QwtPainter::setSVGMode(true);
1466  QPicture picture;
1467  QPainter p(&picture);
1468  d_plot->print(&p, d_plot->rect());
1469  p.end();
1470
1471  picture.save(fname, "svg");
1472}
1473*/
1474
1475
1476
1477
1478/**
1479   Save the current mouse press point
1480   @param p mouse click point
1481*/
1482#if QT_VERSION < 0x040000
1483void G4OpenGLQtViewer::G4MousePressEvent(QPoint p,Qt::ButtonState mButtons)
1484#else
1485void G4OpenGLQtViewer::G4MousePressEvent(QPoint p,Qt::MouseButtons mButtons)
1486#endif
1487{
1488  fAutoMove = false; // stop automove
1489  fLastPos = p;
1490  if (fMouseAction == STYLE2){  // pick
1491    Pick(p.x(),p.y());
1492  }
1493}
1494
1495
1496/**
1497   @param pos_x mouse x position
1498   @param pos_y mouse y position
1499   @param mButtons mouse button active
1500   @param mAutoMove true: apply this move till another evnt came, false :one time move
1501*/
1502
1503#if QT_VERSION < 0x040000
1504void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::ButtonState mButtons,bool mAutoMove)
1505#else
1506  void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::MouseButtons mButtons,bool mAutoMove)
1507#endif
1508{
1509  fAutoMove = mAutoMove;
1510
1511  if (!fAutoMove) {  // keep old delta if automove
1512    fDeltaPosX = fLastPos.x() - pos_x;
1513    fDeltaPosY = fLastPos.y() - pos_y;
1514  }
1515
1516  if ((fDeltaPosX == 0) && (fDeltaPosY == 0)) {
1517    fAutoMove = false;
1518  }
1519
1520  if (fMouseAction == STYLE1) {  // rotate
1521    if (mButtons & Qt::LeftButton) {
1522      rotateScene(fDeltaPosX,fDeltaPosY,fAutoMove);
1523    }
1524  } else if (fMouseAction == STYLE2) {  // move
1525    if (mButtons & Qt::LeftButton) {
1526      if (fAutoMove) {
1527        while (fAutoMove) {
1528          moveScene(-fDeltaPosX,-fDeltaPosY,0,true,true);
1529          ((QApplication*)G4Qt::getInstance ())->processEvents();
1530        }
1531      } else {
1532        moveScene(-fDeltaPosX,-fDeltaPosY,0,true,false);
1533      }
1534    }
1535  }
1536  fLastPos = QPoint(pos_x, pos_y);
1537}
1538
1539
1540/**
1541   Move the scene of dx, dy, dz values.
1542   @param dx delta mouse x position
1543   @param dy delta mouse y position
1544   @param mouseMove : true if even comes froma mouse move, false if even comes from key action
1545*/
1546
1547void G4OpenGLQtViewer::moveScene(G4double dx,G4double dy, G4double dz,bool mouseMove,bool mAutoMove)
1548{
1549  if (fHoldMoveEvent)
1550    return;
1551  fHoldMoveEvent = true;
1552
1553  if( mAutoMove == false) {
1554    fAutoMove = true;
1555  }
1556  G4double coefTrans = 0;
1557  GLdouble coefDepth = 0;
1558  while (fAutoMove) {
1559    if( mAutoMove == false) {
1560      fAutoMove = false;
1561    }
1562    if(mouseMove) {
1563      coefTrans = ((G4double)getSceneNearWidth())/((G4double)WinSize_x);
1564      if (WinSize_y <WinSize_x) {
1565        coefTrans = ((G4double)getSceneNearWidth())/((G4double)WinSize_y);
1566      }
1567    } else {
1568      coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1569      coefDepth = getSceneDepth()*fDeltaDepth;
1570    }
1571    fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1572   
1573    updateQWidget();
1574    if (fAutoMove)
1575      ((QApplication*)G4Qt::getInstance ())->processEvents();
1576  }
1577
1578  fHoldMoveEvent = false;
1579}
1580
1581
1582/**
1583   @param dx delta mouse x position
1584   @param dy delta mouse y position
1585*/
1586
1587void G4OpenGLQtViewer::rotateScene(G4double dx, G4double dy,bool mAutoRotate)
1588{
1589  if (fHoldRotateEvent)
1590    return;
1591  fHoldRotateEvent = true;
1592
1593  if( mAutoRotate == false) {
1594    fAutoMove = true;
1595  }
1596  G4Vector3D vp;
1597  G4Vector3D up;
1598 
1599  G4Vector3D xprime;
1600  G4Vector3D yprime;
1601  G4Vector3D zprime;
1602 
1603  G4double delta_alpha;
1604  G4double delta_theta;
1605 
1606  G4Vector3D new_vp;
1607  G4Vector3D new_up;
1608 
1609  G4double cosalpha;
1610  G4double sinalpha;
1611 
1612  G4Vector3D a1;
1613  G4Vector3D a2;
1614  G4Vector3D delta;
1615  G4Vector3D viewPoint;
1616
1617  while (fAutoMove) {
1618    if( mAutoRotate == false) {
1619      fAutoMove = false;
1620    }
1621   
1622    //phi spin stuff here
1623 
1624    vp = fVP.GetViewpointDirection ().unit ();
1625    up = fVP.GetUpVector ().unit ();
1626 
1627    yprime = (up.cross(vp)).unit();
1628    zprime = (vp.cross(yprime)).unit();
1629 
1630    if (fVP.GetLightsMoveWithCamera()) {
1631      delta_alpha = dy * fDeltaRotation;
1632      delta_theta = -dx * fDeltaRotation;
1633    } else {
1634      delta_alpha = -dy * fDeltaRotation;
1635      delta_theta = dx * fDeltaRotation;
1636    }   
1637 
1638    delta_alpha *= deg;
1639    delta_theta *= deg;
1640 
1641    new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
1642
1643    // to avoid z rotation flipping
1644    // to allow more than 360° rotation
1645    if (fVP.GetLightsMoveWithCamera()) {
1646      new_up = (new_vp.cross(yprime)).unit();
1647      if (new_vp.z()*vp.z() <0) {
1648        new_up.set(new_up.x(),-new_up.y(),new_up.z());
1649      }
1650    } else {
1651      new_up = up;
1652      if (new_vp.z()*vp.z() <0) {
1653        new_up.set(new_up.x(),-new_up.y(),new_up.z());
1654      }
1655    }
1656    fVP.SetUpVector(new_up);
1657    ////////////////
1658    // Rotates by fixed azimuthal angle delta_theta.
1659   
1660    cosalpha = new_up.dot (new_vp.unit());
1661    sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
1662    yprime = (new_up.cross (new_vp.unit())).unit ();
1663    xprime = yprime.cross (new_up);
1664    // Projection of vp on plane perpendicular to up...
1665    a1 = sinalpha * xprime;
1666    // Required new projection...
1667    a2 = sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
1668    // Required Increment vector...
1669    delta = a2 - a1;
1670    // So new viewpoint is...
1671    viewPoint = new_vp.unit() + delta;
1672   
1673#ifdef GEANT4_QT_DEBUG
1674//      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);
1675//      printf("up : %f %f %f\n",up.x(),up.y(),up.z());
1676//      printf("new up : %f %f %f\n",new_up.x(),new_up.y(),new_up.z());
1677//      printf("vp : %f %f %f\n",vp.x(),vp.y(),vp.z());
1678//      printf("new_vp : %f %f %f\n",new_vp.x(),new_vp.y(),new_vp.z());
1679#endif
1680    fVP.SetViewAndLights (viewPoint);
1681    updateQWidget();
1682   
1683    if (fAutoMove)
1684      ((QApplication*)G4Qt::getInstance ())->processEvents();
1685  }
1686 
1687  fHoldRotateEvent = false;
1688}
1689
1690/** This is the benning of a rescale function. It does nothing for the moment
1691    @param aWidth : new width
1692    @param aHeight : new height
1693*/
1694void G4OpenGLQtViewer::rescaleImage(
1695 int aWidth
1696,int aHeight
1697){
1698#ifdef GEANT4_QT_DEBUG
1699  printf("should rescale \n");
1700#endif
1701  GLfloat* feedback_buffer;
1702  GLint returned;
1703  FILE* file;
1704 
1705//   feedback_buffer = new GLfloat[size];
1706//   glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1707//   glRenderMode (GL_FEEDBACK);
1708 
1709//   glViewport (0, 0, aWidth, aHeight);
1710//   DrawView();
1711//   returned = glRenderMode (GL_RENDER);
1712
1713}
1714
1715/**
1716   Generate Vectorial Encapsulated Postscript form image
1717   @param aFilename : name of file
1718   @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1719   @param aImage : Image to print
1720*/
1721bool G4OpenGLQtViewer::generateVectorEPS (
1722 QString aFilename
1723,int aWidth
1724,int aHeight
1725,QImage aImage
1726)
1727{
1728  // Print vectored PostScript
1729 
1730  G4int size = 5000000;
1731
1732  GLfloat* feedback_buffer;
1733  GLint returned;
1734  FILE* file;
1735 
1736  feedback_buffer = new GLfloat[size];
1737  glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1738  glRenderMode (GL_FEEDBACK);
1739 
1740  int side = aWidth;
1741  if (aHeight < aWidth) side = aHeight;
1742  glViewport((aWidth - side) / 2, (aHeight - side) / 2, side, side);
1743  DrawView();
1744
1745  returned = glRenderMode (GL_RENDER);
1746 
1747 
1748#if QT_VERSION < 0x040000
1749  file = fopen (aFilename.ascii(), "w");
1750#else
1751  file = fopen (aFilename.toStdString().c_str(), "w");
1752#endif
1753  if (file) {
1754    spewWireframeEPS (file, returned, feedback_buffer, "rendereps");
1755  } else {
1756#if QT_VERSION < 0x040000
1757    G4cerr << "Could not open "<< aFilename.ascii()<<"\n" << G4endl;
1758#else
1759    G4cerr << "Could not open "<< aFilename.toStdString().c_str()<<"\n" << G4endl;
1760#endif
1761  }
1762 
1763  delete[] feedback_buffer;
1764
1765  return true;
1766}
1767
1768/**
1769   Generate Encapsulated Postscript form image
1770   @param aFilename : name of file
1771   @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1772   @param aImage : Image to print
1773*/
1774bool G4OpenGLQtViewer::generateEPS (
1775 QString aFilename
1776,int aInColor
1777,QImage aImage
1778)
1779{
1780  // FIXME
1781#ifdef GEANT4_QT_DEBUG
1782  printf("saving EPS\n");
1783#endif
1784
1785  FILE* fp;
1786
1787  if (aImage.bits () == NULL)
1788    return false;
1789 
1790#if QT_VERSION < 0x040000
1791  fp = fopen (aFilename.ascii(), "w");
1792#else
1793  fp = fopen (aFilename.toStdString().c_str(), "w");
1794#endif
1795  if (fp == NULL) {
1796    return false;
1797  }
1798 
1799  fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
1800#if QT_VERSION < 0x040000
1801  fprintf (fp, "%%%%Title: %s\n", aFilename.ascii());
1802#else
1803  fprintf (fp, "%%%%Title: %s\n", aFilename.toStdString().c_str());
1804#endif
1805  fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
1806  fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", aImage.width(), aImage.height());
1807  fprintf (fp, "%%%%EndComments\n");
1808  fprintf (fp, "gsave\n");
1809  fprintf (fp, "/bwproc {\n");
1810  fprintf (fp, "    rgbproc\n");
1811  fprintf (fp, "    dup length 3 idiv string 0 3 0 \n");
1812  fprintf (fp, "    5 -1 roll {\n");
1813  fprintf (fp, "    add 2 1 roll 1 sub dup 0 eq\n");
1814  fprintf (fp, "    { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
1815  fprintf (fp, "       3 1 roll 5 -1 roll } put 1 add 3 0 \n");
1816  fprintf (fp, "    { 2 1 roll } ifelse\n");
1817  fprintf (fp, "    }forall\n");
1818  fprintf (fp, "    pop pop pop\n");
1819  fprintf (fp, "} def\n");
1820  fprintf (fp, "systemdict /colorimage known not {\n");
1821  fprintf (fp, "   /colorimage {\n");
1822  fprintf (fp, "       pop\n");
1823  fprintf (fp, "       pop\n");
1824  fprintf (fp, "       /rgbproc exch def\n");
1825  fprintf (fp, "       { bwproc } image\n");
1826  fprintf (fp, "   }  def\n");
1827  fprintf (fp, "} if\n");
1828  fprintf (fp, "/picstr %d string def\n", aImage.width() * aInColor);
1829  fprintf (fp, "%d %d scale\n", aImage.width(), aImage.height());
1830  fprintf (fp, "%d %d %d\n", aImage.width(), aImage.height(), 8);
1831  fprintf (fp, "[%d 0 0 %d 0 0]\n", aImage.width(), aImage.height());
1832  fprintf (fp, "{currentfile picstr readhexstring pop}\n");
1833  fprintf (fp, "false %d\n", aInColor);
1834  fprintf (fp, "colorimage\n");
1835 
1836
1837  int width = aImage.width();
1838  int height = aImage.height();
1839  int depth = aImage.depth();
1840  int size = width*height;
1841 
1842  if (depth == 1)
1843    size = (width+7)/8*height;
1844  else if (aInColor == 1)
1845    size = size*3;
1846 
1847  int i = 0;
1848  //  if ( aInColor ==1 ) {
1849  // FIXME : L. Garnier. For the moment 10 dec 2007, I could not find a way
1850  // to save correctly grayscale Image. I mean that color or grayscale image
1851  // have the same file save size !
1852 
1853  /* } else*/ if (depth == 8) {
1854    for(int y=height-1; y >=0 ; y--) {
1855      const uchar * s = aImage.scanLine(y);
1856      for(int x=0; x <width; x++) {
1857        QRgb rgb = aImage.color(s[x]);
1858        if (aInColor == 1) {
1859          fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
1860          i++;
1861        } else {
1862          fprintf (fp, " %02hx %02hx %02hx",
1863                   (unsigned char) qRed(rgb),
1864                   (unsigned char) qGreen(rgb),
1865                   (unsigned char) qBlue(rgb));
1866          i += 3;
1867        }
1868      }
1869      fprintf (fp, "\n");
1870    }
1871  } else {
1872#if QT_VERSION < 0x040000
1873    bool alpha = aImage.hasAlphaBuffer();
1874#else
1875    bool alpha = aImage.hasAlphaChannel();
1876    for(int y=height-1; y >=0 ; y--) {
1877      QRgb * s = (QRgb*)(aImage.scanLine(y));
1878      for(int x=0; x <width; x++) {
1879        QRgb rgb = (*s++);
1880        if (alpha && qAlpha(rgb) < 0x40) // 25% alpha, convert to white -
1881          rgb = qRgb(0xff, 0xff, 0xff);
1882        if (aInColor == 1) {
1883          fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
1884          i++;
1885        } else {
1886          fprintf (fp, " %02hx %02hx %02hx",
1887                   (unsigned char) qRed(rgb),
1888                   (unsigned char) qGreen(rgb),
1889                   (unsigned char) qBlue(rgb));
1890          i += 3;
1891        }
1892      }
1893      fprintf (fp, "\n");
1894    }
1895#endif
1896
1897  }
1898
1899  fprintf (fp, "grestore\n");
1900  fprintf (fp, "showpage\n");
1901  fclose (fp);
1902
1903  return true;
1904}
1905/**
1906   Generate Postscript or PDF form image
1907   @param aFilename : name of file
1908   @param aInColor : numbers of colors : 1->BW 2->RGB
1909   @param aImage : Image to print
1910*/
1911bool G4OpenGLQtViewer::generatePS_PDF (
1912 QString aFilename
1913,int aInColor
1914,QImage aImage
1915)
1916{
1917
1918#if QT_VERSION < 0x040000
1919#ifdef Q_WS_MAC || Q_WS_X11
1920  QPrinter printer;
1921  //  printer.setPageSize(pageSize);
1922  if (aInColor == 1) {
1923    printer.setColorMode(QPrinter::GrayScale);
1924  } else {
1925    printer.setColorMode(QPrinter::Color);
1926  }
1927
1928  /* FIXME : I don't know which format it will save...
1929     if (aFilename.endsWith(".ps")) {
1930     printer.setOutputFormat(QPrinter::PostScriptFormat);
1931     } else {
1932     printer.setOutputFormat(QPrinter::PdfFormat);
1933     }
1934  */
1935  printer.setOutputFileName(aFilename);
1936  //  printer.setFullPage ( true);
1937  QPainter paint(&printer);
1938  paint.drawImage (0,0,aImage );
1939  paint.end();
1940#else
1941  G4cerr << "This fonction is only supported on Mac OsX or X11 with Qt3. Full platform supported with Qt4\n" << G4endl;
1942#endif
1943#else
1944  QPrinter printer;
1945  //  printer.setPageSize(pageSize);
1946
1947  // FIXME : L. Garnier 4/12/07
1948  // This is not working, it does nothing. Image is staying in color mode
1949  // So I have desactivate the B/W button in GUI
1950  if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1951#if QT_VERSION < 0x040000
1952    aImage = aImage.convertDepth(1,Qt::MonoOnly);
1953#else
1954    aImage = aImage.convertToFormat ( aImage.format(), Qt::MonoOnly);
1955#endif
1956  }
1957
1958
1959  if (aFilename.endsWith(".ps")) {
1960#if QT_VERSION > 0x040200
1961    printer.setOutputFormat(QPrinter::PostScriptFormat);
1962#endif
1963  } else {
1964#if QT_VERSION > 0x040100
1965    printer.setOutputFormat(QPrinter::PdfFormat);
1966#endif
1967  }
1968#if QT_VERSION > 0x040100
1969  printer.setOutputFileName(aFilename);
1970#endif
1971  //  printer.setFullPage ( true);
1972  QPainter paint(&printer);
1973  paint.drawImage (0,0,aImage);
1974  paint.end();
1975#endif
1976  return true;
1977}
1978
1979
1980
1981void G4OpenGLQtViewer::G4keyPressEvent (QKeyEvent * event)
1982{
1983  if (fHoldKeyEvent)
1984    return;
1985
1986  fHoldKeyEvent = true;
1987
1988#if QT_VERSION < 0x040000
1989  if ((event->key() == Qt::Key_Down) && (event->state() & Qt::AltButton )) { // go backward
1990#else
1991  if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::AltModifier )) { // go backward
1992#endif
1993   
1994    moveScene(0,0,1,false);
1995  }
1996#if QT_VERSION < 0x040000
1997  else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::AltButton)) { // go forward
1998#else
1999  else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::AltModifier)) { // go forward
2000#endif
2001    moveScene(0,0,-1,false);
2002  }
2003#if QT_VERSION < 0x040000
2004  if ((event->key() == Qt::Key_Down) && (event->state() & Qt::ShiftButton)) { // rotate phi
2005#else
2006  if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
2007#endif
2008    rotateScene(0,-1);
2009  }
2010#if QT_VERSION < 0x040000
2011  else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::ShiftButton)) { // rotate phi
2012#else
2013  else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
2014#endif
2015    rotateScene(0,1);
2016  }
2017#if QT_VERSION < 0x040000
2018  if ((event->key() == Qt::Key_Left) && (event->state() & Qt::ShiftButton)) { // rotate theta
2019#else
2020  if ((event->key() == Qt::Key_Left) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
2021#endif
2022    rotateScene(1,0);
2023  }
2024#if QT_VERSION < 0x040000
2025  else if ((event->key() == Qt::Key_Right) && (event->state() & Qt::ShiftButton)) { // rotate theta
2026#else
2027  else if ((event->key() == Qt::Key_Right) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
2028#endif
2029    rotateScene(-1,0);
2030  }
2031
2032#if QT_VERSION < 0x040000
2033  if ((event->state() & Qt::AltButton)) {
2034#else
2035  if ((event->modifiers() & Qt::AltModifier)) {
2036#endif
2037    if (event->key() == Qt::Key_Plus) {
2038      fDeltaRotation = fDeltaRotation/0.7;
2039    }
2040    else if (event->key() == Qt::Key_Minus) {
2041      fDeltaRotation = fDeltaRotation*0.7;
2042    }
2043  } else {
2044    if (event->key() == Qt::Key_Plus) {
2045      fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
2046      updateQWidget();
2047    }
2048    else if (event->key() == Qt::Key_Minus) {
2049      fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
2050      updateQWidget();
2051    }
2052  }
2053 
2054 
2055  if (event->key() == Qt::Key_Escape) { // escaped from full screen
2056#if QT_VERSION >= 0x030200
2057    if (GLWindow->isFullScreen()) {
2058#if QT_VERSION < 0x040000
2059      fFullScreenOn->activated();
2060#else
2061      fFullScreenOn->trigger();
2062#endif
2063    }
2064#endif
2065  }
2066
2067  if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)){ // end of video
2068    fRecordFrames = false;
2069    G4cout << "Recording Stop... \n" << G4endl;
2070    G4cout << "Saving /temp/output.mpg \n" << G4endl;
2071    saveVideo("/temp/output.mpg");
2072  }
2073  if (event->key() == Qt::Key_Space){ // start/pause of video
2074    fRecordFrames = !fRecordFrames;
2075    if (fRecordFrames) {
2076      G4cout << "Recording Start... \n" << G4endl;
2077    } else {
2078      G4cout << "Recording Pause... \n" << G4endl;
2079    }
2080  }
2081
2082  // with no modifiers
2083#if QT_VERSION < 0x040000
2084  if (event->state() == Qt::NoButton) {
2085#else
2086  if (event->modifiers() == Qt::NoModifier) {
2087#endif
2088    if (event->key() == Qt::Key_Down) { // go down
2089      moveScene(0,1,0,false);
2090    }
2091    else if (event->key() == Qt::Key_Up) {  // go up
2092      moveScene(0,-1,0,false);
2093    }
2094    if (event->key() == Qt::Key_Left) { // go left
2095      moveScene(-1,0,0,false);
2096    }
2097    else if (event->key() == Qt::Key_Right) { // go right
2098      moveScene(1,0,0,false);
2099    }
2100  }
2101  fHoldKeyEvent = false;
2102}
2103 
2104
2105/** @return if encoder path was not specified, try to guess it and open the movie parameter dialog box.
2106 * if path was already specified, return it.
2107 */
2108QString G4OpenGLQtViewer::getEncoderPath() {
2109  if (fEncoderPath == NULL) {
2110   
2111    //look for encoderPath
2112    QProcess search;
2113    search.setReadChannelMode(QProcess::MergedChannels);
2114    search.start ("which mpeg_encode");
2115   
2116    if (search.waitForFinished()) {
2117      fEncoderPath = QString::fromLocal8Bit(search.readAll());
2118    }
2119    G4OpenGLQtMovieDialog* movieDialog= new G4OpenGLQtMovieDialog(GLWindow);
2120    movieDialog->show();
2121  } else {
2122    return fEncoderPath ;
2123  }
2124}
2125 
2126
2127/**
2128 * set the new encoder path
2129*/
2130void G4OpenGLQtViewer::setEncoderPath(QString path) {
2131  fEncoderPath = path;
2132}
2133 
2134
2135
2136bool G4OpenGLQtViewer::hasPendingEvents () {
2137  return ((QApplication*)G4Qt::getInstance ())->hasPendingEvents ();
2138}
2139
2140bool G4OpenGLQtViewer::saveVideo (QString outputName) {
2141
2142  // save the parameter file
2143  FILE* fp;
2144  fp = fopen ("/temp/parameter_file.par", "w");
2145
2146  if (fp == NULL) {
2147    return false;
2148  }
2149
2150  fprintf (fp,"# parameter file template with lots of comments to assist you\n");
2151  fprintf (fp,"#\n");
2152  fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
2153  fprintf (fp,"# the copy\n");
2154  fprintf (fp,"#\n");
2155  fprintf (fp,"#\n");
2156  fprintf (fp,"# any line beginning with '#' is a comment\n");
2157  fprintf (fp,"#\n");
2158  fprintf (fp,"# no line should be longer than 255 characters\n");
2159  fprintf (fp,"#\n");
2160  fprintf (fp,"#\n");
2161  fprintf (fp,"# general format of each line is:\n");
2162  fprintf (fp,"#          \n");
2163  fprintf (fp,"#\n");
2164  fprintf (fp,"# lines can generally be in any order\n");
2165  fprintf (fp,"#\n");
2166  fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
2167  fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
2168  fprintf (fp,"#\n");
2169  fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
2170  fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
2171  fprintf (fp,"# the INPUT parameter.\n");
2172  fprintf (fp,"#\n");
2173  fprintf (fp,"#  MUST be in UPPER CASE\n");
2174  fprintf (fp,"#\n");
2175  fprintf (fp,"\n");
2176  fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
2177  fprintf (fp,"# for more info.\n");
2178  fprintf (fp,"\n");
2179  fprintf (fp,"PATTERN          IBBPBBPBBPBBPBBP\n");
2180#if QT_VERSION < 0x040000
2181  fprintf (fp,"OUTPUT           %s\n",outputName.ascii());
2182#else
2183  fprintf (fp,"OUTPUT           %s\n",outputName.toStdString().c_str());
2184#endif
2185  fprintf (fp,"\n");
2186  fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
2187  fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
2188  fprintf (fp,"#\n");
2189  fprintf (fp,"# You must specify the type of the input files.  The choices are:\n");
2190  fprintf (fp,"#    YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
2191  fprintf (fp,"#        (must be upper case)\n");
2192  fprintf (fp,"#\n");
2193  fprintf (fp,"BASE_FILE_FORMAT PPM\n");
2194  fprintf (fp,"\n");
2195  fprintf (fp,"#\n");
2196  fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
2197  fprintf (fp,"# YUV_SIZE       widthxheight\n");
2198  fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
2199  fprintf (fp,"# on just one machine\n");
2200  fprintf (fp,"#\n");
2201  fprintf (fp,"YUV_SIZE 352x240\n");
2202  fprintf (fp,"\n");
2203  fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
2204  fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
2205  fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2206  fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
2207  fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
2208  fprintf (fp,"# to specify the file order.\n");
2209  fprintf (fp,"\n");
2210  fprintf (fp,"INPUT_FORMAT UCB\n");
2211  fprintf (fp,"\n");
2212  fprintf (fp,"# the conversion statement\n");
2213  fprintf (fp,"#\n");
2214  fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
2215  fprintf (fp,"#\n");
2216  fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
2217  fprintf (fp,"#        INPUT_CONVERT   giftoppm *\n");
2218  fprintf (fp,"#\n");
2219  fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2220  fprintf (fp,"#        INPUT_CONVERT   cat *.Y *.U *.V\n");
2221  fprintf (fp,"#\n");
2222  fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
2223  fprintf (fp,"#        INPUT_CONVERT   goto frame *; grabppm\n");
2224  fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2225  fprintf (fp,"#\n");
2226  fprintf (fp,"INPUT_CONVERT    * \n");
2227  fprintf (fp,"\n");
2228  fprintf (fp,"# number of frames in a GOP.\n");
2229  fprintf (fp,"#\n");
2230  fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
2231  fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2232  fprintf (fp,"#\n");
2233  fprintf (fp,"# later, will add more flexible GOP signalling\n");
2234  fprintf (fp,"#\n");
2235  fprintf (fp,"GOP_SIZE 16\n");
2236  fprintf (fp,"\n");
2237  fprintf (fp,"# number of slices in a frame\n");
2238  fprintf (fp,"#\n");
2239  fprintf (fp,"# 1 is a good number.  another possibility is the number of macroblock rows\n");
2240  fprintf (fp,"# (which is the height divided by 16)\n");
2241  fprintf (fp,"#\n");
2242  fprintf (fp,"SLICES_PER_FRAME 1\n");
2243  fprintf (fp,"\n");
2244  fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2245  fprintf (fp,"INPUT_DIR        /temp\n");
2246  fprintf (fp,"\n");
2247  fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2248  fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2249  fprintf (fp,"# way of numbering them.  See the manual for more information.\n");
2250  fprintf (fp,"INPUT\n");
2251  fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2252  fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2253  fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2254  fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2255  fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2256  fprintf (fp,"# if you do, too bad!!!\n");
2257  fprintf (fp,"#\n");
2258  fprintf (fp,"#\n");
2259  fprintf (fp,"Test*.ppm        [0-%d]\n",fRecordFrameNumber);
2260  fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2261  fprintf (fp,"# of files\n");
2262  fprintf (fp,"END_INPUT\n");
2263  fprintf (fp,"\n");
2264  fprintf (fp,"\n");
2265  fprintf (fp,"\n");
2266  fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2267  fprintf (fp,"\n");
2268  fprintf (fp,"# FULL or HALF -- must be upper case\n");
2269  fprintf (fp,"# Should be FULL for computer generated images\n");
2270  fprintf (fp,"PIXEL            FULL\n");
2271  fprintf (fp,"\n");
2272  fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2273  fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2274  fprintf (fp,"RANGE            10\n");
2275  fprintf (fp,"\n");
2276  fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2277  fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2278  fprintf (fp,"\n");
2279  fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2280  fprintf (fp,"PSEARCH_ALG      LOGARITHMIC\n");
2281  fprintf (fp,"\n");
2282  fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2283  fprintf (fp,"#\n");
2284  fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2285  fprintf (fp,"#\n");
2286  fprintf (fp,"BSEARCH_ALG      SIMPLE\n");
2287  fprintf (fp,"\n");
2288  fprintf (fp,"#\n");
2289  fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2290  fprintf (fp,"# (values must be between 1 and 31)\n");
2291  fprintf (fp,"# These are the Qscale values for the entire frame in variable bit-rate\n");
2292  fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2293  fprintf (fp,"#\n");
2294  fprintf (fp,"\n");
2295  fprintf (fp,"# Qscale (Quantization scale) affects quality and compression,\n");
2296  fprintf (fp,"# but has very little effect on speed.\n");
2297  fprintf (fp,"\n");
2298  fprintf (fp,"IQSCALE          4\n");
2299  fprintf (fp,"PQSCALE          5\n");
2300  fprintf (fp,"BQSCALE          12\n");
2301  fprintf (fp,"\n");
2302  fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2303  fprintf (fp,"REFERENCE_FRAME  ORIGINAL\n");
2304  fprintf (fp,"\n");
2305  fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2306  fprintf (fp,"\n");
2307  fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2308  fprintf (fp,"#BIT_RATE  1000000\n");
2309  fprintf (fp,"\n");
2310  fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2311  fprintf (fp,"BUFFER_SIZE 327680\n");
2312  fprintf (fp,"\n");
2313  fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2314  fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2315  fprintf (fp,"FRAME_RATE 30\n");
2316  fprintf (fp,"\n");
2317  fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2318  fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.\n");
2319  fprintf (fp,"\n");
2320  fprintf (fp,"\n");
2321  fclose (fp);
2322
2323  QProcess::execute (fEncoderPath, QStringList("/temp/parameter_file.par"));
2324  return true;
2325}
2326
2327/*
2328 
2329void MultiLayer::exportToSVG(const QString& fname)
2330{
2331  QPicture picture;
2332  QPainter p(&picture);
2333  for (int i=0;i<(int)graphsList->count();i++)
2334    {
2335      Graph *gr=(Graph *)graphsList->at(i);
2336      Plot *myPlot= (Plot *)gr->plotWidget();
2337     
2338      QPoint pos=gr->pos();
2339     
2340      int width=int(myPlot->frameGeometry().width());
2341      int height=int(myPlot->frameGeometry().height());
2342     
2343      myPlot->print(&p, QRect(pos,QSize(width,height)));
2344    }
2345 
2346  p.end();
2347  picture.save(fname, "svg");
2348}
2349*/
2350#endif
Note: See TracBrowser for help on using the repository browser.