source: trunk/source/visualization/OpenGL/src/G4OpenGLQtViewer.cc~@ 1355

Last change on this file since 1355 was 1350, checked in by garnier, 15 years ago

update to last version 4.9.4

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