source: trunk/source/visualization/OpenGL/src/#G4OpenGLQtViewer.cc# @ 1350

Last change on this file since 1350 was 1350, checked in by garnier, 13 years ago

update to last version 4.9.4

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