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

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

correction partielle du #120 par l empechement de rentrer recursivement dans les fonctions move et rotate

  • Property svn:mime-type set to text/cpp
File size: 71.0 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26//
27// $Id: G4OpenGLQtViewer.cc,v 1.10 2008/01/30 10:54:13 lgarnier Exp $
28// GEANT4 tag $Name:  $
29//
30//
31// G4OpenGLQtViewer : Class to provide Qt specific
32//                     functionality for OpenGL in GEANT4
33//
34// 27/06/2003 : G.Barrand : implementation (at last !).
35
36#ifdef G4VIS_BUILD_OPENGLQT_DRIVER
37
38#define GEANT4_QT_DEBUG
39
40#include "G4OpenGLQtViewer.hh"
41
42#include "G4ios.hh"
43#include "G4VisExtent.hh"
44#include "G4LogicalVolume.hh"
45#include "G4VSolid.hh"
46#include "G4Point3D.hh"
47#include "G4Normal3D.hh"
48#include "G4Scene.hh"
49#include "G4OpenGLQtExportDialog.hh"
50#include "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#ifdef GEANT4_QT_DEBUG
1260  printf("G4OpenGLQtViewer::toggleFullScreen checked:%d() \n",check);
1261#endif
1262  if (check != GLWindow->isFullScreen()) { //toggle
1263#if QT_VERSION >= 0x030200
1264#if QT_VERSION < 0x040000
1265    GLWindow->setWindowState(GLWindow->windowState() ^ Qt::WindowFullScreen);
1266//     fFullScreenOn->setOn(check);
1267//     fFullScreenOff->setOn(!check);
1268#else
1269    GLWindow->setWindowState(GLWindow->windowState() ^ Qt::WindowFullScreen);
1270//     fFullScreenOn->setChecked(check);
1271//     fFullScreenOff->setChecked(!check);
1272#endif
1273#else
1274    G4cerr << "This version of Qt could not do fullScreen. Resizing the widget is the only solution available.\n" << G4endl;
1275#endif
1276  }
1277}
1278
1279
1280void G4OpenGLQtViewer::saveForVideo(QString nomFich) {
1281  if (nomFich == "") {
1282    return;
1283  }
1284
1285  QImage image;
1286  image = fWindow->grabFrameBuffer();
1287  bool res = false;
1288 
1289  nomFich += "."+QString("ppm");
1290#if QT_VERSION < 0x040000
1291  res = image.save(nomFich,"ppm");
1292#else
1293  res = image.save(nomFich,0);
1294#endif
1295  if (res == false) {
1296#if QT_VERSION < 0x040000
1297    G4cerr << "Error while saving file... "<<nomFich.ascii()<<"\n" << G4endl;
1298#else
1299    G4cerr << "Error while saving file... "<<nomFich.toStdString().c_str()<<"\n" << G4endl;
1300#endif
1301    fRecordFrames = false;
1302  }
1303
1304#if QT_VERSION < 0x040000
1305  printf("SaveForVideo ^^^^^^^^^^^^^^^^^^^^^^^^ %s\n",nomFich.ascii());
1306#else
1307  printf("SaveForVideo ^^^^^^^^^^^^^^^^^^^^^^^^ %s\n",nomFich.toStdString().c_str());
1308#endif
1309}
1310
1311
1312
1313void G4OpenGLQtViewer::actionCreateEPS() {
1314  QString filters;
1315#if QT_VERSION < 0x040000
1316  QStrList listFormat=QImageIO::outputFormats();
1317  char *tmp=listFormat.first();
1318  while (tmp!=0) {
1319    filters += QString(tmp) + ";;";
1320    tmp=listFormat.next();
1321  }
1322#else
1323  QList<QByteArray> formats =  QImageWriter::supportedImageFormats ();
1324  for (int i = 0; i < formats.size(); ++i) {
1325    filters +=formats.at(i) + ";;";
1326  }
1327#endif
1328  filters += "eps;;";
1329  filters += "ps;;";
1330  filters += "pdf";
1331  QString* selectedFormat = new QString();
1332#if QT_VERSION < 0x040000
1333  QString nomFich =  QFileDialog::getSaveFileName ( ".",
1334                                                    filters,
1335                                                    GLWindow,
1336                                                    "Save file dialog",
1337                                                    tr("Save as ..."),
1338                                                    selectedFormat );
1339#else
1340  QString nomFich =  QFileDialog::getSaveFileName ( GLWindow,
1341                                                    tr("Save as ..."),
1342                                                    ".",
1343                                                    filters,
1344                                                    selectedFormat );
1345#endif
1346  // bmp jpg jpeg png ppm xbm xpm
1347  if (nomFich == "") {
1348    return;
1349  }
1350#if QT_VERSION < 0x040000
1351  nomFich += "."+QString(selectedFormat->ascii());
1352  QString format = selectedFormat->lower();
1353#else
1354  nomFich += "."+QString(selectedFormat->toStdString().c_str());
1355  QString format = selectedFormat->toLower();
1356#endif
1357  G4OpenGLQtExportDialog* exportDialog= new G4OpenGLQtExportDialog(GLWindow,format,fWindow->height(),fWindow->width());
1358  if(  exportDialog->exec()) {
1359
1360    QImage image;
1361    bool res = false;
1362    if ((exportDialog->getWidth() !=fWindow->width()) ||
1363        (exportDialog->getHeight() !=fWindow->height())) {
1364      if (format != QString("eps")) {
1365      G4cerr << "Export->Change Size : This function is not implemented, to export in another size, please resize your frame to what you need\n" << G4endl;
1366     
1367      //    rescaleImage(exportDialog->getWidth(),exportDialog->getHeight());// re-scale image
1368      //      QGLWidget* glResized = fWindow;
1369
1370      // FIXME :
1371      // L.Garnier : I've try to implement change size function, but the problem is
1372      // the renderPixmap function call the QGLWidget to resize and it doesn't draw
1373      // the content of this widget... It only draw the background.
1374
1375      //      fWindow->renderPixmap (exportDialog->getWidth()*2,exportDialog->getHeight()*2,true );
1376
1377      //      QPixmap pixmap = fWindow->renderPixmap ();
1378     
1379      //      image = pixmap->toImage();
1380      //      glResized->resize(exportDialog->getWidth()*2,exportDialog->getHeight()*2);
1381      //      image = glResized->grabFrameBuffer();
1382      }     
1383    } else {
1384      image = fWindow->grabFrameBuffer();
1385    }   
1386    if (format == QString("eps")) {
1387      if (exportDialog->getVectorEPS()) {
1388        res = generateVectorEPS(nomFich,exportDialog->getWidth(),exportDialog->getHeight(),image);
1389      } else {
1390        res = generateEPS(nomFich,exportDialog->getNbColor(),image);
1391      }
1392    } else if ((format == "ps") || (format == "pdf")) {
1393      res = generatePS_PDF(nomFich,exportDialog->getNbColor(),image);
1394    } else if ((format == "tif") ||
1395               (format == "tiff") ||
1396               (format == "jpg") ||
1397               (format == "jpeg") ||
1398               (format == "png") ||
1399               (format == "pbm") ||
1400               (format == "pgm") ||
1401               (format == "ppm") ||
1402               (format == "bmp") ||
1403               (format == "xbm") ||
1404               (format == "xpm")) {
1405#if QT_VERSION < 0x040000
1406      res = image.save(nomFich,selectedFormat->ascii(),exportDialog->getSliderValue());
1407#else
1408      res = image.save(nomFich,0,exportDialog->getSliderValue());
1409#endif
1410    } else {
1411      G4cerr << "This version of G4UI Could not generate the selected format\n" << G4endl;
1412    }
1413    if (res == false) {
1414#if QT_VERSION < 0x040000
1415      G4cerr << "Error while saving file... "<<nomFich.ascii()<<"\n" << G4endl;
1416#else
1417      G4cerr << "Error while saving file... "<<nomFich.toStdString().c_str()<<"\n" << G4endl;
1418#endif
1419    } else {
1420#if QT_VERSION < 0x040000
1421      G4cout << "File "<<nomFich.ascii()<<" has been saved \n" << G4endl;
1422#else
1423      G4cout << "File "<<nomFich.toStdString().c_str()<<" has been saved \n" << G4endl;
1424#endif
1425    }
1426   
1427  } else { // cancel selected
1428    return;
1429  }
1430 
1431#ifdef GEANT4_QT_DEBUG
1432  printf("G4OpenGLQtViewer::actionCreateEPS() \n");
1433#endif
1434}
1435
1436/*
1437// 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
1438
1439void Graph::exportToSVG(const QString& fname)
1440{
1441  // enable workaround for Qt3 misalignments
1442  QwtPainter::setSVGMode(true);
1443  QPicture picture;
1444  QPainter p(&picture);
1445  d_plot->print(&p, d_plot->rect());
1446  p.end();
1447
1448  picture.save(fname, "svg");
1449}
1450*/
1451
1452
1453
1454
1455/**
1456   Save the current mouse press point
1457   @param p mouse click point
1458*/
1459#if QT_VERSION < 0x040000
1460void G4OpenGLQtViewer::G4MousePressEvent(QPoint p,Qt::ButtonState mButtons)
1461#else
1462void G4OpenGLQtViewer::G4MousePressEvent(QPoint p,Qt::MouseButtons mButtons)
1463#endif
1464{
1465  fAutoMove = false; // stop automove
1466  fLastPos = p;
1467  if (fMouseAction == STYLE2){  // pick
1468    Pick(p.x(),p.y());
1469  }
1470}
1471
1472
1473/**
1474   @param pos_x mouse x position
1475   @param pos_y mouse y position
1476   @param mButtons mouse button active
1477   @param mAutoMove true: apply this move till another evnt came, false :one time move
1478*/
1479
1480#if QT_VERSION < 0x040000
1481void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::ButtonState mButtons,bool mAutoMove)
1482#else
1483  void G4OpenGLQtViewer::G4MouseMoveEvent(int pos_x, int pos_y,Qt::MouseButtons mButtons,bool mAutoMove)
1484#endif
1485{
1486  fAutoMove = mAutoMove;
1487
1488  if (!fAutoMove) {  // keep old delta if automove
1489    fDeltaPosX = fLastPos.x() - pos_x;
1490    fDeltaPosY = fLastPos.y() - pos_y;
1491  }
1492
1493  if ((fDeltaPosX == 0) && (fDeltaPosY == 0)) {
1494    fAutoMove = false;
1495  }
1496
1497  if (fMouseAction == STYLE1) {  // rotate
1498    if (mButtons & Qt::LeftButton) {
1499      rotateScene(fDeltaPosX,fDeltaPosY,fAutoMove);
1500    }
1501  } else if (fMouseAction == STYLE2) {  // move
1502    if (mButtons & Qt::LeftButton) {
1503      if (fAutoMove) {
1504        while (fAutoMove) {
1505          moveScene(-fDeltaPosX,-fDeltaPosY,0,true,true);
1506          ((QApplication*)G4Qt::getInstance ())->processEvents();
1507        }
1508      } else {
1509        moveScene(-fDeltaPosX,-fDeltaPosY,0,true,false);
1510      }
1511    }
1512  }
1513  fLastPos = QPoint(pos_x, pos_y);
1514}
1515
1516
1517/**
1518   Move the scene of dx, dy, dz values.
1519   @param dx delta mouse x position
1520   @param dy delta mouse y position
1521   @param mouseMove : true if even comes froma mouse move, false if even comes from key action
1522*/
1523
1524void G4OpenGLQtViewer::moveScene(G4double dx,G4double dy, G4double dz,bool mouseMove,bool mAutoMove)
1525{
1526  if (fHoldMoveEvent)
1527    return;
1528  fHoldMoveEvent = true;
1529
1530  if( mAutoMove == false) {
1531    fAutoMove = true;
1532  }
1533  G4double coefTrans = 0;
1534  GLdouble coefDepth = 0;
1535  while (fAutoMove) {
1536    if( mAutoMove == false) {
1537      fAutoMove = false;
1538    }
1539    if(mouseMove) {
1540      coefTrans = ((G4double)getSceneNearWidth())/((G4double)WinSize_x);
1541      if (WinSize_y <WinSize_x) {
1542        coefTrans = ((G4double)getSceneNearWidth())/((G4double)WinSize_y);
1543      }
1544#ifdef GEANT4_QT_DEBUG
1545      printf("Coef trans %f\n",coefTrans);
1546#endif
1547    } else {
1548      coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1549      coefDepth = getSceneDepth()*fDeltaDepth;
1550    }
1551    fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1552   
1553    updateQWidget();
1554    ((QApplication*)G4Qt::getInstance ())->processEvents();
1555  }
1556
1557  fHoldMoveEvent = false;
1558}
1559
1560
1561/**
1562   @param dx delta mouse x position
1563   @param dy delta mouse y position
1564*/
1565
1566void G4OpenGLQtViewer::rotateScene(G4double dx, G4double dy,bool mAutoRotate)
1567{
1568  if (fHoldRotateEvent)
1569    return;
1570  fHoldRotateEvent = true;
1571
1572  if( mAutoRotate == false) {
1573    fAutoMove = true;
1574  }
1575  G4Vector3D vp;
1576  G4Vector3D up;
1577 
1578  G4Vector3D xprime;
1579  G4Vector3D yprime;
1580  G4Vector3D zprime;
1581 
1582  G4double delta_alpha;
1583  G4double delta_theta;
1584 
1585  G4Vector3D new_vp;
1586  G4Vector3D new_up;
1587 
1588  G4double cosalpha;
1589  G4double sinalpha;
1590 
1591  G4Vector3D a1;
1592  G4Vector3D a2;
1593  G4Vector3D delta;
1594  G4Vector3D viewPoint;
1595
1596  while (fAutoMove) {
1597    if( mAutoRotate == false) {
1598      fAutoMove = false;
1599    }
1600   
1601    //phi spin stuff here
1602 
1603    vp = fVP.GetViewpointDirection ().unit ();
1604    up = fVP.GetUpVector ().unit ();
1605 
1606    yprime = (up.cross(vp)).unit();
1607    zprime = (vp.cross(yprime)).unit();
1608 
1609    if (fVP.GetLightsMoveWithCamera()) {
1610      delta_alpha = dy * fDeltaRotation;
1611      delta_theta = -dx * fDeltaRotation;
1612    } else {
1613      delta_alpha = -dy * fDeltaRotation;
1614      delta_theta = dx * fDeltaRotation;
1615    }   
1616 
1617    delta_alpha *= deg;
1618    delta_theta *= deg;
1619 
1620    new_vp = std::cos(delta_alpha) * vp + std::sin(delta_alpha) * zprime;
1621
1622    // to avoid z rotation flipping
1623    // to allow more than 360° rotation
1624    if (fVP.GetLightsMoveWithCamera()) {
1625      new_up = (new_vp.cross(yprime)).unit();
1626      if (new_vp.z()*vp.z() <0) {
1627        new_up.set(new_up.x(),-new_up.y(),new_up.z());
1628      }
1629    } else {
1630      new_up = up;
1631      if (new_vp.z()*vp.z() <0) {
1632        new_up.set(new_up.x(),-new_up.y(),new_up.z());
1633      }
1634    }
1635    fVP.SetUpVector(new_up);
1636    ////////////////
1637    // Rotates by fixed azimuthal angle delta_theta.
1638   
1639    cosalpha = new_up.dot (new_vp.unit());
1640    sinalpha = std::sqrt (1. - std::pow (cosalpha, 2));
1641    yprime = (new_up.cross (new_vp.unit())).unit ();
1642    xprime = yprime.cross (new_up);
1643    // Projection of vp on plane perpendicular to up...
1644    a1 = sinalpha * xprime;
1645    // Required new projection...
1646    a2 = sinalpha * (std::cos (delta_theta) * xprime + std::sin (delta_theta) * yprime);
1647    // Required Increment vector...
1648    delta = a2 - a1;
1649    // So new viewpoint is...
1650    viewPoint = new_vp.unit() + delta;
1651   
1652#ifdef GEANT4_QT_DEBUG
1653//     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);
1654//     printf("up : %f %f %f\n",up.x(),up.y(),up.z());
1655//     printf("new up : %f %f %f\n",new_up.x(),new_up.y(),new_up.z());
1656//     printf("vp : %f %f %f\n",vp.x(),vp.y(),vp.z());
1657//     printf("new_vp : %f %f %f\n",new_vp.x(),new_vp.y(),new_vp.z());
1658#endif
1659    fVP.SetViewAndLights (viewPoint);
1660    updateQWidget();
1661   
1662    ((QApplication*)G4Qt::getInstance ())->processEvents();
1663  }
1664
1665  fHoldRotateEvent = false;
1666}
1667
1668/** This is the benning of a rescale function. It does nothing for the moment
1669    @param aWidth : new width
1670    @param aHeight : new height
1671*/
1672void G4OpenGLQtViewer::rescaleImage(
1673 int aWidth
1674,int aHeight
1675){
1676#ifdef GEANT4_QT_DEBUG
1677  printf("should rescale \n");
1678#endif
1679  GLfloat* feedback_buffer;
1680  GLint returned;
1681  FILE* file;
1682 
1683//   feedback_buffer = new GLfloat[size];
1684//   glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1685//   glRenderMode (GL_FEEDBACK);
1686 
1687//   glViewport (0, 0, aWidth, aHeight);
1688//   DrawView();
1689//   returned = glRenderMode (GL_RENDER);
1690
1691}
1692
1693/**
1694   Generate Vectorial Encapsulated Postscript form image
1695   @param aFilename : name of file
1696   @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1697   @param aImage : Image to print
1698*/
1699bool G4OpenGLQtViewer::generateVectorEPS (
1700 QString aFilename
1701,int aWidth
1702,int aHeight
1703,QImage aImage
1704)
1705{
1706  // Print vectored PostScript
1707 
1708  G4int size = 5000000;
1709
1710  GLfloat* feedback_buffer;
1711  GLint returned;
1712  FILE* file;
1713 
1714  feedback_buffer = new GLfloat[size];
1715  glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1716  glRenderMode (GL_FEEDBACK);
1717 
1718  int side = aWidth;
1719  if (aHeight < aWidth) side = aHeight;
1720  glViewport((aWidth - side) / 2, (aHeight - side) / 2, side, side);
1721  DrawView();
1722
1723  returned = glRenderMode (GL_RENDER);
1724 
1725 
1726#if QT_VERSION < 0x040000
1727  file = fopen (aFilename.ascii(), "w");
1728#else
1729  file = fopen (aFilename.toStdString().c_str(), "w");
1730#endif
1731  if (file) {
1732    spewWireframeEPS (file, returned, feedback_buffer, "rendereps");
1733  } else {
1734#if QT_VERSION < 0x040000
1735    G4cerr << "Could not open "<< aFilename.ascii()<<"\n" << G4endl;
1736#else
1737    G4cerr << "Could not open "<< aFilename.toStdString().c_str()<<"\n" << G4endl;
1738#endif
1739  }
1740 
1741  delete[] feedback_buffer;
1742
1743  return true;
1744}
1745
1746/**
1747   Generate Encapsulated Postscript form image
1748   @param aFilename : name of file
1749   @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1750   @param aImage : Image to print
1751*/
1752bool G4OpenGLQtViewer::generateEPS (
1753 QString aFilename
1754,int aInColor
1755,QImage aImage
1756)
1757{
1758  // FIXME
1759#ifdef GEANT4_QT_DEBUG
1760  printf("saving EPS\n");
1761#endif
1762
1763  FILE* fp;
1764
1765  if (aImage.bits () == NULL)
1766    return false;
1767 
1768#if QT_VERSION < 0x040000
1769  fp = fopen (aFilename.ascii(), "w");
1770#else
1771  fp = fopen (aFilename.toStdString().c_str(), "w");
1772#endif
1773  if (fp == NULL) {
1774    return false;
1775  }
1776 
1777  fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
1778#if QT_VERSION < 0x040000
1779  fprintf (fp, "%%%%Title: %s\n", aFilename.ascii());
1780#else
1781  fprintf (fp, "%%%%Title: %s\n", aFilename.toStdString().c_str());
1782#endif
1783  fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
1784  fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", aImage.width(), aImage.height());
1785  fprintf (fp, "%%%%EndComments\n");
1786  fprintf (fp, "gsave\n");
1787  fprintf (fp, "/bwproc {\n");
1788  fprintf (fp, "    rgbproc\n");
1789  fprintf (fp, "    dup length 3 idiv string 0 3 0 \n");
1790  fprintf (fp, "    5 -1 roll {\n");
1791  fprintf (fp, "    add 2 1 roll 1 sub dup 0 eq\n");
1792  fprintf (fp, "    { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
1793  fprintf (fp, "       3 1 roll 5 -1 roll } put 1 add 3 0 \n");
1794  fprintf (fp, "    { 2 1 roll } ifelse\n");
1795  fprintf (fp, "    }forall\n");
1796  fprintf (fp, "    pop pop pop\n");
1797  fprintf (fp, "} def\n");
1798  fprintf (fp, "systemdict /colorimage known not {\n");
1799  fprintf (fp, "   /colorimage {\n");
1800  fprintf (fp, "       pop\n");
1801  fprintf (fp, "       pop\n");
1802  fprintf (fp, "       /rgbproc exch def\n");
1803  fprintf (fp, "       { bwproc } image\n");
1804  fprintf (fp, "   }  def\n");
1805  fprintf (fp, "} if\n");
1806  fprintf (fp, "/picstr %d string def\n", aImage.width() * aInColor);
1807  fprintf (fp, "%d %d scale\n", aImage.width(), aImage.height());
1808  fprintf (fp, "%d %d %d\n", aImage.width(), aImage.height(), 8);
1809  fprintf (fp, "[%d 0 0 %d 0 0]\n", aImage.width(), aImage.height());
1810  fprintf (fp, "{currentfile picstr readhexstring pop}\n");
1811  fprintf (fp, "false %d\n", aInColor);
1812  fprintf (fp, "colorimage\n");
1813 
1814
1815  int width = aImage.width();
1816  int height = aImage.height();
1817  int depth = aImage.depth();
1818  int size = width*height;
1819 
1820  if (depth == 1)
1821    size = (width+7)/8*height;
1822  else if (aInColor == 1)
1823    size = size*3;
1824 
1825  int i = 0;
1826  //  if ( aInColor ==1 ) {
1827  // FIXME : L. Garnier. For the moment 10 dec 2007, I could not find a way
1828  // to save correctly grayscale Image. I mean that color or grayscale image
1829  // have the same file save size !
1830 
1831  /* } else*/ if (depth == 8) {
1832    for(int y=height-1; y >=0 ; y--) {
1833      const uchar * s = aImage.scanLine(y);
1834      for(int x=0; x <width; x++) {
1835        QRgb rgb = aImage.color(s[x]);
1836        if (aInColor == 1) {
1837          fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
1838          i++;
1839        } else {
1840          fprintf (fp, " %02hx %02hx %02hx",
1841                   (unsigned char) qRed(rgb),
1842                   (unsigned char) qGreen(rgb),
1843                   (unsigned char) qBlue(rgb));
1844          i += 3;
1845        }
1846      }
1847      fprintf (fp, "\n");
1848    }
1849  } else {
1850#if QT_VERSION < 0x040000
1851    bool alpha = aImage.hasAlphaBuffer();
1852#else
1853    bool alpha = aImage.hasAlphaChannel();
1854    for(int y=height-1; y >=0 ; y--) {
1855      QRgb * s = (QRgb*)(aImage.scanLine(y));
1856      for(int x=0; x <width; x++) {
1857        QRgb rgb = (*s++);
1858        if (alpha && qAlpha(rgb) < 0x40) // 25% alpha, convert to white -
1859          rgb = qRgb(0xff, 0xff, 0xff);
1860        if (aInColor == 1) {
1861          fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
1862          i++;
1863        } else {
1864          fprintf (fp, " %02hx %02hx %02hx",
1865                   (unsigned char) qRed(rgb),
1866                   (unsigned char) qGreen(rgb),
1867                   (unsigned char) qBlue(rgb));
1868          i += 3;
1869        }
1870      }
1871      fprintf (fp, "\n");
1872    }
1873#endif
1874
1875  }
1876
1877  fprintf (fp, "grestore\n");
1878  fprintf (fp, "showpage\n");
1879  fclose (fp);
1880
1881  return true;
1882}
1883/**
1884   Generate Postscript or PDF form image
1885   @param aFilename : name of file
1886   @param aInColor : numbers of colors : 1->BW 2->RGB
1887   @param aImage : Image to print
1888*/
1889bool G4OpenGLQtViewer::generatePS_PDF (
1890 QString aFilename
1891,int aInColor
1892,QImage aImage
1893)
1894{
1895
1896#if QT_VERSION < 0x040000
1897#ifdef Q_WS_MAC || Q_WS_X11
1898  QPrinter printer;
1899  //  printer.setPageSize(pageSize);
1900  if (aInColor == 1) {
1901    printer.setColorMode(QPrinter::GrayScale);
1902  } else {
1903    printer.setColorMode(QPrinter::Color);
1904  }
1905
1906  /* FIXME : I don't know which format it will save...
1907     if (aFilename.endsWith(".ps")) {
1908     printer.setOutputFormat(QPrinter::PostScriptFormat);
1909     } else {
1910     printer.setOutputFormat(QPrinter::PdfFormat);
1911     }
1912  */
1913  printer.setOutputFileName(aFilename);
1914  //  printer.setFullPage ( true);
1915  QPainter paint(&printer);
1916  paint.drawImage (0,0,aImage );
1917  paint.end();
1918#else
1919  G4cerr << "This fonction is only supported on Mac OsX or X11 with Qt3. Full platform supported with Qt4\n" << G4endl;
1920#endif
1921#else
1922  QPrinter printer;
1923  //  printer.setPageSize(pageSize);
1924
1925  // FIXME : L. Garnier 4/12/07
1926  // This is not working, it does nothing. Image is staying in color mode
1927  // So I have desactivate the B/W button in GUI
1928  if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1929#if QT_VERSION < 0x040000
1930    aImage = aImage.convertDepth(1,Qt::MonoOnly);
1931#else
1932    aImage = aImage.convertToFormat ( aImage.format(), Qt::MonoOnly);
1933#endif
1934  }
1935
1936
1937  if (aFilename.endsWith(".ps")) {
1938#if QT_VERSION > 0x040200
1939    printer.setOutputFormat(QPrinter::PostScriptFormat);
1940#endif
1941  } else {
1942#if QT_VERSION > 0x040100
1943    printer.setOutputFormat(QPrinter::PdfFormat);
1944#endif
1945  }
1946#if QT_VERSION > 0x040100
1947  printer.setOutputFileName(aFilename);
1948#endif
1949  //  printer.setFullPage ( true);
1950  QPainter paint(&printer);
1951  paint.drawImage (0,0,aImage);
1952  paint.end();
1953#endif
1954  return true;
1955}
1956
1957
1958
1959void G4OpenGLQtViewer::G4keyPressEvent (QKeyEvent * event)
1960{
1961  if (fHoldKeyEvent)
1962    return;
1963
1964  fHoldKeyEvent = true;
1965
1966#if QT_VERSION < 0x040000
1967  if ((event->key() == Qt::Key_Down) && (event->state() & Qt::AltButton )) { // go backward
1968#else
1969  if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::AltModifier )) { // go backward
1970#endif
1971   
1972    moveScene(0,0,1,false);
1973  }
1974#if QT_VERSION < 0x040000
1975  else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::AltButton)) { // go forward
1976#else
1977  else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::AltModifier)) { // go forward
1978#endif
1979    moveScene(0,0,-1,false);
1980  }
1981#if QT_VERSION < 0x040000
1982  if ((event->key() == Qt::Key_Down) && (event->state() & Qt::ShiftButton)) { // rotate phi
1983#else
1984  if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
1985#endif
1986    rotateScene(0,-1);
1987  }
1988#if QT_VERSION < 0x040000
1989  else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::ShiftButton)) { // rotate phi
1990#else
1991  else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
1992#endif
1993    rotateScene(0,1);
1994  }
1995#if QT_VERSION < 0x040000
1996  if ((event->key() == Qt::Key_Left) && (event->state() & Qt::ShiftButton)) { // rotate theta
1997#else
1998  if ((event->key() == Qt::Key_Left) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
1999#endif
2000    rotateScene(1,0);
2001  }
2002#if QT_VERSION < 0x040000
2003  else if ((event->key() == Qt::Key_Right) && (event->state() & Qt::ShiftButton)) { // rotate theta
2004#else
2005  else if ((event->key() == Qt::Key_Right) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
2006#endif
2007    rotateScene(-1,0);
2008  }
2009
2010#if QT_VERSION < 0x040000
2011  if ((event->state() & Qt::AltButton)) {
2012#else
2013  if ((event->modifiers() & Qt::AltModifier)) {
2014#endif
2015    if (event->key() == Qt::Key_Plus) {
2016      fDeltaRotation = fDeltaRotation/0.7;
2017    }
2018    else if (event->key() == Qt::Key_Minus) {
2019      fDeltaRotation = fDeltaRotation*0.7;
2020    }
2021  } else {
2022    if (event->key() == Qt::Key_Plus) {
2023      fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
2024      updateQWidget();
2025    }
2026    else if (event->key() == Qt::Key_Minus) {
2027      fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
2028      updateQWidget();
2029    }
2030  }
2031 
2032 
2033  if (event->key() == Qt::Key_Escape) { // escaped from full screen
2034#if QT_VERSION >= 0x030200
2035    if (GLWindow->isFullScreen()) {
2036#if QT_VERSION < 0x040000
2037      fFullScreenOn->activated();
2038#else
2039      fFullScreenOn->trigger();
2040#endif
2041    }
2042#endif
2043  }
2044
2045  if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)){ // end of video
2046    fRecordFrames = false;
2047    G4cout << "Recording Stop... \n" << G4endl;
2048    G4cout << "Saving /temp/output.mpg \n" << G4endl;
2049    saveVideo("/temp/output.mpg");
2050  }
2051  if (event->key() == Qt::Key_Space){ // start/pause of video
2052    fRecordFrames = !fRecordFrames;
2053    if (fRecordFrames) {
2054      G4cout << "Recording Start... \n" << G4endl;
2055    } else {
2056      G4cout << "Recording Pause... \n" << G4endl;
2057    }
2058  }
2059
2060  // with no modifiers
2061#if QT_VERSION < 0x040000
2062  if (event->state() == Qt::NoButton) {
2063#else
2064  if (event->modifiers() == Qt::NoModifier) {
2065#endif
2066    if (event->key() == Qt::Key_Down) { // go down
2067      moveScene(0,-1,0,false);
2068    }
2069    else if (event->key() == Qt::Key_Up) {  // go up
2070      moveScene(0,1,0,false);
2071    }
2072    if (event->key() == Qt::Key_Left) { // go left
2073      moveScene(-1,0,0,false);
2074    }
2075    else if (event->key() == Qt::Key_Right) { // go right
2076      moveScene(1,0,0,false);
2077    }
2078  }
2079  fHoldKeyEvent = false;
2080}
2081
2082
2083bool G4OpenGLQtViewer::hasPendingEvents () {
2084  return ((QApplication*)G4Qt::getInstance ())->hasPendingEvents ();
2085}
2086
2087bool G4OpenGLQtViewer::saveVideo (QString outputName) {
2088
2089  // save the parameter file
2090  FILE* fp;
2091  fp = fopen ("/temp/parameter_file.par", "w");
2092
2093  if (fp == NULL) {
2094    return false;
2095  }
2096
2097  fprintf (fp,"# parameter file template with lots of comments to assist you\n");
2098  fprintf (fp,"#\n");
2099  fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
2100  fprintf (fp,"# the copy\n");
2101  fprintf (fp,"#\n");
2102  fprintf (fp,"#\n");
2103  fprintf (fp,"# any line beginning with '#' is a comment\n");
2104  fprintf (fp,"#\n");
2105  fprintf (fp,"# no line should be longer than 255 characters\n");
2106  fprintf (fp,"#\n");
2107  fprintf (fp,"#\n");
2108  fprintf (fp,"# general format of each line is:\n");
2109  fprintf (fp,"#          \n");
2110  fprintf (fp,"#\n");
2111  fprintf (fp,"# lines can generally be in any order\n");
2112  fprintf (fp,"#\n");
2113  fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
2114  fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
2115  fprintf (fp,"#\n");
2116  fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
2117  fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
2118  fprintf (fp,"# the INPUT parameter.\n");
2119  fprintf (fp,"#\n");
2120  fprintf (fp,"#  MUST be in UPPER CASE\n");
2121  fprintf (fp,"#\n");
2122  fprintf (fp,"\n");
2123  fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
2124  fprintf (fp,"# for more info.\n");
2125  fprintf (fp,"\n");
2126  fprintf (fp,"PATTERN          IBBPBBPBBPBBPBBP\n");
2127#if QT_VERSION < 0x040000
2128  fprintf (fp,"OUTPUT           %s\n",outputName.ascii());
2129#else
2130  fprintf (fp,"OUTPUT           %s\n",outputName.toStdString().c_str());
2131#endif
2132  fprintf (fp,"\n");
2133  fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
2134  fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
2135  fprintf (fp,"#\n");
2136  fprintf (fp,"# You must specify the type of the input files.  The choices are:\n");
2137  fprintf (fp,"#    YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
2138  fprintf (fp,"#        (must be upper case)\n");
2139  fprintf (fp,"#\n");
2140  fprintf (fp,"BASE_FILE_FORMAT PPM\n");
2141  fprintf (fp,"\n");
2142  fprintf (fp,"#\n");
2143  fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
2144  fprintf (fp,"# YUV_SIZE       widthxheight\n");
2145  fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
2146  fprintf (fp,"# on just one machine\n");
2147  fprintf (fp,"#\n");
2148  fprintf (fp,"YUV_SIZE 352x240\n");
2149  fprintf (fp,"\n");
2150  fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
2151  fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
2152  fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2153  fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
2154  fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
2155  fprintf (fp,"# to specify the file order.\n");
2156  fprintf (fp,"\n");
2157  fprintf (fp,"INPUT_FORMAT UCB\n");
2158  fprintf (fp,"\n");
2159  fprintf (fp,"# the conversion statement\n");
2160  fprintf (fp,"#\n");
2161  fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
2162  fprintf (fp,"#\n");
2163  fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
2164  fprintf (fp,"#        INPUT_CONVERT   giftoppm *\n");
2165  fprintf (fp,"#\n");
2166  fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2167  fprintf (fp,"#        INPUT_CONVERT   cat *.Y *.U *.V\n");
2168  fprintf (fp,"#\n");
2169  fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
2170  fprintf (fp,"#        INPUT_CONVERT   goto frame *; grabppm\n");
2171  fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2172  fprintf (fp,"#\n");
2173  fprintf (fp,"INPUT_CONVERT    * \n");
2174  fprintf (fp,"\n");
2175  fprintf (fp,"# number of frames in a GOP.\n");
2176  fprintf (fp,"#\n");
2177  fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
2178  fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2179  fprintf (fp,"#\n");
2180  fprintf (fp,"# later, will add more flexible GOP signalling\n");
2181  fprintf (fp,"#\n");
2182  fprintf (fp,"GOP_SIZE 16\n");
2183  fprintf (fp,"\n");
2184  fprintf (fp,"# number of slices in a frame\n");
2185  fprintf (fp,"#\n");
2186  fprintf (fp,"# 1 is a good number.  another possibility is the number of macroblock rows\n");
2187  fprintf (fp,"# (which is the height divided by 16)\n");
2188  fprintf (fp,"#\n");
2189  fprintf (fp,"SLICES_PER_FRAME 1\n");
2190  fprintf (fp,"\n");
2191  fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2192  fprintf (fp,"INPUT_DIR        /temp\n");
2193  fprintf (fp,"\n");
2194  fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2195  fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2196  fprintf (fp,"# way of numbering them.  See the manual for more information.\n");
2197  fprintf (fp,"INPUT\n");
2198  fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2199  fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2200  fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2201  fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2202  fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2203  fprintf (fp,"# if you do, too bad!!!\n");
2204  fprintf (fp,"#\n");
2205  fprintf (fp,"#\n");
2206  fprintf (fp,"Test*.ppm        [0-%d]\n",fRecordFrameNumber);
2207  fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2208  fprintf (fp,"# of files\n");
2209  fprintf (fp,"END_INPUT\n");
2210  fprintf (fp,"\n");
2211  fprintf (fp,"\n");
2212  fprintf (fp,"\n");
2213  fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2214  fprintf (fp,"\n");
2215  fprintf (fp,"# FULL or HALF -- must be upper case\n");
2216  fprintf (fp,"# Should be FULL for computer generated images\n");
2217  fprintf (fp,"PIXEL            FULL\n");
2218  fprintf (fp,"\n");
2219  fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2220  fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2221  fprintf (fp,"RANGE            10\n");
2222  fprintf (fp,"\n");
2223  fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2224  fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2225  fprintf (fp,"\n");
2226  fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2227  fprintf (fp,"PSEARCH_ALG      LOGARITHMIC\n");
2228  fprintf (fp,"\n");
2229  fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2230  fprintf (fp,"#\n");
2231  fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2232  fprintf (fp,"#\n");
2233  fprintf (fp,"BSEARCH_ALG      SIMPLE\n");
2234  fprintf (fp,"\n");
2235  fprintf (fp,"#\n");
2236  fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2237  fprintf (fp,"# (values must be between 1 and 31)\n");
2238  fprintf (fp,"# These are the Qscale values for the entire frame in variable bit-rate\n");
2239  fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2240  fprintf (fp,"#\n");
2241  fprintf (fp,"\n");
2242  fprintf (fp,"# Qscale (Quantization scale) affects quality and compression,\n");
2243  fprintf (fp,"# but has very little effect on speed.\n");
2244  fprintf (fp,"\n");
2245  fprintf (fp,"IQSCALE          4\n");
2246  fprintf (fp,"PQSCALE          5\n");
2247  fprintf (fp,"BQSCALE          12\n");
2248  fprintf (fp,"\n");
2249  fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2250  fprintf (fp,"REFERENCE_FRAME  ORIGINAL\n");
2251  fprintf (fp,"\n");
2252  fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2253  fprintf (fp,"\n");
2254  fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2255  fprintf (fp,"#BIT_RATE  1000000\n");
2256  fprintf (fp,"\n");
2257  fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2258  fprintf (fp,"BUFFER_SIZE 327680\n");
2259  fprintf (fp,"\n");
2260  fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2261  fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2262  fprintf (fp,"FRAME_RATE 30\n");
2263  fprintf (fp,"\n");
2264  fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2265  fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.\n");
2266  fprintf (fp,"\n");
2267  fprintf (fp,"\n");
2268  fclose (fp);
2269
2270  QProcess::execute ("/sw/bin/mpeg_encode", QStringList("/temp/parameter_file.par"));
2271  return true;
2272}
2273
2274/*
2275 
2276void MultiLayer::exportToSVG(const QString& fname)
2277{
2278  QPicture picture;
2279  QPainter p(&picture);
2280  for (int i=0;i<(int)graphsList->count();i++)
2281    {
2282      Graph *gr=(Graph *)graphsList->at(i);
2283      Plot *myPlot= (Plot *)gr->plotWidget();
2284     
2285      QPoint pos=gr->pos();
2286     
2287      int width=int(myPlot->frameGeometry().width());
2288      int height=int(myPlot->frameGeometry().height());
2289     
2290      myPlot->print(&p, QRect(pos,QSize(width,height)));
2291    }
2292 
2293  p.end();
2294  picture.save(fname, "svg");
2295}
2296*/
2297#endif
Note: See TracBrowser for help on using the repository browser.