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

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

print improvments begin, see History file

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