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

Last change on this file since 1344 was 1340, checked in by garnier, 15 years ago

update ti head

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