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

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

avant modif pour CVS

  • 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.40 2009/05/06 13:51:21 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#if QT_VERSION < 0x040000
1294 fPrintFilename = QFileDialog::getSaveFileName ( ".",
1295 filters,
1296 fGLWindow,
1297 "Save file dialog",
1298 tr("Save as ..."),
1299 selectedFormat ).ascii();
1300#else
1301 fPrintFilename = QFileDialog::getSaveFileName ( fGLWindow,
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 += "." + std::string(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(fGLWindow,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,fGLWindow);
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)getWinWidth());
1565 if (getWinHeight() <getWinWidth()) {
1566 coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinHeight());
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#if defined(Q_WS_MAC) || defined(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 // FIXME
1692 // L.Garnier 6 May 2009 : Only to fix compilation warnings
1693 if (aFilename.empty()) {
1694 aInColor = 0;
1695 aImage = 0;
1696 }
1697 // END_OF FIXME
1698#endif
1699#else
1700 QPrinter printer;
1701 // printer.setPageSize(pageSize);
1702
1703 // FIXME : L. Garnier 4/12/07
1704 // This is not working, it does nothing. Image is staying in color mode
1705 // So I have desactivate the B/W button in GUI
1706 if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1707#if QT_VERSION < 0x040000
1708 aImage = aImage.convertDepth(1,Qt::MonoOnly);
1709#else
1710 aImage = aImage.convertToFormat ( aImage.format(), Qt::MonoOnly);
1711#endif
1712 }
1713
1714
1715 if (aFilename.substr(aFilename.size()-3) == ".ps") {
1716#if QT_VERSION > 0x040200
1717 printer.setOutputFormat(QPrinter::PostScriptFormat);
1718#endif
1719 } else {
1720#if QT_VERSION > 0x040100
1721 printer.setOutputFormat(QPrinter::PdfFormat);
1722#endif
1723 }
1724#if QT_VERSION > 0x040100
1725 printer.setOutputFileName(QString(aFilename.c_str()));
1726#endif
1727 // printer.setFullPage ( true);
1728 QPainter paint(&printer);
1729 paint.drawImage (0,0,aImage);
1730 paint.end();
1731#endif
1732 return true;
1733}
1734
1735
1736void G4OpenGLQtViewer::G4wheelEvent (QWheelEvent * event)
1737{
1738 fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.GetZoomFactor()*(event->delta())/1200));
1739 updateQWidget();
1740}
1741
1742
1743void G4OpenGLQtViewer::G4keyPressEvent (QKeyEvent * event)
1744{
1745 if (fHoldKeyEvent)
1746 return;
1747
1748 fHoldKeyEvent = true;
1749
1750#if QT_VERSION < 0x040000
1751 if ((event->key() == Qt::Key_Down) && (event->state() & Qt::AltButton )) { // go backward
1752#else
1753 if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::AltModifier )) { // go backward
1754#endif
1755
1756 moveScene(0,0,1,false);
1757 }
1758#if QT_VERSION < 0x040000
1759 else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::AltButton)) { // go forward
1760#else
1761 else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::AltModifier)) { // go forward
1762#endif
1763 moveScene(0,0,-1,false);
1764 }
1765#if QT_VERSION < 0x040000
1766 if ((event->key() == Qt::Key_Down) && (event->state() & Qt::ShiftButton)) { // rotate phi
1767#else
1768 if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
1769#endif
1770 rotateQtCamera(0,-1);
1771 }
1772#if QT_VERSION < 0x040000
1773 else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::ShiftButton)) { // rotate phi
1774#else
1775 else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
1776#endif
1777 rotateQtCamera(0,1);
1778 }
1779#if QT_VERSION < 0x040000
1780 if ((event->key() == Qt::Key_Left) && (event->state() & Qt::ShiftButton)) { // rotate theta
1781#else
1782 if ((event->key() == Qt::Key_Left) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
1783#endif
1784 rotateQtCamera(1,0);
1785 }
1786#if QT_VERSION < 0x040000
1787 else if ((event->key() == Qt::Key_Right) && (event->state() & Qt::ShiftButton)) { // rotate theta
1788#else
1789 else if ((event->key() == Qt::Key_Right) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
1790#endif
1791 rotateQtCamera(-1,0);
1792 }
1793
1794#if QT_VERSION < 0x040000
1795 if ((event->state() & Qt::AltButton)) {
1796#else
1797 if ((event->modifiers() & Qt::AltModifier)) {
1798#endif
1799 if (event->key() == Qt::Key_Plus) {
1800 fDeltaRotation = fDeltaRotation/0.7;
1801 }
1802 else if (event->key() == Qt::Key_Minus) {
1803 fDeltaRotation = fDeltaRotation*0.7;
1804 }
1805 } else {
1806 if (event->key() == Qt::Key_Plus) {
1807 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
1808 updateQWidget();
1809 }
1810 else if (event->key() == Qt::Key_Minus) {
1811 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
1812 updateQWidget();
1813 }
1814 }
1815
1816
1817 if (event->key() == Qt::Key_Escape) { // escaped from full screen
1818#if QT_VERSION >= 0x030200
1819 toggleFullScreen(false);
1820#endif
1821 }
1822 // several case here : If return is pressed, in every case -> display the movie parameters dialog
1823 // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
1824 // If encoder not found-> does nothing.Only display a message in status box
1825 // If all ok-> generate parameter file
1826 // If ok -> put encoder button enabled
1827
1828 if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)){ // end of video
1829 stopVideo();
1830 }
1831 if (event->key() == Qt::Key_Space){ // start/pause of video
1832 startPauseVideo();
1833 }
1834
1835 // with no modifiers
1836#if QT_VERSION < 0x040000
1837 if (event->state() == Qt::NoButton) {
1838#else
1839 if ((event->modifiers() == Qt::NoModifier) || (event->modifiers() == Qt::KeypadModifier )) {
1840#endif
1841 if (event->key() == Qt::Key_Down) { // go down
1842 moveScene(0,1,0,false);
1843 }
1844 else if (event->key() == Qt::Key_Up) { // go up
1845 moveScene(0,-1,0,false);
1846 }
1847 if (event->key() == Qt::Key_Left) { // go left
1848 moveScene(-1,0,0,false);
1849 }
1850 else if (event->key() == Qt::Key_Right) { // go right
1851 moveScene(1,0,0,false);
1852 }
1853 }
1854 fHoldKeyEvent = false;
1855}
1856
1857
1858/** Stop the video. Check all parameters and enable encoder button if all is ok.
1859*/
1860void G4OpenGLQtViewer::stopVideo() {
1861
1862 // if encoder parameter is wrong, display parameters dialog and return
1863 if (!fMovieParametersDialog) {
1864 showMovieParametersDialog();
1865 }
1866 setRecordingStatus(STOP);
1867
1868 if (fRecordFrameNumber >0) {
1869 // check parameters if they were modified (Re APPLY them...)
1870 if (!(fMovieParametersDialog->checkEncoderSwParameters())) {
1871 setRecordingStatus(BAD_ENCODER);
1872 } else if (!(fMovieParametersDialog->checkSaveFileNameParameters())) {
1873 setRecordingStatus(BAD_OUTPUT);
1874 }
1875 } else {
1876 resetRecording();
1877 setRecordingInfos("No frame to encode.");
1878 }
1879}
1880
1881/** Stop the video. Check all parameters and enable encoder button if all is ok.
1882*/
1883void G4OpenGLQtViewer::saveVideo() {
1884
1885 // if encoder parameter is wrong, display parameters dialog and return
1886 if (!fMovieParametersDialog) {
1887 showMovieParametersDialog();
1888 }
1889
1890 fMovieParametersDialog->checkEncoderSwParameters();
1891 fMovieParametersDialog->checkSaveFileNameParameters();
1892
1893 if (fRecordingStep == STOP) {
1894 setRecordingStatus(SAVE);
1895 generateMpegEncoderParameters();
1896 encodeVideo();
1897 }
1898}
1899
1900
1901/** Start/Pause the video..
1902*/
1903void G4OpenGLQtViewer::startPauseVideo() {
1904
1905 // first time, if temp parameter is wrong, display parameters dialog and return
1906
1907 if (( fRecordingStep == WAIT)) {
1908 if ( fRecordFrameNumber == 0) {
1909 if (getTempFolderPath() == "") { // BAD_OUTPUT
1910 showMovieParametersDialog();
1911 setRecordingInfos("You should specified the temp folder in order to make movie");
1912 return;
1913 } else {
1914 // remove temp folder if it was create
1915 QString tmp = removeTempFolder();
1916 if (tmp !="") {
1917 setRecordingInfos(tmp);
1918 return;
1919 }
1920 tmp = createTempFolder();
1921 if (tmp != "") {
1922 setRecordingInfos("Can't create temp folder."+tmp);
1923 return;
1924 }
1925 }
1926 }
1927 }
1928 if ((fRecordingStep == WAIT)) {
1929 setRecordingStatus(START);
1930 } else if (fRecordingStep == START) {
1931 setRecordingStatus(PAUSE);
1932 } else if (fRecordingStep == PAUSE) {
1933 setRecordingStatus(CONTINUE);
1934 } else if (fRecordingStep == CONTINUE) {
1935 setRecordingStatus(PAUSE);
1936 }
1937}
1938
1939void G4OpenGLQtViewer::setRecordingStatus(RECORDING_STEP step) {
1940
1941 fRecordingStep = step;
1942 displayRecordingStatus();
1943}
1944
1945
1946void G4OpenGLQtViewer::displayRecordingStatus() {
1947
1948 QString txtStatus = "";
1949 if (fRecordingStep == WAIT) {
1950 txtStatus = "Waiting to start...";
1951 fRecordFrameNumber = 0; // reset the frame number
1952 } else if (fRecordingStep == START) {
1953 txtStatus = "Start Recording...";
1954 } else if (fRecordingStep == PAUSE) {
1955 txtStatus = "Pause Recording...";
1956 } else if (fRecordingStep == CONTINUE) {
1957 txtStatus = "Continue Recording...";
1958 } else if (fRecordingStep == STOP) {
1959 txtStatus = "Stop Recording...";
1960 } else if (fRecordingStep == READY_TO_ENCODE) {
1961 txtStatus = "Ready to Encode...";
1962 } else if (fRecordingStep == ENCODING) {
1963 txtStatus = "Encoding...";
1964 } else if (fRecordingStep == FAILED) {
1965 txtStatus = "Failed to encode...";
1966 } else if ((fRecordingStep == BAD_ENCODER)
1967 || (fRecordingStep == BAD_OUTPUT)
1968 || (fRecordingStep == BAD_TMP)) {
1969 txtStatus = "Correct above errors first";
1970 } else if (fRecordingStep == SUCCESS) {
1971 txtStatus = "File encoded successfully";
1972 } else {
1973 }
1974
1975 if (fMovieParametersDialog) {
1976 fMovieParametersDialog->setRecordingStatus(txtStatus);
1977 } else {
1978#if QT_VERSION < 0x040000
1979 G4cout << txtStatus.ascii() << G4endl;
1980#else
1981 G4cout << txtStatus.toStdString().c_str() << G4endl;
1982#endif
1983 }
1984 setRecordingInfos("");
1985}
1986
1987
1988void G4OpenGLQtViewer::setRecordingInfos(QString txt) {
1989 if (fMovieParametersDialog) {
1990 fMovieParametersDialog->setRecordingInfos(txt);
1991 } else {
1992#if QT_VERSION < 0x040000
1993 G4cout << txt.ascii() << G4endl;
1994#else
1995 G4cout << txt.toStdString().c_str() << G4endl;
1996#endif
1997 }
1998}
1999
2000/** Init the movie parameters. Temp dir and encoder path
2001*/
2002void G4OpenGLQtViewer::initMovieParameters() {
2003 //init encoder
2004
2005 //look for encoderPath
2006 fProcess = new QProcess();
2007
2008#if QT_VERSION < 0x040000
2009 QObject ::connect(fProcess,SIGNAL(processExited ()),
2010 this,SLOT(processLookForFinished()));
2011 fProcess->setCommunication(QProcess::DupStderr);
2012 fProcess->setArguments(QStringList("which mpeg_encode"));
2013 fProcess->start();
2014#else
2015 QObject ::connect(fProcess,SIGNAL(finished ( int)),
2016 this,SLOT(processLookForFinished()));
2017 fProcess->setReadChannelMode(QProcess::MergedChannels);
2018 fProcess->start ("which mpeg_encode");
2019#endif
2020
2021}
2022
2023/** @return encoder path or "" if it does not exist
2024 */
2025QString G4OpenGLQtViewer::getEncoderPath() {
2026 return fEncoderPath;
2027}
2028
2029
2030/**
2031 * set the new encoder path
2032 * @return "" if correct. The error otherwise
2033*/
2034QString G4OpenGLQtViewer::setEncoderPath(QString path) {
2035 if (path == "") {
2036 return "File does not exist";
2037 }
2038
2039#if QT_VERSION < 0x040000
2040 path = QDir::cleanDirPath(path);
2041#else
2042 path = QDir::cleanPath(path);
2043#endif
2044 QFileInfo *f = new QFileInfo(path);
2045 if (!f->exists()) {
2046 return "File does not exist";
2047 } else if (f->isDir()) {
2048 return "This is a directory";
2049 } else if (!f->isExecutable()) {
2050 return "File exist but is not executable";
2051 } else if (!f->isFile()) {
2052 return "This is not a file";
2053 }
2054 fEncoderPath = path;
2055
2056 if ((fRecordingStep == BAD_ENCODER)) {
2057 setRecordingStatus(STOP);
2058 }
2059 return "";
2060}
2061
2062
2063bool G4OpenGLQtViewer::isRecording(){
2064 if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
2065 return true;
2066 }
2067 return false;
2068}
2069
2070bool G4OpenGLQtViewer::isPaused(){
2071 if (fRecordingStep == PAUSE) {
2072 return true;
2073 }
2074 return false;
2075}
2076
2077bool G4OpenGLQtViewer::isEncoding(){
2078 if (fRecordingStep == ENCODING) {
2079 return true;
2080 }
2081 return false;
2082}
2083
2084bool G4OpenGLQtViewer::isWaiting(){
2085 if (fRecordingStep == WAIT) {
2086 return true;
2087 }
2088 return false;
2089}
2090
2091bool G4OpenGLQtViewer::isStopped(){
2092 if (fRecordingStep == STOP) {
2093 return true;
2094 }
2095 return false;
2096}
2097
2098bool G4OpenGLQtViewer::isFailed(){
2099 if (fRecordingStep == FAILED) {
2100 return true;
2101 }
2102 return false;
2103}
2104
2105bool G4OpenGLQtViewer::isSuccess(){
2106 if (fRecordingStep == SUCCESS) {
2107 return true;
2108 }
2109 return false;
2110}
2111
2112bool G4OpenGLQtViewer::isBadEncoder(){
2113 if (fRecordingStep == BAD_ENCODER) {
2114 return true;
2115 }
2116 return false;
2117}
2118bool G4OpenGLQtViewer::isBadTmp(){
2119 if (fRecordingStep == BAD_TMP) {
2120 return true;
2121 }
2122 return false;
2123}
2124bool G4OpenGLQtViewer::isBadOutput(){
2125 if (fRecordingStep == BAD_OUTPUT) {
2126 return true;
2127 }
2128 return false;
2129}
2130
2131void G4OpenGLQtViewer::setBadEncoder(){
2132 fRecordingStep = BAD_ENCODER;
2133 displayRecordingStatus();
2134}
2135void G4OpenGLQtViewer::setBadTmp(){
2136 fRecordingStep = BAD_TMP;
2137 displayRecordingStatus();
2138}
2139void G4OpenGLQtViewer::setBadOutput(){
2140 fRecordingStep = BAD_OUTPUT;
2141 displayRecordingStatus();
2142}
2143
2144void G4OpenGLQtViewer::setWaiting(){
2145 fRecordingStep = WAIT;
2146 displayRecordingStatus();
2147}
2148
2149
2150bool G4OpenGLQtViewer::isReadyToEncode(){
2151 if (fRecordingStep == READY_TO_ENCODE) {
2152 return true;
2153 }
2154 return false;
2155}
2156
2157void G4OpenGLQtViewer::resetRecording() {
2158 setRecordingStatus(WAIT);
2159}
2160
2161/**
2162 * set the temp folder path
2163 * @return "" if correct. The error otherwise
2164*/
2165QString G4OpenGLQtViewer::setTempFolderPath(QString path) {
2166
2167 if (path == "") {
2168 return "Path does not exist";
2169 }
2170#if QT_VERSION < 0x040000
2171 path = QDir::cleanDirPath(path);
2172#else
2173 path = QDir::cleanPath(path);
2174#endif
2175 QFileInfo *d = new QFileInfo(path);
2176 if (!d->exists()) {
2177 return "Path does not exist";
2178 } else if (!d->isDir()) {
2179 return "This is not a directory";
2180 } else if (!d->isReadable()) {
2181 return path +" is read protected";
2182 } else if (!d->isWritable()) {
2183 return path +" is write protected";
2184 }
2185
2186 if ((fRecordingStep == BAD_TMP)) {
2187 setRecordingStatus(WAIT);
2188 }
2189 fTempFolderPath = path;
2190 return "";
2191}
2192
2193/** @return the temp folder path or "" if it does not exist
2194 */
2195QString G4OpenGLQtViewer::getTempFolderPath() {
2196 return fTempFolderPath;
2197}
2198
2199/**
2200 * set the save file name path
2201 * @return "" if correct. The error otherwise
2202*/
2203QString G4OpenGLQtViewer::setSaveFileName(QString path) {
2204
2205 if (path == "") {
2206 return "Path does not exist";
2207 }
2208
2209 QFileInfo *file = new QFileInfo(path);
2210 QDir dir = file->dir();
2211#if QT_VERSION < 0x040000
2212 path = QDir::cleanDirPath(path);
2213#else
2214 path = QDir::cleanPath(path);
2215#endif
2216 if (file->exists()) {
2217 return "File already exist, please choose a new one";
2218 } else if (!dir.exists()) {
2219 return "Dir does not exist";
2220 } else if (!dir.isReadable()) {
2221 return path +" is read protected";
2222 }
2223
2224 if ((fRecordingStep == BAD_OUTPUT)) {
2225 setRecordingStatus(STOP);
2226 }
2227 fSaveFileName = path;
2228 return "";
2229}
2230
2231/** @return the save file path
2232 */
2233QString G4OpenGLQtViewer::getSaveFileName() {
2234 return fSaveFileName ;
2235}
2236
2237/** Create a Qt_temp folder in the temp folder given
2238* The temp folder will be like this /tmp/QtMovie_12-02-2008_12_12_58/
2239* @return "" if success. Error message if not.
2240*/
2241QString G4OpenGLQtViewer::createTempFolder() {
2242 fMovieTempFolderPath = "";
2243 //check
2244 QString tmp = setTempFolderPath(fTempFolderPath);
2245 if (tmp != "") {
2246 return tmp;
2247 }
2248#if QT_VERSION < 0x040000
2249 QString sep = QChar(QDir::separator());
2250#else
2251 QString sep = QString(QDir::separator());
2252#endif
2253 QString path = sep+"QtMovie_"+QDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+sep;
2254#if QT_VERSION < 0x040000
2255 QDir *d = new QDir(QDir::cleanDirPath(fTempFolderPath));
2256#else
2257 QDir *d = new QDir(QDir::cleanPath(fTempFolderPath));
2258#endif
2259 // check if it is already present
2260 if (d->exists(path)) {
2261 return "Folder "+path+" already exists.Please remove it first";
2262 }
2263 if (d->mkdir(fTempFolderPath+path)) {
2264 fMovieTempFolderPath = fTempFolderPath+path;
2265 return "";
2266 } else {
2267 return "Can't create "+fTempFolderPath+path;
2268 }
2269 return "-";
2270}
2271
2272/** Remove the Qt_temp folder in the temp folder
2273*/
2274QString G4OpenGLQtViewer::removeTempFolder() {
2275 // remove files in Qt_temp folder
2276 if (fMovieTempFolderPath == "") {
2277 return "";
2278 }
2279#if QT_VERSION < 0x040000
2280 QDir *d = new QDir(QDir::cleanDirPath(fMovieTempFolderPath));
2281#else
2282 QDir *d = new QDir(QDir::cleanPath(fMovieTempFolderPath));
2283#endif
2284 if (!d->exists()) {
2285 return ""; // already remove
2286 }
2287
2288 d->setFilter( QDir::Files );
2289 QStringList subDirList = d->entryList();
2290 int res = true;
2291 QString error = "";
2292 for (QStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
2293 const QString currentFile = *it;
2294 if (!d->remove(currentFile)) {
2295 res = false;
2296 QString file = fMovieTempFolderPath+currentFile;
2297 error +="Removing file failed : "+file;
2298 } else {
2299 }
2300 }
2301 if (res) {
2302 if (d->rmdir(fMovieTempFolderPath)) {
2303 fMovieTempFolderPath = "";
2304 return "";
2305 } else {
2306 return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
2307 }
2308
2309 }
2310 return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
2311}
2312
2313
2314
2315bool G4OpenGLQtViewer::hasPendingEvents () {
2316 return ((QApplication*)G4Qt::getInstance ())->hasPendingEvents ();
2317}
2318
2319bool G4OpenGLQtViewer::generateMpegEncoderParameters () {
2320
2321 // save the parameter file
2322 FILE* fp;
2323#if QT_VERSION < 0x040000
2324 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).ascii(), "w");
2325#else
2326 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).toStdString().c_str(), "w");
2327#endif
2328
2329 if (fp == NULL) {
2330 setRecordingInfos("Generation of parameter file failed");
2331 return false;
2332 }
2333
2334 fprintf (fp,"# parameter file template with lots of comments to assist you\n");
2335 fprintf (fp,"#\n");
2336 fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
2337 fprintf (fp,"# the copy\n");
2338 fprintf (fp,"#\n");
2339 fprintf (fp,"#\n");
2340 fprintf (fp,"# any line beginning with '#' is a comment\n");
2341 fprintf (fp,"#\n");
2342 fprintf (fp,"# no line should be longer than 255 characters\n");
2343 fprintf (fp,"#\n");
2344 fprintf (fp,"#\n");
2345 fprintf (fp,"# general format of each line is:\n");
2346 fprintf (fp,"# \n");
2347 fprintf (fp,"#\n");
2348 fprintf (fp,"# lines can generally be in any order\n");
2349 fprintf (fp,"#\n");
2350 fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
2351 fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
2352 fprintf (fp,"#\n");
2353 fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
2354 fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
2355 fprintf (fp,"# the INPUT parameter.\n");
2356 fprintf (fp,"#\n");
2357 fprintf (fp,"# MUST be in UPPER CASE\n");
2358 fprintf (fp,"#\n");
2359 fprintf (fp,"\n");
2360 fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
2361 fprintf (fp,"# for more info.\n");
2362 fprintf (fp,"\n");
2363 fprintf (fp,"PATTERN IBBPBBPBBPBBPBBP\n");
2364#if QT_VERSION < 0x040000
2365 fprintf (fp,"OUTPUT %s\n",getSaveFileName().ascii());
2366#else
2367 fprintf (fp,"OUTPUT %s\n",getSaveFileName().toStdString().c_str());
2368#endif
2369 fprintf (fp,"\n");
2370 fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
2371 fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
2372 fprintf (fp,"#\n");
2373 fprintf (fp,"# You must specify the type of the input files. The choices are:\n");
2374 fprintf (fp,"# YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
2375 fprintf (fp,"# (must be upper case)\n");
2376 fprintf (fp,"#\n");
2377 fprintf (fp,"BASE_FILE_FORMAT PPM\n");
2378 fprintf (fp,"\n");
2379 fprintf (fp,"#\n");
2380 fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
2381 fprintf (fp,"# YUV_SIZE widthxheight\n");
2382 fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
2383 fprintf (fp,"# on just one machine\n");
2384 fprintf (fp,"#\n");
2385 fprintf (fp,"YUV_SIZE 352x240\n");
2386 fprintf (fp,"\n");
2387 fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
2388 fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
2389 fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2390 fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
2391 fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
2392 fprintf (fp,"# to specify the file order.\n");
2393 fprintf (fp,"\n");
2394 fprintf (fp,"INPUT_FORMAT UCB\n");
2395 fprintf (fp,"\n");
2396 fprintf (fp,"# the conversion statement\n");
2397 fprintf (fp,"#\n");
2398 fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
2399 fprintf (fp,"#\n");
2400 fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
2401 fprintf (fp,"# INPUT_CONVERT giftoppm *\n");
2402 fprintf (fp,"#\n");
2403 fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2404 fprintf (fp,"# INPUT_CONVERT cat *.Y *.U *.V\n");
2405 fprintf (fp,"#\n");
2406 fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
2407 fprintf (fp,"# INPUT_CONVERT goto frame *; grabppm\n");
2408 fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2409 fprintf (fp,"#\n");
2410 fprintf (fp,"INPUT_CONVERT * \n");
2411 fprintf (fp,"\n");
2412 fprintf (fp,"# number of frames in a GOP.\n");
2413 fprintf (fp,"#\n");
2414 fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
2415 fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2416 fprintf (fp,"#\n");
2417 fprintf (fp,"# later, will add more flexible GOP signalling\n");
2418 fprintf (fp,"#\n");
2419 fprintf (fp,"GOP_SIZE 16\n");
2420 fprintf (fp,"\n");
2421 fprintf (fp,"# number of slices in a frame\n");
2422 fprintf (fp,"#\n");
2423 fprintf (fp,"# 1 is a good number. another possibility is the number of macroblock rows\n");
2424 fprintf (fp,"# (which is the height divided by 16)\n");
2425 fprintf (fp,"#\n");
2426 fprintf (fp,"SLICES_PER_FRAME 1\n");
2427 fprintf (fp,"\n");
2428 fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2429#if QT_VERSION < 0x040000
2430 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.ascii());
2431#else
2432 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.toStdString().c_str());
2433#endif
2434 fprintf (fp,"\n");
2435 fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2436 fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2437 fprintf (fp,"# way of numbering them. See the manual for more information.\n");
2438 fprintf (fp,"INPUT\n");
2439 fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2440 fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2441 fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2442 fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2443 fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2444 fprintf (fp,"# if you do, too bad!!!\n");
2445 fprintf (fp,"#\n");
2446 fprintf (fp,"#\n");
2447 fprintf (fp,"Test*.ppm [0-%d]\n",fRecordFrameNumber-1);
2448 fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2449 fprintf (fp,"# of files\n");
2450 fprintf (fp,"END_INPUT\n");
2451 fprintf (fp,"\n");
2452 fprintf (fp,"\n");
2453 fprintf (fp,"\n");
2454 fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2455 fprintf (fp,"\n");
2456 fprintf (fp,"# FULL or HALF -- must be upper case\n");
2457 fprintf (fp,"# Should be FULL for computer generated images\n");
2458 fprintf (fp,"PIXEL FULL\n");
2459 fprintf (fp,"\n");
2460 fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2461 fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2462 fprintf (fp,"RANGE 10\n");
2463 fprintf (fp,"\n");
2464 fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2465 fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2466 fprintf (fp,"\n");
2467 fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2468 fprintf (fp,"PSEARCH_ALG LOGARITHMIC\n");
2469 fprintf (fp,"\n");
2470 fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2471 fprintf (fp,"#\n");
2472 fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2473 fprintf (fp,"#\n");
2474 fprintf (fp,"BSEARCH_ALG SIMPLE\n");
2475 fprintf (fp,"\n");
2476 fprintf (fp,"#\n");
2477 fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2478 fprintf (fp,"# (values must be between 1 and 31)\n");
2479 fprintf (fp,"# These are the Qscale values for the entire frame in variable bit-rate\n");
2480 fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2481 fprintf (fp,"#\n");
2482 fprintf (fp,"\n");
2483 fprintf (fp,"# Qscale (Quantization scale) affects quality and compression,\n");
2484 fprintf (fp,"# but has very little effect on speed.\n");
2485 fprintf (fp,"\n");
2486 fprintf (fp,"IQSCALE 4\n");
2487 fprintf (fp,"PQSCALE 5\n");
2488 fprintf (fp,"BQSCALE 12\n");
2489 fprintf (fp,"\n");
2490 fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2491 fprintf (fp,"REFERENCE_FRAME ORIGINAL\n");
2492 fprintf (fp,"\n");
2493 fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2494 fprintf (fp,"\n");
2495 fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2496 fprintf (fp,"#BIT_RATE 1000000\n");
2497 fprintf (fp,"\n");
2498 fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2499 fprintf (fp,"BUFFER_SIZE 327680\n");
2500 fprintf (fp,"\n");
2501 fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2502 fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2503 fprintf (fp,"FRAME_RATE 30\n");
2504 fprintf (fp,"\n");
2505 fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2506 fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.\n");
2507 fprintf (fp,"\n");
2508 fprintf (fp,"\n");
2509 fclose (fp);
2510
2511 setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
2512 setRecordingStatus(READY_TO_ENCODE);
2513 return true;
2514}
2515
2516void G4OpenGLQtViewer::encodeVideo()
2517{
2518 if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
2519 setRecordingStatus(ENCODING);
2520
2521#if QT_VERSION < 0x040000
2522 QStringList args = QStringList(fEncoderPath);
2523 args.push_back(fMovieTempFolderPath+fParameterFileName);
2524 fProcess = new QProcess(args);
2525 QObject ::connect(fProcess,SIGNAL(processExited ()),
2526 this,SLOT(processEncodeFinished()));
2527 QObject ::connect(fProcess,SIGNAL(readyReadStdout ()),
2528 this,SLOT(processEncodeStdout()));
2529 fProcess->setCommunication(QProcess::DupStderr);
2530 fProcess->launch("");
2531#else
2532 fProcess = new QProcess();
2533#if QT_VERSION > 0x040100
2534 QObject ::connect(fProcess,SIGNAL(finished ( int,QProcess::ExitStatus)),
2535 this,SLOT(processEncodeFinished()));
2536 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2537 this,SLOT(processEncodeStdout()));
2538#else
2539 QObject ::connect(fProcess,SIGNAL(finished ( int)),
2540 this,SLOT(processEncodeFinished()));
2541 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2542 this,SLOT(processEncodeStdout()));
2543#endif
2544 fProcess->setReadChannelMode(QProcess::MergedChannels);
2545 fProcess->start (fEncoderPath, QStringList(fMovieTempFolderPath+fParameterFileName));
2546#endif
2547 }
2548}
2549
2550
2551// FIXME : does not work on Qt3
2552void G4OpenGLQtViewer::processEncodeStdout()
2553{
2554#if QT_VERSION > 0x040000
2555 QString tmp = fProcess->readAllStandardOutput ().data();
2556 int start = tmp.lastIndexOf("ESTIMATED TIME");
2557 tmp = tmp.mid(start,tmp.indexOf("\n",start)-start);
2558#else
2559 QString tmp = fProcess->readStdout ().data();
2560 int start = tmp.findRev("ESTIMATED TIME");
2561 tmp = tmp.mid(start,tmp.find("\n",start)-start);
2562#endif
2563 setRecordingInfos(tmp);
2564}
2565
2566
2567void G4OpenGLQtViewer::processEncodeFinished()
2568{
2569
2570 QString txt = "";
2571 txt = getProcessErrorMsg();
2572 if (txt == "") {
2573 setRecordingStatus(SUCCESS);
2574 } else {
2575 setRecordingStatus(FAILED);
2576 }
2577 // setRecordingInfos(txt+removeTempFolder());
2578}
2579
2580
2581void G4OpenGLQtViewer::processLookForFinished()
2582 {
2583
2584 QString txt = getProcessErrorMsg();
2585 if (txt != "") {
2586 fEncoderPath = "";
2587 } else {
2588#if QT_VERSION > 0x040000
2589 fEncoderPath = QString(fProcess->readAllStandardOutput ().data()).trimmed();
2590#else
2591 fEncoderPath = QString(fProcess->readStdout ().data()).simplifyWhiteSpace();
2592#endif
2593 // if not found, return "not found"
2594 if (fEncoderPath.contains(" ")) {
2595 fEncoderPath = "";
2596 } else if (!fEncoderPath.contains("mpeg_encode")) {
2597 fEncoderPath = "";
2598 }
2599 setEncoderPath(fEncoderPath);
2600 }
2601 // init temp folder
2602#if QT_VERSION > 0x040000
2603 setTempFolderPath(QDir::temp ().absolutePath ());
2604#else
2605 // Let's have a try
2606 setTempFolderPath("/tmp/");
2607#endif
2608}
2609
2610
2611QString G4OpenGLQtViewer::getProcessErrorMsg()
2612{
2613 QString txt = "";
2614#if QT_VERSION < 0x040000
2615 if (!fProcess->normalExit ()) {
2616 txt = "Exist status "+ fProcess->exitStatus ();
2617 }
2618#else
2619 if (fProcess->exitCode() != 0) {
2620 switch (fProcess->error()) {
2621 case QProcess::FailedToStart:
2622 txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2623 break;
2624 case QProcess::Crashed:
2625 txt = "The process crashed some time after starting successfully.\n";
2626 break;
2627 case QProcess::Timedout:
2628 txt = "The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.\n";
2629 break;
2630 case QProcess::WriteError:
2631 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";
2632 break;
2633 case QProcess::ReadError:
2634 txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2635 break;
2636 case QProcess::UnknownError:
2637 txt = "An unknown error occurred. This is the default return value of error().\n";
2638 break;
2639 }
2640 }
2641#endif
2642 return txt;
2643}
2644
2645/*
2646
2647void MultiLayer::exportToSVG(const QString& fname)
2648{
2649 QPicture picture;
2650 QPainter p(&picture);
2651 for (int i=0;i<(int)graphsList->count();i++)
2652 {
2653 Graph *gr=(Graph *)graphsList->at(i);
2654 Plot *myPlot= (Plot *)gr->plotWidget();
2655
2656 QPoint pos=gr->pos();
2657
2658 int width=int(myPlot->frameGeometry().width());
2659 int height=int(myPlot->frameGeometry().height());
2660
2661 myPlot->print(&p, QRect(pos,QSize(width,height)));
2662 }
2663
2664 p.end();
2665 picture.save(fname, "svg");
2666}
2667*/
2668#endif
Note: See TracBrowser for help on using the repository browser.