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

Last change on this file since 970 was 959, checked in by garnier, 17 years ago

after maj on CVS good-HEAD

  • Property svn:mime-type set to text/cpp
File size: 80.3 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id: G4OpenGLQtViewer.cc,v 1.38 2009/03/05 16:36:13 lgarnier Exp $
28// GEANT4 tag $Name: $
29//
30//
31// G4OpenGLQtViewer : Class to provide Qt specific
32// functionality for OpenGL in GEANT4
33//
34
35#ifdef G4VIS_BUILD_OPENGLQT_DRIVER
36
37#include "G4OpenGLQtViewer.hh"
38#include "G4VViewer.hh"
39#include "G4VSceneHandler.hh"
40#include "G4OpenGLSceneHandler.hh"
41
42#include "G4ios.hh"
43#include "G4VisExtent.hh"
44#include "G4LogicalVolume.hh"
45#include "G4VSolid.hh"
46#include "G4Point3D.hh"
47#include "G4Normal3D.hh"
48#include "G4Scene.hh"
49#include "G4OpenGLQtExportDialog.hh"
50#include "G4OpenGLQtMovieDialog.hh"
51#include "G4UnitsTable.hh"
52#include "G4Qt.hh"
53#include "G4UImanager.hh"
54#include "G4UIcommandTree.hh"
55#include <qlayout.h>
56#include <qdialog.h>
57#include <qprocess.h>
58#include <qapplication.h>
59#include <qdesktopwidget.h>
60
61#if QT_VERSION >= 0x040000
62#include <qmenu.h>
63#include <qimagewriter.h>
64#else
65#include <qaction.h>
66#include <qwidgetlist.h>
67#include <qpopupmenu.h>
68#include <qimage.h>
69#endif
70
71#include <qapplication.h>
72#include <qmessagebox.h>
73#include <qfiledialog.h>
74#include <qprinter.h>
75#include <qdatetime.h>
76#include <qpainter.h>
77#include <qgl.h> // include <qglwidget.h>
78#include <qdialog.h>
79#include <qevent.h> //include <qcontextmenuevent.h>
80
81
82//////////////////////////////////////////////////////////////////////////////
83/**
84 Implementation of virtual method of G4VViewer
85*/
86void G4OpenGLQtViewer::SetView (
87)
88//////////////////////////////////////////////////////////////////////////////
89//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
90{
91 G4OpenGLViewer::SetView ();
92}
93
94
95
96
97//////////////////////////////////////////////////////////////////////////////
98void G4OpenGLQtViewer::CreateMainWindow (
99 QGLWidget* glWidget
100 ,QString name
101)
102//////////////////////////////////////////////////////////////////////////////
103//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
104{
105
106 if(fWindow) return; //Done.
107#ifdef G4DEBUG_VIS_OGL
108 printf("G4OpenGLQtViewer::CreateMainWindow glWidget\n");
109#endif
110
111 // launch Qt if not
112 G4Qt* interactorManager = G4Qt::getInstance ();
113 // G4UImanager* UI = G4UImanager::GetUIpointer();
114
115 fWindow = glWidget ;
116 // fWindow->makeCurrent();
117
118 // create window
119 if (((QApplication*)interactorManager->GetMainInteractor())) {
120 // look for the main window
121 bool found = false;
122#if QT_VERSION < 0x040000
123 // theses lines does nothing exept this one "GLWindow = new QDialog(0..."
124 // but if I comment them, it doesn't work...
125 QWidgetList *list = QApplication::allWidgets();
126 QWidgetListIt it( *list ); // iterate over the widgets
127 QWidget * widget;
128 while ( (widget=it.current()) != 0 ) { // for each widget...
129 ++it;
130 if ((found== false) && (widget->inherits("QMainWindow"))) {
131 GLWindow = new QDialog(0,0,FALSE,Qt::WStyle_Title | Qt::WStyle_SysMenu | Qt::WStyle_MinMax );
132 found = true;
133 }
134 }
135 delete list; // delete the list, not the widgets
136#else
137 foreach (QWidget *widget, QApplication::allWidgets()) {
138 if ((found== false) && (widget->inherits("QMainWindow"))) {
139 GLWindow = new QDialog(0,Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
140 found = true;
141 }
142 }
143#endif
144
145#if QT_VERSION < 0x040000
146 glWidget->reparent(GLWindow,0,QPoint(0,0));
147#else
148 glWidget->setParent(GLWindow);
149#endif
150
151 if (found==false) {
152#ifdef G4DEBUG_VIS_OGL
153 printf("G4OpenGLQtViewer::CreateMainWindow case Qapp exist, but not found\n");
154#endif
155 GLWindow = new QDialog();
156 }
157 } else {
158#ifdef G4DEBUG_VIS_OGL
159 printf("G4OpenGLQtViewer::CreateMainWindow case Qapp exist\n");
160#endif
161 GLWindow = new QDialog();
162 }
163
164 QHBoxLayout *mainLayout = new QHBoxLayout(GLWindow);
165
166 mainLayout->addWidget(fWindow);
167
168#if QT_VERSION < 0x040000
169 GLWindow->setCaption(name );
170#else
171 GLWindow->setLayout(mainLayout);
172 GLWindow->setWindowTitle( name);
173#endif
174 fWinSize_x = fVP.GetWindowSizeHintX();
175 fWinSize_y = 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 GLWindow->resize(fWinSize_x, fWinSize_y);
186 GLWindow->move(fVP.GetWindowAbsoluteLocationHintX(QApplication::desktop()->width()),YPos);
187 GLWindow->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// // GLWindow = 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( GLWindow,"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 (!GLWindow) {
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 != GLWindow->isFullScreen()) { //toggle
1237#if QT_VERSION >= 0x030200
1238 GLWindow->setWindowState(GLWindow->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#if QT_VERSION < 0x040000
1294 fPrintFilename = QFileDialog::getSaveFileName ( ".",
1295 filters,
1296 GLWindow,
1297 "Save file dialog",
1298 tr("Save as ..."),
1299 selectedFormat ).ascii();
1300#else
1301 fPrintFilename = QFileDialog::getSaveFileName ( GLWindow,
1302 tr("Save as ..."),
1303 ".",
1304 filters,
1305 selectedFormat ).toStdString().c_str();
1306#endif
1307 // bmp jpg jpeg png ppm xbm xpm
1308 if (fPrintFilename.empty()) {
1309 return;
1310 }
1311#if QT_VERSION < 0x040000
1312 fPrintFilename += "." + selectedFormat->ascii();
1313 QString format = selectedFormat->lower();
1314#else
1315 fPrintFilename += "." + selectedFormat->toStdString();
1316 QString format = selectedFormat->toLower();
1317#endif
1318 G4OpenGLQtExportDialog* exportDialog= new G4OpenGLQtExportDialog(GLWindow,format,fWindow->height(),fWindow->width());
1319 if( exportDialog->exec()) {
1320
1321 QImage image;
1322 bool res = false;
1323 if ((exportDialog->getWidth() !=fWindow->width()) ||
1324 (exportDialog->getHeight() !=fWindow->height())) {
1325 fPrintSizeX = exportDialog->getWidth();
1326 fPrintSizeY = exportDialog->getHeight();
1327 if ((format != QString("eps")) && (format != QString("ps"))) {
1328 G4cerr << "Export->Change Size : This function is not implemented, to export in another size, please resize your frame to what you need" << G4endl;
1329
1330 // rescaleImage(exportDialog->getWidth(),exportDialog->getHeight());// re-scale image
1331 // QGLWidget* glResized = fWindow;
1332
1333 // FIXME :
1334 // L.Garnier : I've try to implement change size function, but the problem is
1335 // the renderPixmap function call the QGLWidget to resize and it doesn't draw
1336 // the content of this widget... It only draw the background.
1337
1338 // fWindow->renderPixmap (exportDialog->getWidth()*2,exportDialog->getHeight()*2,true );
1339
1340 // QPixmap pixmap = fWindow->renderPixmap ();
1341
1342 // image = pixmap->toImage();
1343 // glResized->resize(exportDialog->getWidth()*2,exportDialog->getHeight()*2);
1344 // image = glResized->grabFrameBuffer();
1345 }
1346 } else {
1347 image = fWindow->grabFrameBuffer();
1348 }
1349 if (format == QString("eps")) {
1350 fVectoredPs = exportDialog->getVectorEPS();
1351 printEPS();
1352 } else if (format == "ps") {
1353 fVectoredPs = true;
1354 printEPS();
1355 } else if (format == "pdf") {
1356
1357 res = printPDF(fPrintFilename,exportDialog->getNbColor(),image);
1358
1359 } else if ((format == "tif") ||
1360 (format == "tiff") ||
1361 (format == "jpg") ||
1362 (format == "jpeg") ||
1363 (format == "png") ||
1364 (format == "pbm") ||
1365 (format == "pgm") ||
1366 (format == "ppm") ||
1367 (format == "bmp") ||
1368 (format == "xbm") ||
1369 (format == "xpm")) {
1370#if QT_VERSION < 0x040000
1371 res = image.save(QString(fPrintFilename.c_str()),selectedFormat->ascii(),exportDialog->getSliderValue());
1372#else
1373 res = image.save(QString(fPrintFilename.c_str()),0,exportDialog->getSliderValue());
1374#endif
1375 } else {
1376 G4cerr << "This version of G4UI Could not generate the selected format" << G4endl;
1377 }
1378 if ((format == QString("eps")) && (format == QString("ps"))) {
1379 if (res == false) {
1380 G4cerr << "Error while saving file... "<<fPrintFilename.c_str()<< G4endl;
1381 } else {
1382 G4cout << "File "<<fPrintFilename.c_str()<<" has been saved " << G4endl;
1383 }
1384 }
1385
1386 } else { // cancel selected
1387 return;
1388 }
1389
1390}
1391
1392
1393void G4OpenGLQtViewer::actionMovieParameters() {
1394 showMovieParametersDialog();
1395}
1396
1397
1398void G4OpenGLQtViewer::showMovieParametersDialog() {
1399 if (!fMovieParametersDialog) {
1400 fMovieParametersDialog= new G4OpenGLQtMovieDialog(this,GLWindow);
1401 displayRecordingStatus();
1402 fMovieParametersDialog->checkEncoderSwParameters();
1403 fMovieParametersDialog->checkSaveFileNameParameters();
1404 fMovieParametersDialog->checkTempFolderParameters();
1405 if (getEncoderPath() == "") {
1406 setRecordingInfos("mpeg_encode is needed to encode in video format. It is available here: http://bmrc.berkeley.edu/frame/research/mpeg/");
1407 }
1408 }
1409 fMovieParametersDialog->show();
1410}
1411
1412
1413/*
1414// 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
1415
1416void Graph::exportToSVG(const QString& fname)
1417{
1418 // enable workaround for Qt3 misalignments
1419 QwtPainter::setSVGMode(true);
1420 QPicture picture;
1421 QPainter p(&picture);
1422 d_plot->print(&p, d_plot->rect());
1423 p.end();
1424
1425 picture.save(fname, "svg");
1426}
1427*/
1428
1429
1430
1431void G4OpenGLQtViewer::FinishView()
1432{
1433 glFlush ();
1434 fWindow->swapBuffers ();
1435}
1436
1437/**
1438 Save the current mouse press point
1439 @param p mouse click point
1440*/
1441void G4OpenGLQtViewer::G4MousePressEvent(QMouseEvent *event)
1442{
1443#if QT_VERSION < 0x040000
1444 if ((event->button() & Qt::LeftButton)
1445 && !((event->state() & Qt::ShiftButton)
1446 || (event->state() & Qt::ControlButton)
1447 || (event->state() & Qt::AltButton)
1448 || (event->state() & Qt::MetaButton))) {
1449#else
1450 if ((event->buttons() & Qt::LeftButton)
1451 && !((event->modifiers() & Qt::ShiftModifier)
1452 || (event->modifiers() & Qt::ControlModifier)
1453 || (event->modifiers() & Qt::AltModifier)
1454 || (event->modifiers() & Qt::MetaModifier))) {
1455#endif
1456 fWindow->setMouseTracking(true);
1457 fAutoMove = false; // stop automove
1458 fLastPos1 = event->pos();
1459 fLastPos2 = fLastPos1;
1460 fLastPos3 = fLastPos2;
1461 fLastEventTime->start();
1462 if (fMouseAction == STYLE3){ // pick
1463 Pick(event->pos().x(),event->pos().y());
1464 }
1465 }
1466}
1467
1468/**
1469*/
1470void G4OpenGLQtViewer::G4MouseReleaseEvent()
1471{
1472 fSpinningDelay = fLastEventTime->elapsed();
1473 QPoint delta = (fLastPos3-fLastPos1);
1474 if ((delta.x() == 0) && (delta.y() == 0)) {
1475 return;
1476 }
1477 if (fSpinningDelay < fLaunchSpinDelay ) {
1478 fAutoMove = true;
1479 QTime lastMoveTime;
1480 lastMoveTime.start();
1481 // try to addapt speed move/rotate looking to drawing speed
1482 int cycles = 4;
1483 while (fAutoMove) {
1484 // if ( lastMoveTime.elapsed() > (fSpinningDelay / (cycles/2))) {
1485 if (fMouseAction == STYLE1) { // rotate
1486 rotateQtScene(((float)delta.x())/cycles,((float)delta.y())/cycles);
1487 } else if (fMouseAction == STYLE2) { // move
1488 moveScene(-((float)delta.x())/cycles,-((float)delta.y())/cycles,0,true);
1489 }
1490 lastMoveTime.start();
1491 cycles = 1 ;
1492 ((QApplication*)G4Qt::getInstance ())->processEvents();
1493 cycles ++ ;
1494 }
1495 }
1496 fWindow->setMouseTracking(false);
1497
1498}
1499
1500
1501void G4OpenGLQtViewer::G4MouseDoubleClickEvent()
1502{
1503 fWindow->setMouseTracking(true);
1504}
1505
1506
1507/**
1508 @param pos_x mouse x position
1509 @param pos_y mouse y position
1510 @param mButtons mouse button active
1511 @param mAutoMove true: apply this move till another evnt came, false :one time move
1512*/
1513
1514void G4OpenGLQtViewer::G4MouseMoveEvent(QMouseEvent *event)
1515{
1516
1517#if QT_VERSION < 0x040000
1518 Qt::ButtonState mButtons = event->state();
1519#else
1520 Qt::MouseButtons mButtons = event->buttons();
1521#endif
1522
1523 if (fAutoMove) {
1524 return;
1525 }
1526
1527 fLastPos3 = fLastPos2;
1528 fLastPos2 = fLastPos1;
1529 fLastPos1 = QPoint(event->x(), event->y());
1530
1531 int deltaX = fLastPos2.x()-fLastPos1.x();
1532 int deltaY = fLastPos2.y()-fLastPos1.y();
1533
1534 if (fMouseAction == STYLE1) { // rotate
1535 if (mButtons & Qt::LeftButton) {
1536 rotateQtScene(deltaX,deltaY);
1537 }
1538 } else if (fMouseAction == STYLE2) { // move
1539 if (mButtons & Qt::LeftButton) {
1540 moveScene(-deltaX,-deltaY,0,true);
1541 }
1542 }
1543
1544 fLastEventTime->start();
1545}
1546
1547
1548/**
1549 Move the scene of dx, dy, dz values.
1550 @param dx delta mouse x position
1551 @param dy delta mouse y position
1552 @param mouseMove : true if even comes from a mouse move, false if even comes from key action
1553*/
1554
1555void G4OpenGLQtViewer::moveScene(float dx,float dy, float dz,bool mouseMove)
1556{
1557 if (fHoldMoveEvent)
1558 return;
1559 fHoldMoveEvent = true;
1560
1561 G4double coefTrans = 0;
1562 GLdouble coefDepth = 0;
1563 if(mouseMove) {
1564 coefTrans = ((G4double)getSceneNearWidth())/((G4double)fWinSize_x);
1565 if (fWinSize_y <fWinSize_x) {
1566 coefTrans = ((G4double)getSceneNearWidth())/((G4double)fWinSize_y);
1567 }
1568 } else {
1569 coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1570 coefDepth = getSceneDepth()*fDeltaDepth;
1571 }
1572 fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1573 emit moveX(-dx*coefTrans);
1574 emit moveY(dy*coefTrans);
1575 emit moveZ(dz*coefTrans);
1576
1577 updateQWidget();
1578 if (fAutoMove)
1579 ((QApplication*)G4Qt::getInstance ())->processEvents();
1580
1581 fHoldMoveEvent = false;
1582}
1583
1584
1585/**
1586 @param dx delta mouse x position
1587 @param dy delta mouse y position
1588*/
1589
1590void G4OpenGLQtViewer::rotateQtScene(float dx, float dy)
1591{
1592 if (fHoldRotateEvent)
1593 return;
1594 fHoldRotateEvent = true;
1595
1596 if( dx != 0) {
1597 rotateScene(dx,0,fDeltaRotation);
1598 emit rotateTheta(dx);
1599 }
1600 if( dy != 0) {
1601 rotateScene(0,dy,fDeltaRotation);
1602 emit rotatePhi(dy);
1603 }
1604 updateQWidget();
1605
1606 fHoldRotateEvent = false;
1607}
1608
1609/**
1610 @param dx delta mouse x position
1611 @param dy delta mouse y position
1612*/
1613
1614void G4OpenGLQtViewer::rotateQtCamera(float dx, float dy)
1615{
1616 if (fHoldRotateEvent)
1617 return;
1618 fHoldRotateEvent = true;
1619
1620 rotateScene(dx,dy,fDeltaRotation);
1621 emit rotateTheta(dx);
1622 emit rotatePhi(dy);
1623 updateQWidget();
1624
1625 fHoldRotateEvent = false;
1626}
1627
1628
1629
1630
1631/** This is the benning of a rescale function. It does nothing for the moment
1632 @param aWidth : new width
1633 @param aHeight : new height
1634*/
1635void G4OpenGLQtViewer::rescaleImage(
1636 int /* aWidth */
1637,int /* aHeight */
1638){
1639 // GLfloat* feedback_buffer;
1640 // GLint returned;
1641 // FILE* file;
1642
1643// feedback_buffer = new GLfloat[size];
1644// glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1645// glRenderMode (GL_FEEDBACK);
1646
1647// DrawView();
1648// returned = glRenderMode (GL_RENDER);
1649
1650}
1651
1652
1653
1654/**
1655 Generate Postscript or PDF form image
1656 @param aFilename : name of file
1657 @param aInColor : numbers of colors : 1->BW 2->RGB
1658 @param aImage : Image to print
1659*/
1660bool G4OpenGLQtViewer::printPDF (
1661 const std::string aFilename
1662,int aInColor
1663,QImage aImage
1664)
1665{
1666
1667#if QT_VERSION < 0x040000
1668#ifdef Q_WS_MAC || Q_WS_X11
1669 QPrinter printer;
1670 // printer.setPageSize(pageSize);
1671 if (aInColor == 1) {
1672 printer.setColorMode(QPrinter::GrayScale);
1673 } else {
1674 printer.setColorMode(QPrinter::Color);
1675 }
1676
1677 /* FIXME : I don't know which format it will save...
1678 if (aFilename.endsWith(".ps")) {
1679 printer.setOutputFormat(QPrinter::PostScriptFormat);
1680 } else {
1681 printer.setOutputFormat(QPrinter::PdfFormat);
1682 }
1683 */
1684 printer.setOutputFileName(aFilename);
1685 // printer.setFullPage ( true);
1686 QPainter paint(&printer);
1687 paint.drawImage (0,0,aImage );
1688 paint.end();
1689#else
1690 G4cerr << "This fonction is only supported on Mac OsX or X11 with Qt3. Full platform supported with Qt4" << G4endl;
1691#endif
1692#else
1693 QPrinter printer;
1694 // printer.setPageSize(pageSize);
1695
1696 // FIXME : L. Garnier 4/12/07
1697 // This is not working, it does nothing. Image is staying in color mode
1698 // So I have desactivate the B/W button in GUI
1699 if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1700#if QT_VERSION < 0x040000
1701 aImage = aImage.convertDepth(1,Qt::MonoOnly);
1702#else
1703 aImage = aImage.convertToFormat ( aImage.format(), Qt::MonoOnly);
1704#endif
1705 }
1706
1707
1708 if (aFilename.substr(aFilename.size()-3) == ".ps") {
1709#if QT_VERSION > 0x040200
1710 printer.setOutputFormat(QPrinter::PostScriptFormat);
1711#endif
1712 } else {
1713#if QT_VERSION > 0x040100
1714 printer.setOutputFormat(QPrinter::PdfFormat);
1715#endif
1716 }
1717#if QT_VERSION > 0x040100
1718 printer.setOutputFileName(QString(aFilename.c_str()));
1719#endif
1720 // printer.setFullPage ( true);
1721 QPainter paint(&printer);
1722 paint.drawImage (0,0,aImage);
1723 paint.end();
1724#endif
1725 return true;
1726}
1727
1728
1729void G4OpenGLQtViewer::G4wheelEvent (QWheelEvent * event)
1730{
1731 fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.GetZoomFactor()*(event->delta())/1200));
1732 updateQWidget();
1733}
1734
1735
1736void G4OpenGLQtViewer::G4keyPressEvent (QKeyEvent * event)
1737{
1738 if (fHoldKeyEvent)
1739 return;
1740
1741 fHoldKeyEvent = true;
1742
1743#if QT_VERSION < 0x040000
1744 if ((event->key() == Qt::Key_Down) && (event->state() & Qt::AltButton )) { // go backward
1745#else
1746 if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::AltModifier )) { // go backward
1747#endif
1748
1749 moveScene(0,0,1,false);
1750 }
1751#if QT_VERSION < 0x040000
1752 else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::AltButton)) { // go forward
1753#else
1754 else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::AltModifier)) { // go forward
1755#endif
1756 moveScene(0,0,-1,false);
1757 }
1758#if QT_VERSION < 0x040000
1759 if ((event->key() == Qt::Key_Down) && (event->state() & Qt::ShiftButton)) { // rotate phi
1760#else
1761 if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
1762#endif
1763 rotateQtCamera(0,-1);
1764 }
1765#if QT_VERSION < 0x040000
1766 else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::ShiftButton)) { // rotate phi
1767#else
1768 else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
1769#endif
1770 rotateQtCamera(0,1);
1771 }
1772#if QT_VERSION < 0x040000
1773 if ((event->key() == Qt::Key_Left) && (event->state() & Qt::ShiftButton)) { // rotate theta
1774#else
1775 if ((event->key() == Qt::Key_Left) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
1776#endif
1777 rotateQtCamera(1,0);
1778 }
1779#if QT_VERSION < 0x040000
1780 else if ((event->key() == Qt::Key_Right) && (event->state() & Qt::ShiftButton)) { // rotate theta
1781#else
1782 else if ((event->key() == Qt::Key_Right) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
1783#endif
1784 rotateQtCamera(-1,0);
1785 }
1786
1787#if QT_VERSION < 0x040000
1788 if ((event->state() & Qt::AltButton)) {
1789#else
1790 if ((event->modifiers() & Qt::AltModifier)) {
1791#endif
1792 if (event->key() == Qt::Key_Plus) {
1793 fDeltaRotation = fDeltaRotation/0.7;
1794 }
1795 else if (event->key() == Qt::Key_Minus) {
1796 fDeltaRotation = fDeltaRotation*0.7;
1797 }
1798 } else {
1799 if (event->key() == Qt::Key_Plus) {
1800 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
1801 updateQWidget();
1802 }
1803 else if (event->key() == Qt::Key_Minus) {
1804 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
1805 updateQWidget();
1806 }
1807 }
1808
1809
1810 if (event->key() == Qt::Key_Escape) { // escaped from full screen
1811#if QT_VERSION >= 0x030200
1812 toggleFullScreen(false);
1813#endif
1814 }
1815 // several case here : If return is pressed, in every case -> display the movie parameters dialog
1816 // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
1817 // If encoder not found-> does nothing.Only display a message in status box
1818 // If all ok-> generate parameter file
1819 // If ok -> put encoder button enabled
1820
1821 if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)){ // end of video
1822 stopVideo();
1823 }
1824 if (event->key() == Qt::Key_Space){ // start/pause of video
1825 startPauseVideo();
1826 }
1827
1828 // with no modifiers
1829#if QT_VERSION < 0x040000
1830 if (event->state() == Qt::NoButton) {
1831#else
1832 if ((event->modifiers() == Qt::NoModifier) || (event->modifiers() == Qt::KeypadModifier )) {
1833#endif
1834 if (event->key() == Qt::Key_Down) { // go down
1835 moveScene(0,1,0,false);
1836 }
1837 else if (event->key() == Qt::Key_Up) { // go up
1838 moveScene(0,-1,0,false);
1839 }
1840 if (event->key() == Qt::Key_Left) { // go left
1841 moveScene(-1,0,0,false);
1842 }
1843 else if (event->key() == Qt::Key_Right) { // go right
1844 moveScene(1,0,0,false);
1845 }
1846 }
1847 fHoldKeyEvent = false;
1848}
1849
1850
1851/** Stop the video. Check all parameters and enable encoder button if all is ok.
1852*/
1853void G4OpenGLQtViewer::stopVideo() {
1854
1855 // if encoder parameter is wrong, display parameters dialog and return
1856 if (!fMovieParametersDialog) {
1857 showMovieParametersDialog();
1858 }
1859 setRecordingStatus(STOP);
1860
1861 if (fRecordFrameNumber >0) {
1862 // check parameters if they were modified (Re APPLY them...)
1863 if (!(fMovieParametersDialog->checkEncoderSwParameters())) {
1864 setRecordingStatus(BAD_ENCODER);
1865 } else if (!(fMovieParametersDialog->checkSaveFileNameParameters())) {
1866 setRecordingStatus(BAD_OUTPUT);
1867 }
1868 } else {
1869 resetRecording();
1870 setRecordingInfos("No frame to encode.");
1871 }
1872}
1873
1874/** Stop the video. Check all parameters and enable encoder button if all is ok.
1875*/
1876void G4OpenGLQtViewer::saveVideo() {
1877
1878 // if encoder parameter is wrong, display parameters dialog and return
1879 if (!fMovieParametersDialog) {
1880 showMovieParametersDialog();
1881 }
1882
1883 fMovieParametersDialog->checkEncoderSwParameters();
1884 fMovieParametersDialog->checkSaveFileNameParameters();
1885
1886 if (fRecordingStep == STOP) {
1887 setRecordingStatus(SAVE);
1888 generateMpegEncoderParameters();
1889 encodeVideo();
1890 }
1891}
1892
1893
1894/** Start/Pause the video..
1895*/
1896void G4OpenGLQtViewer::startPauseVideo() {
1897
1898 // first time, if temp parameter is wrong, display parameters dialog and return
1899
1900 if (( fRecordingStep == WAIT)) {
1901 if ( fRecordFrameNumber == 0) {
1902 if (getTempFolderPath() == "") { // BAD_OUTPUT
1903 showMovieParametersDialog();
1904 setRecordingInfos("You should specified the temp folder in order to make movie");
1905 return;
1906 } else {
1907 // remove temp folder if it was create
1908 QString tmp = removeTempFolder();
1909 if (tmp !="") {
1910 setRecordingInfos(tmp);
1911 return;
1912 }
1913 tmp = createTempFolder();
1914 if (tmp != "") {
1915 setRecordingInfos("Can't create temp folder."+tmp);
1916 return;
1917 }
1918 }
1919 }
1920 }
1921 if ((fRecordingStep == WAIT)) {
1922 setRecordingStatus(START);
1923 } else if (fRecordingStep == START) {
1924 setRecordingStatus(PAUSE);
1925 } else if (fRecordingStep == PAUSE) {
1926 setRecordingStatus(CONTINUE);
1927 } else if (fRecordingStep == CONTINUE) {
1928 setRecordingStatus(PAUSE);
1929 }
1930}
1931
1932void G4OpenGLQtViewer::setRecordingStatus(RECORDING_STEP step) {
1933
1934 fRecordingStep = step;
1935 displayRecordingStatus();
1936}
1937
1938
1939void G4OpenGLQtViewer::displayRecordingStatus() {
1940
1941 QString txtStatus = "";
1942 if (fRecordingStep == WAIT) {
1943 txtStatus = "Waiting to start...";
1944 fRecordFrameNumber = 0; // reset the frame number
1945 } else if (fRecordingStep == START) {
1946 txtStatus = "Start Recording...";
1947 } else if (fRecordingStep == PAUSE) {
1948 txtStatus = "Pause Recording...";
1949 } else if (fRecordingStep == CONTINUE) {
1950 txtStatus = "Continue Recording...";
1951 } else if (fRecordingStep == STOP) {
1952 txtStatus = "Stop Recording...";
1953 } else if (fRecordingStep == READY_TO_ENCODE) {
1954 txtStatus = "Ready to Encode...";
1955 } else if (fRecordingStep == ENCODING) {
1956 txtStatus = "Encoding...";
1957 } else if (fRecordingStep == FAILED) {
1958 txtStatus = "Failed to encode...";
1959 } else if ((fRecordingStep == BAD_ENCODER)
1960 || (fRecordingStep == BAD_OUTPUT)
1961 || (fRecordingStep == BAD_TMP)) {
1962 txtStatus = "Correct above errors first";
1963 } else if (fRecordingStep == SUCCESS) {
1964 txtStatus = "File encoded successfully";
1965 } else {
1966 }
1967
1968 if (fMovieParametersDialog) {
1969 fMovieParametersDialog->setRecordingStatus(txtStatus);
1970 } else {
1971#if QT_VERSION < 0x040000
1972 G4cout << txtStatus.ascii() << G4endl;
1973#else
1974 G4cout << txtStatus.toStdString().c_str() << G4endl;
1975#endif
1976 }
1977 setRecordingInfos("");
1978}
1979
1980
1981void G4OpenGLQtViewer::setRecordingInfos(QString txt) {
1982 if (fMovieParametersDialog) {
1983 fMovieParametersDialog->setRecordingInfos(txt);
1984 } else {
1985#if QT_VERSION < 0x040000
1986 G4cout << txt.ascii() << G4endl;
1987#else
1988 G4cout << txt.toStdString().c_str() << G4endl;
1989#endif
1990 }
1991}
1992
1993/** Init the movie parameters. Temp dir and encoder path
1994*/
1995void G4OpenGLQtViewer::initMovieParameters() {
1996 //init encoder
1997
1998 //look for encoderPath
1999 fProcess = new QProcess();
2000
2001#if QT_VERSION < 0x040000
2002 QObject ::connect(fProcess,SIGNAL(processExited ()),
2003 this,SLOT(processLookForFinished()));
2004 fProcess->setCommunication(QProcess::DupStderr);
2005 fProcess->setArguments(QStringList("which mpeg_encode"));
2006 fProcess->start();
2007#else
2008 QObject ::connect(fProcess,SIGNAL(finished ( int)),
2009 this,SLOT(processLookForFinished()));
2010 fProcess->setReadChannelMode(QProcess::MergedChannels);
2011 fProcess->start ("which mpeg_encode");
2012#endif
2013
2014}
2015
2016/** @return encoder path or "" if it does not exist
2017 */
2018QString G4OpenGLQtViewer::getEncoderPath() {
2019 return fEncoderPath;
2020}
2021
2022
2023/**
2024 * set the new encoder path
2025 * @return "" if correct. The error otherwise
2026*/
2027QString G4OpenGLQtViewer::setEncoderPath(QString path) {
2028 if (path == "") {
2029 return "File does not exist";
2030 }
2031
2032#if QT_VERSION < 0x040000
2033 path = QDir::cleanDirPath(path);
2034#else
2035 path = QDir::cleanPath(path);
2036#endif
2037 QFileInfo *f = new QFileInfo(path);
2038 if (!f->exists()) {
2039 return "File does not exist";
2040 } else if (f->isDir()) {
2041 return "This is a directory";
2042 } else if (!f->isExecutable()) {
2043 return "File exist but is not executable";
2044 } else if (!f->isFile()) {
2045 return "This is not a file";
2046 }
2047 fEncoderPath = path;
2048
2049 if ((fRecordingStep == BAD_ENCODER)) {
2050 setRecordingStatus(STOP);
2051 }
2052 return "";
2053}
2054
2055
2056bool G4OpenGLQtViewer::isRecording(){
2057 if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
2058 return true;
2059 }
2060 return false;
2061}
2062
2063bool G4OpenGLQtViewer::isPaused(){
2064 if (fRecordingStep == PAUSE) {
2065 return true;
2066 }
2067 return false;
2068}
2069
2070bool G4OpenGLQtViewer::isEncoding(){
2071 if (fRecordingStep == ENCODING) {
2072 return true;
2073 }
2074 return false;
2075}
2076
2077bool G4OpenGLQtViewer::isWaiting(){
2078 if (fRecordingStep == WAIT) {
2079 return true;
2080 }
2081 return false;
2082}
2083
2084bool G4OpenGLQtViewer::isStopped(){
2085 if (fRecordingStep == STOP) {
2086 return true;
2087 }
2088 return false;
2089}
2090
2091bool G4OpenGLQtViewer::isFailed(){
2092 if (fRecordingStep == FAILED) {
2093 return true;
2094 }
2095 return false;
2096}
2097
2098bool G4OpenGLQtViewer::isSuccess(){
2099 if (fRecordingStep == SUCCESS) {
2100 return true;
2101 }
2102 return false;
2103}
2104
2105bool G4OpenGLQtViewer::isBadEncoder(){
2106 if (fRecordingStep == BAD_ENCODER) {
2107 return true;
2108 }
2109 return false;
2110}
2111bool G4OpenGLQtViewer::isBadTmp(){
2112 if (fRecordingStep == BAD_TMP) {
2113 return true;
2114 }
2115 return false;
2116}
2117bool G4OpenGLQtViewer::isBadOutput(){
2118 if (fRecordingStep == BAD_OUTPUT) {
2119 return true;
2120 }
2121 return false;
2122}
2123
2124void G4OpenGLQtViewer::setBadEncoder(){
2125 fRecordingStep = BAD_ENCODER;
2126 displayRecordingStatus();
2127}
2128void G4OpenGLQtViewer::setBadTmp(){
2129 fRecordingStep = BAD_TMP;
2130 displayRecordingStatus();
2131}
2132void G4OpenGLQtViewer::setBadOutput(){
2133 fRecordingStep = BAD_OUTPUT;
2134 displayRecordingStatus();
2135}
2136
2137void G4OpenGLQtViewer::setWaiting(){
2138 fRecordingStep = WAIT;
2139 displayRecordingStatus();
2140}
2141
2142
2143bool G4OpenGLQtViewer::isReadyToEncode(){
2144 if (fRecordingStep == READY_TO_ENCODE) {
2145 return true;
2146 }
2147 return false;
2148}
2149
2150void G4OpenGLQtViewer::resetRecording() {
2151 setRecordingStatus(WAIT);
2152}
2153
2154/**
2155 * set the temp folder path
2156 * @return "" if correct. The error otherwise
2157*/
2158QString G4OpenGLQtViewer::setTempFolderPath(QString path) {
2159
2160 if (path == "") {
2161 return "Path does not exist";
2162 }
2163#if QT_VERSION < 0x040000
2164 path = QDir::cleanDirPath(path);
2165#else
2166 path = QDir::cleanPath(path);
2167#endif
2168 QFileInfo *d = new QFileInfo(path);
2169 if (!d->exists()) {
2170 return "Path does not exist";
2171 } else if (!d->isDir()) {
2172 return "This is not a directory";
2173 } else if (!d->isReadable()) {
2174 return path +" is read protected";
2175 } else if (!d->isWritable()) {
2176 return path +" is write protected";
2177 }
2178
2179 if ((fRecordingStep == BAD_TMP)) {
2180 setRecordingStatus(WAIT);
2181 }
2182 fTempFolderPath = path;
2183 return "";
2184}
2185
2186/** @return the temp folder path or "" if it does not exist
2187 */
2188QString G4OpenGLQtViewer::getTempFolderPath() {
2189 return fTempFolderPath;
2190}
2191
2192/**
2193 * set the save file name path
2194 * @return "" if correct. The error otherwise
2195*/
2196QString G4OpenGLQtViewer::setSaveFileName(QString path) {
2197
2198 if (path == "") {
2199 return "Path does not exist";
2200 }
2201
2202 QFileInfo *file = new QFileInfo(path);
2203 QDir dir = file->dir();
2204#if QT_VERSION < 0x040000
2205 path = QDir::cleanDirPath(path);
2206#else
2207 path = QDir::cleanPath(path);
2208#endif
2209 if (file->exists()) {
2210 return "File already exist, please choose a new one";
2211 } else if (!dir.exists()) {
2212 return "Dir does not exist";
2213 } else if (!dir.isReadable()) {
2214 return path +" is read protected";
2215 }
2216
2217 if ((fRecordingStep == BAD_OUTPUT)) {
2218 setRecordingStatus(STOP);
2219 }
2220 fSaveFileName = path;
2221 return "";
2222}
2223
2224/** @return the save file path
2225 */
2226QString G4OpenGLQtViewer::getSaveFileName() {
2227 return fSaveFileName ;
2228}
2229
2230/** Create a Qt_temp folder in the temp folder given
2231* The temp folder will be like this /tmp/QtMovie_12-02-2008_12_12_58/
2232* @return "" if success. Error message if not.
2233*/
2234QString G4OpenGLQtViewer::createTempFolder() {
2235 fMovieTempFolderPath = "";
2236 //check
2237 QString tmp = setTempFolderPath(fTempFolderPath);
2238 if (tmp != "") {
2239 return tmp;
2240 }
2241#if QT_VERSION < 0x040000
2242 QString sep = QChar(QDir::separator());
2243#else
2244 QString sep = QString(QDir::separator());
2245#endif
2246 QString path = sep+"QtMovie_"+QDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+sep;
2247#if QT_VERSION < 0x040000
2248 QDir *d = new QDir(QDir::cleanDirPath(fTempFolderPath));
2249#else
2250 QDir *d = new QDir(QDir::cleanPath(fTempFolderPath));
2251#endif
2252 // check if it is already present
2253 if (d->exists(path)) {
2254 return "Folder "+path+" already exists.Please remove it first";
2255 }
2256 if (d->mkdir(fTempFolderPath+path)) {
2257 fMovieTempFolderPath = fTempFolderPath+path;
2258 return "";
2259 } else {
2260 return "Can't create "+fTempFolderPath+path;
2261 }
2262 return "-";
2263}
2264
2265/** Remove the Qt_temp folder in the temp folder
2266*/
2267QString G4OpenGLQtViewer::removeTempFolder() {
2268 // remove files in Qt_temp folder
2269 if (fMovieTempFolderPath == "") {
2270 return "";
2271 }
2272#if QT_VERSION < 0x040000
2273 QDir *d = new QDir(QDir::cleanDirPath(fMovieTempFolderPath));
2274#else
2275 QDir *d = new QDir(QDir::cleanPath(fMovieTempFolderPath));
2276#endif
2277 if (!d->exists()) {
2278 return ""; // already remove
2279 }
2280
2281 d->setFilter( QDir::Files );
2282 QStringList subDirList = d->entryList();
2283 int res = true;
2284 QString error = "";
2285 for (QStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
2286 const QString currentFile = *it;
2287 if (!d->remove(currentFile)) {
2288 res = false;
2289 QString file = fMovieTempFolderPath+currentFile;
2290 error +="Removing file failed : "+file;
2291 } else {
2292 }
2293 }
2294 if (res) {
2295 if (d->rmdir(fMovieTempFolderPath)) {
2296 fMovieTempFolderPath = "";
2297 return "";
2298 } else {
2299 return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
2300 }
2301
2302 }
2303 return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
2304}
2305
2306
2307
2308bool G4OpenGLQtViewer::hasPendingEvents () {
2309 return ((QApplication*)G4Qt::getInstance ())->hasPendingEvents ();
2310}
2311
2312bool G4OpenGLQtViewer::generateMpegEncoderParameters () {
2313
2314 // save the parameter file
2315 FILE* fp;
2316#if QT_VERSION < 0x040000
2317 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).ascii(), "w");
2318#else
2319 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).toStdString().c_str(), "w");
2320#endif
2321
2322 if (fp == NULL) {
2323 setRecordingInfos("Generation of parameter file failed");
2324 return false;
2325 }
2326
2327 fprintf (fp,"# parameter file template with lots of comments to assist you\n");
2328 fprintf (fp,"#\n");
2329 fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
2330 fprintf (fp,"# the copy\n");
2331 fprintf (fp,"#\n");
2332 fprintf (fp,"#\n");
2333 fprintf (fp,"# any line beginning with '#' is a comment\n");
2334 fprintf (fp,"#\n");
2335 fprintf (fp,"# no line should be longer than 255 characters\n");
2336 fprintf (fp,"#\n");
2337 fprintf (fp,"#\n");
2338 fprintf (fp,"# general format of each line is:\n");
2339 fprintf (fp,"# \n");
2340 fprintf (fp,"#\n");
2341 fprintf (fp,"# lines can generally be in any order\n");
2342 fprintf (fp,"#\n");
2343 fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
2344 fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
2345 fprintf (fp,"#\n");
2346 fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
2347 fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
2348 fprintf (fp,"# the INPUT parameter.\n");
2349 fprintf (fp,"#\n");
2350 fprintf (fp,"# MUST be in UPPER CASE\n");
2351 fprintf (fp,"#\n");
2352 fprintf (fp,"\n");
2353 fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
2354 fprintf (fp,"# for more info.\n");
2355 fprintf (fp,"\n");
2356 fprintf (fp,"PATTERN IBBPBBPBBPBBPBBP\n");
2357#if QT_VERSION < 0x040000
2358 fprintf (fp,"OUTPUT %s\n",getSaveFileName().ascii());
2359#else
2360 fprintf (fp,"OUTPUT %s\n",getSaveFileName().toStdString().c_str());
2361#endif
2362 fprintf (fp,"\n");
2363 fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
2364 fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
2365 fprintf (fp,"#\n");
2366 fprintf (fp,"# You must specify the type of the input files. The choices are:\n");
2367 fprintf (fp,"# YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
2368 fprintf (fp,"# (must be upper case)\n");
2369 fprintf (fp,"#\n");
2370 fprintf (fp,"BASE_FILE_FORMAT PPM\n");
2371 fprintf (fp,"\n");
2372 fprintf (fp,"#\n");
2373 fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
2374 fprintf (fp,"# YUV_SIZE widthxheight\n");
2375 fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
2376 fprintf (fp,"# on just one machine\n");
2377 fprintf (fp,"#\n");
2378 fprintf (fp,"YUV_SIZE 352x240\n");
2379 fprintf (fp,"\n");
2380 fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
2381 fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
2382 fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2383 fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
2384 fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
2385 fprintf (fp,"# to specify the file order.\n");
2386 fprintf (fp,"\n");
2387 fprintf (fp,"INPUT_FORMAT UCB\n");
2388 fprintf (fp,"\n");
2389 fprintf (fp,"# the conversion statement\n");
2390 fprintf (fp,"#\n");
2391 fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
2392 fprintf (fp,"#\n");
2393 fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
2394 fprintf (fp,"# INPUT_CONVERT giftoppm *\n");
2395 fprintf (fp,"#\n");
2396 fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2397 fprintf (fp,"# INPUT_CONVERT cat *.Y *.U *.V\n");
2398 fprintf (fp,"#\n");
2399 fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
2400 fprintf (fp,"# INPUT_CONVERT goto frame *; grabppm\n");
2401 fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2402 fprintf (fp,"#\n");
2403 fprintf (fp,"INPUT_CONVERT * \n");
2404 fprintf (fp,"\n");
2405 fprintf (fp,"# number of frames in a GOP.\n");
2406 fprintf (fp,"#\n");
2407 fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
2408 fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2409 fprintf (fp,"#\n");
2410 fprintf (fp,"# later, will add more flexible GOP signalling\n");
2411 fprintf (fp,"#\n");
2412 fprintf (fp,"GOP_SIZE 16\n");
2413 fprintf (fp,"\n");
2414 fprintf (fp,"# number of slices in a frame\n");
2415 fprintf (fp,"#\n");
2416 fprintf (fp,"# 1 is a good number. another possibility is the number of macroblock rows\n");
2417 fprintf (fp,"# (which is the height divided by 16)\n");
2418 fprintf (fp,"#\n");
2419 fprintf (fp,"SLICES_PER_FRAME 1\n");
2420 fprintf (fp,"\n");
2421 fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2422#if QT_VERSION < 0x040000
2423 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.ascii());
2424#else
2425 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.toStdString().c_str());
2426#endif
2427 fprintf (fp,"\n");
2428 fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2429 fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2430 fprintf (fp,"# way of numbering them. See the manual for more information.\n");
2431 fprintf (fp,"INPUT\n");
2432 fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2433 fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2434 fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2435 fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2436 fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2437 fprintf (fp,"# if you do, too bad!!!\n");
2438 fprintf (fp,"#\n");
2439 fprintf (fp,"#\n");
2440 fprintf (fp,"Test*.ppm [0-%d]\n",fRecordFrameNumber-1);
2441 fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2442 fprintf (fp,"# of files\n");
2443 fprintf (fp,"END_INPUT\n");
2444 fprintf (fp,"\n");
2445 fprintf (fp,"\n");
2446 fprintf (fp,"\n");
2447 fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2448 fprintf (fp,"\n");
2449 fprintf (fp,"# FULL or HALF -- must be upper case\n");
2450 fprintf (fp,"# Should be FULL for computer generated images\n");
2451 fprintf (fp,"PIXEL FULL\n");
2452 fprintf (fp,"\n");
2453 fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2454 fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2455 fprintf (fp,"RANGE 10\n");
2456 fprintf (fp,"\n");
2457 fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2458 fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2459 fprintf (fp,"\n");
2460 fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2461 fprintf (fp,"PSEARCH_ALG LOGARITHMIC\n");
2462 fprintf (fp,"\n");
2463 fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2464 fprintf (fp,"#\n");
2465 fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2466 fprintf (fp,"#\n");
2467 fprintf (fp,"BSEARCH_ALG SIMPLE\n");
2468 fprintf (fp,"\n");
2469 fprintf (fp,"#\n");
2470 fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2471 fprintf (fp,"# (values must be between 1 and 31)\n");
2472 fprintf (fp,"# These are the Qscale values for the entire frame in variable bit-rate\n");
2473 fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2474 fprintf (fp,"#\n");
2475 fprintf (fp,"\n");
2476 fprintf (fp,"# Qscale (Quantization scale) affects quality and compression,\n");
2477 fprintf (fp,"# but has very little effect on speed.\n");
2478 fprintf (fp,"\n");
2479 fprintf (fp,"IQSCALE 4\n");
2480 fprintf (fp,"PQSCALE 5\n");
2481 fprintf (fp,"BQSCALE 12\n");
2482 fprintf (fp,"\n");
2483 fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2484 fprintf (fp,"REFERENCE_FRAME ORIGINAL\n");
2485 fprintf (fp,"\n");
2486 fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2487 fprintf (fp,"\n");
2488 fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2489 fprintf (fp,"#BIT_RATE 1000000\n");
2490 fprintf (fp,"\n");
2491 fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2492 fprintf (fp,"BUFFER_SIZE 327680\n");
2493 fprintf (fp,"\n");
2494 fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2495 fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2496 fprintf (fp,"FRAME_RATE 30\n");
2497 fprintf (fp,"\n");
2498 fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2499 fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.\n");
2500 fprintf (fp,"\n");
2501 fprintf (fp,"\n");
2502 fclose (fp);
2503
2504 setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
2505 setRecordingStatus(READY_TO_ENCODE);
2506 return true;
2507}
2508
2509void G4OpenGLQtViewer::encodeVideo()
2510{
2511 if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
2512 setRecordingStatus(ENCODING);
2513
2514#if QT_VERSION < 0x040000
2515 QStringList args = QStringList(fEncoderPath);
2516 args.push_back(fMovieTempFolderPath+fParameterFileName);
2517 fProcess = new QProcess(args);
2518 QObject ::connect(fProcess,SIGNAL(processExited ()),
2519 this,SLOT(processEncodeFinished()));
2520 QObject ::connect(fProcess,SIGNAL(readyReadStdout ()),
2521 this,SLOT(processEncodeStdout()));
2522 fProcess->setCommunication(QProcess::DupStderr);
2523 fProcess->launch("");
2524#else
2525 fProcess = new QProcess();
2526#if QT_VERSION > 0x040100
2527 QObject ::connect(fProcess,SIGNAL(finished ( int,QProcess::ExitStatus)),
2528 this,SLOT(processEncodeFinished()));
2529 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2530 this,SLOT(processEncodeStdout()));
2531#else
2532 QObject ::connect(fProcess,SIGNAL(finished ( int)),
2533 this,SLOT(processEncodeFinished()));
2534 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2535 this,SLOT(processEncodeStdout()));
2536#endif
2537 fProcess->setReadChannelMode(QProcess::MergedChannels);
2538 fProcess->start (fEncoderPath, QStringList(fMovieTempFolderPath+fParameterFileName));
2539#endif
2540 }
2541}
2542
2543
2544// FIXME : does not work on Qt3
2545void G4OpenGLQtViewer::processEncodeStdout()
2546{
2547#if QT_VERSION > 0x040000
2548 QString tmp = fProcess->readAllStandardOutput ().data();
2549 int start = tmp.lastIndexOf("ESTIMATED TIME");
2550 tmp = tmp.mid(start,tmp.indexOf("\n",start)-start);
2551#else
2552 QString tmp = fProcess->readStdout ().data();
2553 int start = tmp.findRev("ESTIMATED TIME");
2554 tmp = tmp.mid(start,tmp.find("\n",start)-start);
2555#endif
2556 setRecordingInfos(tmp);
2557}
2558
2559
2560void G4OpenGLQtViewer::processEncodeFinished()
2561{
2562
2563 QString txt = "";
2564 txt = getProcessErrorMsg();
2565 if (txt == "") {
2566 setRecordingStatus(SUCCESS);
2567 } else {
2568 setRecordingStatus(FAILED);
2569 }
2570 // setRecordingInfos(txt+removeTempFolder());
2571}
2572
2573
2574void G4OpenGLQtViewer::processLookForFinished()
2575 {
2576
2577 QString txt = getProcessErrorMsg();
2578 if (txt != "") {
2579 fEncoderPath = "";
2580 } else {
2581#if QT_VERSION > 0x040000
2582 fEncoderPath = QString(fProcess->readAllStandardOutput ().data()).trimmed();
2583#else
2584 fEncoderPath = QString(fProcess->readStdout ().data()).simplifyWhiteSpace();
2585#endif
2586 // if not found, return "not found"
2587 if (fEncoderPath.contains(" ")) {
2588 fEncoderPath = "";
2589 } else if (!fEncoderPath.contains("mpeg_encode")) {
2590 fEncoderPath = "";
2591 }
2592 setEncoderPath(fEncoderPath);
2593 }
2594 // init temp folder
2595#if QT_VERSION > 0x040000
2596 setTempFolderPath(QDir::temp ().absolutePath ());
2597#else
2598 // Let's have a try
2599 setTempFolderPath("/tmp/");
2600#endif
2601}
2602
2603
2604QString G4OpenGLQtViewer::getProcessErrorMsg()
2605{
2606 QString txt = "";
2607#if QT_VERSION < 0x040000
2608 if (!fProcess->normalExit ()) {
2609 txt = "Exist status "+ fProcess->exitStatus ();
2610 }
2611#else
2612 if (fProcess->exitCode() != 0) {
2613 switch (fProcess->error()) {
2614 case QProcess::FailedToStart:
2615 txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2616 break;
2617 case QProcess::Crashed:
2618 txt = "The process crashed some time after starting successfully.\n";
2619 break;
2620 case QProcess::Timedout:
2621 txt = "The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.\n";
2622 break;
2623 case QProcess::WriteError:
2624 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";
2625 break;
2626 case QProcess::ReadError:
2627 txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2628 break;
2629 case QProcess::UnknownError:
2630 txt = "An unknown error occurred. This is the default return value of error().\n";
2631 break;
2632 }
2633 }
2634#endif
2635 return txt;
2636}
2637
2638/*
2639
2640void MultiLayer::exportToSVG(const QString& fname)
2641{
2642 QPicture picture;
2643 QPainter p(&picture);
2644 for (int i=0;i<(int)graphsList->count();i++)
2645 {
2646 Graph *gr=(Graph *)graphsList->at(i);
2647 Plot *myPlot= (Plot *)gr->plotWidget();
2648
2649 QPoint pos=gr->pos();
2650
2651 int width=int(myPlot->frameGeometry().width());
2652 int height=int(myPlot->frameGeometry().height());
2653
2654 myPlot->print(&p, QRect(pos,QSize(width,height)));
2655 }
2656
2657 p.end();
2658 picture.save(fname, "svg");
2659}
2660*/
2661#endif
Note: See TracBrowser for help on using the repository browser.