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

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

warning fix on Win VC 9

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