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

Last change on this file since 1136 was 1135, checked in by garnier, 15 years ago

preparation to integrate Vis in UI for Qt

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