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

Last change on this file since 1268 was 1259, checked in by garnier, 16 years ago

best auto rotation

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