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

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

see history

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