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

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

suppres des debug et modif des WinSize

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