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

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

better tab intergration in UI

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