source: trunk/source/visualization/OpenGL/src/G4OpenGLQtViewer.cc @ 1259

Last change on this file since 1259 was 1259, checked in by garnier, 14 years ago

best auto rotation

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