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

Last change on this file since 1318 was 1314, checked in by garnier, 15 years ago

en test pas dans CVS

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