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

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

pre-tag revision and some improvments

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