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

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

before tag

  • Property svn:mime-type set to text/cpp
File size: 87.6 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id: G4OpenGLQtViewer.cc,v 1.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 float globalTime = 0;
1543 float globalRun = 0;
1544 while (fAutoMove) {
1545 if ( lastMoveTime.elapsed () >= (int)(1000/fNbMaxFramesPerSec)) {
1546 float lTime = 1000/((float)lastMoveTime.elapsed ());
1547 if (((((float)delta.x())/correctionFactor)*lTime > fNbMaxAnglePerSec) ||
1548 ((((float)delta.x())/correctionFactor)*lTime < -fNbMaxAnglePerSec) ) {
1549 correctionFactor = (float)delta.x()*(lTime/fNbMaxAnglePerSec);
1550 if (delta.x() <0 ) {
1551 correctionFactor = -correctionFactor;
1552 }
1553 }
1554 if (((((float)delta.y())/correctionFactor)*lTime > fNbMaxAnglePerSec) ||
1555 ((((float)delta.y())/correctionFactor)*lTime < -fNbMaxAnglePerSec) ) {
1556 correctionFactor = (float)delta.y()*(lTime/fNbMaxAnglePerSec);
1557 if (delta.y() <0 ) {
1558 correctionFactor = -correctionFactor;
1559 }
1560 }
1561
1562 // Check Qt Versions for META Keys
1563
1564 // Click and move mouse to rotate volume
1565 // ALT + Click and move mouse to rotate volume (View Direction)
1566 // SHIFT + Click and move camera point of view
1567 // CTRL + Click and zoom mouse to zoom in/out
1568
1569 if (fMouseAction == STYLE1) { // rotate
1570 if (fNoKeyPress) {
1571 rotateQtScene(((float)delta.x())/correctionFactor,((float)delta.y())/correctionFactor);
1572 } else if (fAltKeyPress) {
1573 rotateQtSceneInViewDirection(((float)delta.x())/correctionFactor,((float)delta.y())/correctionFactor);
1574 }
1575
1576 } else if (fMouseAction == STYLE2) { // move
1577 moveScene(-((float)delta.x())/correctionFactor,-((float)delta.y())/correctionFactor,0,true);
1578 }
1579 //#ifdef G4DEBUG_VIS_OGL
1580 globalTime += (float)lastMoveTime.elapsed ();
1581 globalRun +=1;
1582 printf("G4OpenGLQtViewer::CreateMainWindow :: time/per run :%f run:%f %f\n",globalTime/globalRun,globalRun,globalTime);
1583 //#endif
1584 lastMoveTime.start();
1585 }
1586 ((QApplication*)G4Qt::getInstance ())->processEvents();
1587 }
1588 }
1589 fWindow->setMouseTracking(false);
1590
1591}
1592
1593
1594void G4OpenGLQtViewer::G4MouseDoubleClickEvent()
1595{
1596 fWindow->setMouseTracking(true);
1597}
1598
1599
1600/**
1601 @param pos_x mouse x position
1602 @param pos_y mouse y position
1603 @param mButtons mouse button active
1604 @param mAutoMove true: apply this move till another evnt came, false :one time move
1605*/
1606
1607void G4OpenGLQtViewer::G4MouseMoveEvent(QMouseEvent *event)
1608{
1609
1610#if QT_VERSION < 0x040000
1611 Qt::ButtonState mButtons = event->state();
1612#else
1613 Qt::MouseButtons mButtons = event->buttons();
1614#endif
1615
1616#if QT_VERSION < 0x040000
1617 updateKeyModifierState(event->state());
1618#else
1619 updateKeyModifierState(event->modifiers());
1620#endif
1621
1622 if (fAutoMove) {
1623 return;
1624 }
1625
1626 fLastPos3 = fLastPos2;
1627 fLastPos2 = fLastPos1;
1628 fLastPos1 = QPoint(event->x(), event->y());
1629
1630 int deltaX = fLastPos2.x()-fLastPos1.x();
1631 int deltaY = fLastPos2.y()-fLastPos1.y();
1632
1633 if (fMouseAction == STYLE1) { // rotate
1634 if (mButtons & Qt::LeftButton) {
1635 if (fNoKeyPress) {
1636 rotateQtScene(((float)deltaX),((float)deltaY));
1637 } else if (fAltKeyPress) {
1638 rotateQtSceneInViewDirection(((float)deltaX),((float)deltaY));
1639 } else if (fShiftKeyPress) {
1640 unsigned int sizeWin;
1641 sizeWin = getWinWidth();
1642 if (getWinHeight() < getWinWidth()) {
1643 sizeWin = getWinHeight();
1644 }
1645
1646 // L.Garnier : 08/2010 100 is the good value, but don't ask me why !
1647 float factor = ((float)100/(float)sizeWin) ;
1648 moveScene(-(float)deltaX*factor,-(float)deltaY*factor,0,false);
1649 } else if (fControlKeyPress) {
1650 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+((float)deltaY)));
1651 }
1652 }
1653 } else if (fMouseAction == STYLE2) { // move
1654 if (mButtons & Qt::LeftButton) {
1655 moveScene(-deltaX,-deltaY,0,true);
1656 }
1657 }
1658
1659 fLastEventTime->start();
1660}
1661
1662
1663/**
1664 Move the scene of dx, dy, dz values.
1665 @param dx delta mouse x position
1666 @param dy delta mouse y position
1667 @param mouseMove : true if even comes from a mouse move, false if even comes from key action
1668*/
1669
1670void G4OpenGLQtViewer::moveScene(float dx,float dy, float dz,bool mouseMove)
1671{
1672 if (fHoldMoveEvent)
1673 return;
1674 fHoldMoveEvent = true;
1675
1676 G4double coefTrans = 0;
1677 GLdouble coefDepth = 0;
1678 if(mouseMove) {
1679 coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinWidth());
1680 if (getWinHeight() <getWinWidth()) {
1681 coefTrans = ((G4double)getSceneNearWidth())/((G4double)getWinHeight());
1682 }
1683 } else {
1684 coefTrans = getSceneNearWidth()*fDeltaSceneTranslation;
1685 coefDepth = getSceneDepth()*fDeltaDepth;
1686 }
1687 fVP.IncrementPan(-dx*coefTrans,dy*coefTrans,dz*coefDepth);
1688 emit moveX(-static_cast<int>(dx*coefTrans));
1689 emit moveY(static_cast<int>(dy*coefTrans));
1690 emit moveZ(static_cast<int>(dz*coefTrans));
1691
1692 updateQWidget();
1693 if (fAutoMove)
1694 ((QApplication*)G4Qt::getInstance ())->processEvents();
1695
1696 fHoldMoveEvent = false;
1697}
1698
1699
1700/**
1701 @param dx delta mouse x position
1702 @param dy delta mouse y position
1703*/
1704
1705void G4OpenGLQtViewer::rotateQtScene(float dx, float dy)
1706{
1707 if (fHoldRotateEvent)
1708 return;
1709 fHoldRotateEvent = true;
1710
1711 if( dx != 0) {
1712 rotateScene(dx,0,fDeltaRotation);
1713 emit rotateTheta(static_cast<int>(dx));
1714 }
1715 if( dy != 0) {
1716 rotateScene(0,dy,fDeltaRotation);
1717 emit rotatePhi(static_cast<int>(dy));
1718 }
1719 updateQWidget();
1720
1721 fHoldRotateEvent = false;
1722}
1723
1724/**
1725 @param dx delta mouse x position
1726 @param dy delta mouse y position
1727*/
1728
1729void G4OpenGLQtViewer::rotateQtSceneInViewDirection(float dx, float dy)
1730{
1731 if (fHoldRotateEvent)
1732 return;
1733 fHoldRotateEvent = true;
1734
1735 fXRot +=dx;
1736 fYRot +=dy;
1737
1738 rotateSceneInViewDirection(dx,dy,fDeltaRotation/100);
1739
1740 emit rotateTheta(static_cast<int>(dx));
1741 emit rotatePhi(static_cast<int>(dy));
1742 updateQWidget();
1743
1744 fHoldRotateEvent = false;
1745}
1746
1747/**
1748 @param dx delta mouse x position
1749 @param dy delta mouse y position
1750*/
1751
1752void G4OpenGLQtViewer::rotateQtCamera(float dx, float dy)
1753{
1754 if (fHoldRotateEvent)
1755 return;
1756 fHoldRotateEvent = true;
1757
1758 rotateScene(dx,dy,fDeltaRotation);
1759 emit rotateTheta(static_cast<int>(dx));
1760 emit rotatePhi(static_cast<int>(dy));
1761 updateQWidget();
1762
1763 fHoldRotateEvent = false;
1764}
1765
1766/**
1767 @param dx delta mouse x position
1768 @param dy delta mouse y position
1769*/
1770
1771void G4OpenGLQtViewer::rotateQtCameraInViewDirection(float dx, float dy)
1772{
1773 if (fHoldRotateEvent)
1774 return;
1775 fHoldRotateEvent = true;
1776
1777 fVP.SetUpVector(G4Vector3D(0.0, 1.0, 0.0));
1778 fVP.SetViewAndLights (G4Vector3D(0.0, 0.0, 1.0));
1779
1780
1781 fXRot +=dx;
1782 fYRot +=dy;
1783
1784 rotateSceneInViewDirection(fXRot,fYRot,fDeltaRotation/100);
1785
1786 emit rotateTheta(static_cast<int>(dx));
1787 emit rotatePhi(static_cast<int>(dy));
1788 updateQWidget();
1789
1790 fHoldRotateEvent = false;
1791}
1792
1793
1794
1795
1796
1797/** This is the benning of a rescale function. It does nothing for the moment
1798 @param aWidth : new width
1799 @param aHeight : new height
1800*/
1801void G4OpenGLQtViewer::rescaleImage(
1802 int /* aWidth */
1803,int /* aHeight */
1804){
1805 // GLfloat* feedback_buffer;
1806 // GLint returned;
1807 // FILE* file;
1808
1809// feedback_buffer = new GLfloat[size];
1810// glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1811// glRenderMode (GL_FEEDBACK);
1812
1813// DrawView();
1814// returned = glRenderMode (GL_RENDER);
1815
1816}
1817
1818
1819
1820/**
1821 Generate Postscript or PDF form image
1822 @param aFilename : name of file
1823 @param aInColor : numbers of colors : 1->BW 2->RGB
1824 @param aImage : Image to print
1825*/
1826bool G4OpenGLQtViewer::printPDF (
1827 const std::string aFilename
1828,int aInColor
1829,QImage aImage
1830)
1831{
1832
1833#if QT_VERSION < 0x040000
1834#if defined(Q_WS_MAC) || defined(Q_WS_X11)
1835 QPrinter printer;
1836 // printer.setPageSize(pageSize);
1837 if (aInColor == 1) {
1838 printer.setColorMode(QPrinter::GrayScale);
1839 } else {
1840 printer.setColorMode(QPrinter::Color);
1841 }
1842
1843 /* FIXME : I don't know which format it will save...
1844 if (aFilename.endsWith(".ps")) {
1845 printer.setOutputFormat(QPrinter::PostScriptFormat);
1846 } else {
1847 printer.setOutputFormat(QPrinter::PdfFormat);
1848 }
1849 */
1850 printer.setOutputFileName(QString(aFilename.c_str()));
1851 // printer.setFullPage ( true);
1852 QPainter paint(&printer);
1853 paint.drawImage (0,0,aImage );
1854 paint.end();
1855#else
1856 G4cerr << "This fonction is only supported on Mac OsX or X11 with Qt3. Full platform supported with Qt4" << G4endl;
1857 // FIXME
1858 // L.Garnier 6 May 2009 : Only to fix compilation warnings
1859 if (aFilename.empty()) {
1860 aInColor = 0;
1861 aImage = 0;
1862 }
1863 // END_OF FIXME
1864#endif
1865#else
1866 QPrinter printer;
1867 // printer.setPageSize(pageSize);
1868
1869 // FIXME : L. Garnier 4/12/07
1870 // This is not working, it does nothing. Image is staying in color mode
1871 // So I have desactivate the B/W button in GUI
1872 if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1873#if QT_VERSION < 0x040000
1874 aImage = aImage.convertDepth(1,Qt::MonoOnly);
1875#else
1876 aImage = aImage.convertToFormat ( aImage.format(), Qt::MonoOnly);
1877#endif
1878 }
1879
1880
1881 if (aFilename.substr(aFilename.size()-3) == ".ps") {
1882#if QT_VERSION > 0x040200
1883 printer.setOutputFormat(QPrinter::PostScriptFormat);
1884#endif
1885 } else {
1886#if QT_VERSION > 0x040100
1887 printer.setOutputFormat(QPrinter::PdfFormat);
1888#endif
1889 }
1890#if QT_VERSION > 0x040100
1891 printer.setOutputFileName(QString(aFilename.c_str()));
1892#endif
1893 // printer.setFullPage ( true);
1894 QPainter paint(&printer);
1895 paint.drawImage (0,0,aImage);
1896 paint.end();
1897#endif
1898 return true;
1899}
1900
1901
1902void G4OpenGLQtViewer::G4wheelEvent (QWheelEvent * event)
1903{
1904 fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.GetZoomFactor()*(event->delta())/1200));
1905 updateQWidget();
1906}
1907
1908
1909 void G4OpenGLQtViewer::G4keyPressEvent (QKeyEvent * event)
1910{
1911 if (fHoldKeyEvent)
1912 return;
1913
1914 fHoldKeyEvent = true;
1915
1916
1917 // with no modifiers
1918#if QT_VERSION < 0x040000
1919 updateKeyModifierState(event->state());
1920 if (fNoKeyPress) {
1921#else
1922 updateKeyModifierState(event->modifiers());
1923 if ((fNoKeyPress) || (event->modifiers() == Qt::KeypadModifier )) {
1924#endif
1925 if (event->key() == Qt::Key_Down) { // go down
1926 moveScene(0,1,0,false);
1927 }
1928 else if (event->key() == Qt::Key_Up) { // go up
1929 moveScene(0,-1,0,false);
1930 }
1931 if (event->key() == Qt::Key_Left) { // go left
1932 moveScene(-1,0,0,false);
1933 }
1934 else if (event->key() == Qt::Key_Right) { // go right
1935 moveScene(1,0,0,false);
1936 }
1937 if (event->key() == Qt::Key_Minus) { // go backward
1938 moveScene(0,0,1,false);
1939 }
1940 else if (event->key() == Qt::Key_Plus) { // go forward
1941 moveScene(0,0,-1,false);
1942 }
1943
1944 // escaped from full screen
1945 if (event->key() == Qt::Key_Escape) {
1946#if QT_VERSION >= 0x030200
1947 toggleFullScreen(false);
1948#endif
1949 }
1950 }
1951 // several case here : If return is pressed, in every case -> display the movie parameters dialog
1952 // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
1953 // If encoder not found-> does nothing.Only display a message in status box
1954 // If all ok-> generate parameter file
1955 // If ok -> put encoder button enabled
1956
1957 if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)){ // end of video
1958 stopVideo();
1959 }
1960 if (event->key() == Qt::Key_Space){ // start/pause of video
1961 startPauseVideo();
1962 }
1963
1964 // H : Return Home view
1965 if (event->key() == Qt::Key_H){ // go Home
1966 fDeltaRotation = 1;
1967 fDeltaSceneTranslation = 0.01;
1968 fDeltaDepth = 0.01;
1969 fDeltaZoom = 0.05;
1970 fDeltaMove = 0.05;
1971
1972 fVP.SetZoomFactor(1.);
1973 fVP.SetUpVector(G4Vector3D (0., 1., 0.));
1974 fVP.SetViewAndLights (G4Vector3D (0., 0., 1.));
1975
1976 updateQWidget();
1977 }
1978
1979 // Shift Modifier
1980 if (fShiftKeyPress) {
1981 if (event->key() == Qt::Key_Down) { // rotate phi
1982 rotateQtScene(0,-fDeltaRotation);
1983 }
1984 else if (event->key() == Qt::Key_Up) { // rotate phi
1985 rotateQtScene(0,fDeltaRotation);
1986 }
1987 if (event->key() == Qt::Key_Left) { // rotate theta
1988 rotateQtScene(fDeltaRotation,0);
1989 }
1990 else if (event->key() == Qt::Key_Right) { // rotate theta
1991 rotateQtScene(-fDeltaRotation,0);
1992 }
1993
1994 // Alt Modifier
1995 }
1996 if ((fAltKeyPress)) {
1997 if (event->key() == Qt::Key_Down) { // rotate phi
1998 rotateQtSceneInViewDirection(0,-fDeltaRotation);
1999 }
2000 else if (event->key() == Qt::Key_Up) { // rotate phi
2001 rotateQtSceneInViewDirection(0,fDeltaRotation);
2002 }
2003 if (event->key() == Qt::Key_Left) { // rotate theta
2004 rotateQtSceneInViewDirection(fDeltaRotation,0);
2005 }
2006 else if (event->key() == Qt::Key_Right) { // rotate theta
2007 rotateQtSceneInViewDirection(-fDeltaRotation,0);
2008 }
2009
2010 // Rotatio +/-
2011 if (event->key() == Qt::Key_Plus) {
2012 fDeltaRotation = fDeltaRotation/0.7;
2013 G4cout << "Auto-rotation set to : " << fDeltaRotation << G4endl;
2014 }
2015 else if (event->key() == Qt::Key_Minus) {
2016 fDeltaRotation = fDeltaRotation*0.7;
2017 G4cout << "Auto-rotation set to : " << fDeltaRotation << G4endl;
2018 }
2019
2020 // Control Modifier OR Command on MAC
2021 }
2022 if ((fControlKeyPress)) {
2023 if (event->key() == Qt::Key_Plus) {
2024 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
2025 updateQWidget();
2026 }
2027 else if (event->key() == Qt::Key_Minus) {
2028 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
2029 updateQWidget();
2030 }
2031 }
2032
2033 fHoldKeyEvent = false;
2034}
2035
2036
2037#if QT_VERSION < 0x040000
2038void G4OpenGLQtViewer::updateKeyModifierState(Qt::ButtonState modifier) {
2039#else
2040void G4OpenGLQtViewer::updateKeyModifierState(Qt::KeyboardModifiers modifier) {
2041#endif
2042 // Check Qt Versions for META Keys
2043
2044 fNoKeyPress = true;
2045 fAltKeyPress = false;
2046 fShiftKeyPress = false;
2047 fControlKeyPress = false;
2048
2049#if QT_VERSION < 0x040000
2050 if (modifier & Qt::AltButton ) {
2051 fAltKeyPress = true;
2052 fNoKeyPress = false;
2053 }
2054 if (modifier & Qt::ShiftButton ) {
2055 fShiftKeyPress = true;
2056 fNoKeyPress = false;
2057 }
2058 if (modifier & Qt::ControlButton ) {
2059 fControlKeyPress = true;
2060 fNoKeyPress = false;
2061 }
2062#else
2063 if (modifier & Qt::AltModifier ) {
2064 fAltKeyPress = true;
2065 fNoKeyPress = false;
2066 }
2067 if (modifier & Qt::ShiftModifier ) {
2068 fShiftKeyPress = true;
2069 fNoKeyPress = false;
2070 }
2071 if (modifier & Qt::ControlModifier ) {
2072 fControlKeyPress = true;
2073 fNoKeyPress = false;
2074 }
2075#endif
2076}
2077
2078
2079/** Stop the video. Check all parameters and enable encoder button if all is ok.
2080*/
2081void G4OpenGLQtViewer::stopVideo() {
2082
2083 // if encoder parameter is wrong, display parameters dialog and return
2084 if (!fMovieParametersDialog) {
2085 showMovieParametersDialog();
2086 }
2087 setRecordingStatus(STOP);
2088
2089 if (fRecordFrameNumber >0) {
2090 // check parameters if they were modified (Re APPLY them...)
2091 if (!(fMovieParametersDialog->checkEncoderSwParameters())) {
2092 setRecordingStatus(BAD_ENCODER);
2093 } else if (!(fMovieParametersDialog->checkSaveFileNameParameters())) {
2094 setRecordingStatus(BAD_OUTPUT);
2095 }
2096 } else {
2097 resetRecording();
2098 setRecordingInfos("No frame to encode.");
2099 }
2100}
2101
2102/** Stop the video. Check all parameters and enable encoder button if all is ok.
2103*/
2104void G4OpenGLQtViewer::saveVideo() {
2105
2106 // if encoder parameter is wrong, display parameters dialog and return
2107 if (!fMovieParametersDialog) {
2108 showMovieParametersDialog();
2109 }
2110
2111 fMovieParametersDialog->checkEncoderSwParameters();
2112 fMovieParametersDialog->checkSaveFileNameParameters();
2113
2114 if (fRecordingStep == STOP) {
2115 setRecordingStatus(SAVE);
2116 generateMpegEncoderParameters();
2117 encodeVideo();
2118 }
2119}
2120
2121
2122/** Start/Pause the video..
2123*/
2124void G4OpenGLQtViewer::startPauseVideo() {
2125
2126 // first time, if temp parameter is wrong, display parameters dialog and return
2127
2128 if (( fRecordingStep == WAIT)) {
2129 if ( fRecordFrameNumber == 0) {
2130 if (getTempFolderPath() == "") { // BAD_OUTPUT
2131 showMovieParametersDialog();
2132 setRecordingInfos("You should specified the temp folder in order to make movie");
2133 return;
2134 } else {
2135 // remove temp folder if it was create
2136 QString tmp = removeTempFolder();
2137 if (tmp !="") {
2138 setRecordingInfos(tmp);
2139 return;
2140 }
2141 tmp = createTempFolder();
2142 if (tmp != "") {
2143 setRecordingInfos("Can't create temp folder."+tmp);
2144 return;
2145 }
2146 }
2147 }
2148 }
2149 if ((fRecordingStep == WAIT)) {
2150 setRecordingStatus(START);
2151 } else if (fRecordingStep == START) {
2152 setRecordingStatus(PAUSE);
2153 } else if (fRecordingStep == PAUSE) {
2154 setRecordingStatus(CONTINUE);
2155 } else if (fRecordingStep == CONTINUE) {
2156 setRecordingStatus(PAUSE);
2157 }
2158}
2159
2160void G4OpenGLQtViewer::setRecordingStatus(RECORDING_STEP step) {
2161
2162 fRecordingStep = step;
2163 displayRecordingStatus();
2164}
2165
2166
2167void G4OpenGLQtViewer::displayRecordingStatus() {
2168
2169 QString txtStatus = "";
2170 if (fRecordingStep == WAIT) {
2171 txtStatus = "Waiting to start...";
2172 fRecordFrameNumber = 0; // reset the frame number
2173 } else if (fRecordingStep == START) {
2174 txtStatus = "Start Recording...";
2175 } else if (fRecordingStep == PAUSE) {
2176 txtStatus = "Pause Recording...";
2177 } else if (fRecordingStep == CONTINUE) {
2178 txtStatus = "Continue Recording...";
2179 } else if (fRecordingStep == STOP) {
2180 txtStatus = "Stop Recording...";
2181 } else if (fRecordingStep == READY_TO_ENCODE) {
2182 txtStatus = "Ready to Encode...";
2183 } else if (fRecordingStep == ENCODING) {
2184 txtStatus = "Encoding...";
2185 } else if (fRecordingStep == FAILED) {
2186 txtStatus = "Failed to encode...";
2187 } else if ((fRecordingStep == BAD_ENCODER)
2188 || (fRecordingStep == BAD_OUTPUT)
2189 || (fRecordingStep == BAD_TMP)) {
2190 txtStatus = "Correct above errors first";
2191 } else if (fRecordingStep == SUCCESS) {
2192 txtStatus = "File encoded successfully";
2193 } else {
2194 }
2195
2196 if (fMovieParametersDialog) {
2197 fMovieParametersDialog->setRecordingStatus(txtStatus);
2198 } else {
2199#if QT_VERSION < 0x040000
2200 G4cout << txtStatus.ascii() << G4endl;
2201#else
2202 G4cout << txtStatus.toStdString().c_str() << G4endl;
2203#endif
2204 }
2205 setRecordingInfos("");
2206}
2207
2208
2209void G4OpenGLQtViewer::setRecordingInfos(QString txt) {
2210 if (fMovieParametersDialog) {
2211 fMovieParametersDialog->setRecordingInfos(txt);
2212 } else {
2213#if QT_VERSION < 0x040000
2214 G4cout << txt.ascii() << G4endl;
2215#else
2216 G4cout << txt.toStdString().c_str() << G4endl;
2217#endif
2218 }
2219}
2220
2221/** Init the movie parameters. Temp dir and encoder path
2222*/
2223void G4OpenGLQtViewer::initMovieParameters() {
2224 //init encoder
2225
2226 //look for encoderPath
2227 fProcess = new QProcess();
2228
2229#if QT_VERSION < 0x040000
2230 QObject ::connect(fProcess,SIGNAL(processExited ()),
2231 this,SLOT(processLookForFinished()));
2232 fProcess->setCommunication(QProcess::DupStderr);
2233 fProcess->setArguments(QStringList("which mpeg_encode"));
2234 fProcess->start();
2235#else
2236 QObject ::connect(fProcess,SIGNAL(finished ( int)),
2237 this,SLOT(processLookForFinished()));
2238 fProcess->setReadChannelMode(QProcess::MergedChannels);
2239 fProcess->start ("which mpeg_encode");
2240#endif
2241
2242}
2243
2244/** @return encoder path or "" if it does not exist
2245 */
2246QString G4OpenGLQtViewer::getEncoderPath() {
2247 return fEncoderPath;
2248}
2249
2250
2251/**
2252 * set the new encoder path
2253 * @return "" if correct. The error otherwise
2254*/
2255QString G4OpenGLQtViewer::setEncoderPath(QString path) {
2256 if (path == "") {
2257 return "File does not exist";
2258 }
2259
2260#if QT_VERSION < 0x040000
2261 path = QDir::cleanDirPath(path);
2262#else
2263 path = QDir::cleanPath(path);
2264#endif
2265 QFileInfo *f = new QFileInfo(path);
2266 if (!f->exists()) {
2267 return "File does not exist";
2268 } else if (f->isDir()) {
2269 return "This is a directory";
2270 } else if (!f->isExecutable()) {
2271 return "File exist but is not executable";
2272 } else if (!f->isFile()) {
2273 return "This is not a file";
2274 }
2275 fEncoderPath = path;
2276
2277 if ((fRecordingStep == BAD_ENCODER)) {
2278 setRecordingStatus(STOP);
2279 }
2280 return "";
2281}
2282
2283
2284bool G4OpenGLQtViewer::isRecording(){
2285 if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
2286 return true;
2287 }
2288 return false;
2289}
2290
2291bool G4OpenGLQtViewer::isPaused(){
2292 if (fRecordingStep == PAUSE) {
2293 return true;
2294 }
2295 return false;
2296}
2297
2298bool G4OpenGLQtViewer::isEncoding(){
2299 if (fRecordingStep == ENCODING) {
2300 return true;
2301 }
2302 return false;
2303}
2304
2305bool G4OpenGLQtViewer::isWaiting(){
2306 if (fRecordingStep == WAIT) {
2307 return true;
2308 }
2309 return false;
2310}
2311
2312bool G4OpenGLQtViewer::isStopped(){
2313 if (fRecordingStep == STOP) {
2314 return true;
2315 }
2316 return false;
2317}
2318
2319bool G4OpenGLQtViewer::isFailed(){
2320 if (fRecordingStep == FAILED) {
2321 return true;
2322 }
2323 return false;
2324}
2325
2326bool G4OpenGLQtViewer::isSuccess(){
2327 if (fRecordingStep == SUCCESS) {
2328 return true;
2329 }
2330 return false;
2331}
2332
2333bool G4OpenGLQtViewer::isBadEncoder(){
2334 if (fRecordingStep == BAD_ENCODER) {
2335 return true;
2336 }
2337 return false;
2338}
2339bool G4OpenGLQtViewer::isBadTmp(){
2340 if (fRecordingStep == BAD_TMP) {
2341 return true;
2342 }
2343 return false;
2344}
2345bool G4OpenGLQtViewer::isBadOutput(){
2346 if (fRecordingStep == BAD_OUTPUT) {
2347 return true;
2348 }
2349 return false;
2350}
2351
2352void G4OpenGLQtViewer::setBadEncoder(){
2353 fRecordingStep = BAD_ENCODER;
2354 displayRecordingStatus();
2355}
2356void G4OpenGLQtViewer::setBadTmp(){
2357 fRecordingStep = BAD_TMP;
2358 displayRecordingStatus();
2359}
2360void G4OpenGLQtViewer::setBadOutput(){
2361 fRecordingStep = BAD_OUTPUT;
2362 displayRecordingStatus();
2363}
2364
2365void G4OpenGLQtViewer::setWaiting(){
2366 fRecordingStep = WAIT;
2367 displayRecordingStatus();
2368}
2369
2370
2371bool G4OpenGLQtViewer::isReadyToEncode(){
2372 if (fRecordingStep == READY_TO_ENCODE) {
2373 return true;
2374 }
2375 return false;
2376}
2377
2378void G4OpenGLQtViewer::resetRecording() {
2379 setRecordingStatus(WAIT);
2380}
2381
2382/**
2383 * set the temp folder path
2384 * @return "" if correct. The error otherwise
2385*/
2386QString G4OpenGLQtViewer::setTempFolderPath(QString path) {
2387
2388 if (path == "") {
2389 return "Path does not exist";
2390 }
2391#if QT_VERSION < 0x040000
2392 path = QDir::cleanDirPath(path);
2393#else
2394 path = QDir::cleanPath(path);
2395#endif
2396 QFileInfo *d = new QFileInfo(path);
2397 if (!d->exists()) {
2398 return "Path does not exist";
2399 } else if (!d->isDir()) {
2400 return "This is not a directory";
2401 } else if (!d->isReadable()) {
2402 return path +" is read protected";
2403 } else if (!d->isWritable()) {
2404 return path +" is write protected";
2405 }
2406
2407 if ((fRecordingStep == BAD_TMP)) {
2408 setRecordingStatus(WAIT);
2409 }
2410 fTempFolderPath = path;
2411 return "";
2412}
2413
2414/** @return the temp folder path or "" if it does not exist
2415 */
2416QString G4OpenGLQtViewer::getTempFolderPath() {
2417 return fTempFolderPath;
2418}
2419
2420/**
2421 * set the save file name path
2422 * @return "" if correct. The error otherwise
2423*/
2424QString G4OpenGLQtViewer::setSaveFileName(QString path) {
2425
2426 if (path == "") {
2427 return "Path does not exist";
2428 }
2429
2430 QFileInfo *file = new QFileInfo(path);
2431 QDir dir = file->dir();
2432#if QT_VERSION < 0x040000
2433 path = QDir::cleanDirPath(path);
2434#else
2435 path = QDir::cleanPath(path);
2436#endif
2437 if (file->exists()) {
2438 return "File already exist, please choose a new one";
2439 } else if (!dir.exists()) {
2440 return "Dir does not exist";
2441 } else if (!dir.isReadable()) {
2442 return path +" is read protected";
2443 }
2444
2445 if ((fRecordingStep == BAD_OUTPUT)) {
2446 setRecordingStatus(STOP);
2447 }
2448 fSaveFileName = path;
2449 return "";
2450}
2451
2452/** @return the save file path
2453 */
2454QString G4OpenGLQtViewer::getSaveFileName() {
2455 return fSaveFileName ;
2456}
2457
2458/** Create a Qt_temp folder in the temp folder given
2459* The temp folder will be like this /tmp/QtMovie_12-02-2008_12_12_58/
2460* @return "" if success. Error message if not.
2461*/
2462QString G4OpenGLQtViewer::createTempFolder() {
2463 fMovieTempFolderPath = "";
2464 //check
2465 QString tmp = setTempFolderPath(fTempFolderPath);
2466 if (tmp != "") {
2467 return tmp;
2468 }
2469#if QT_VERSION < 0x040000
2470 QString sep = QChar(QDir::separator());
2471#else
2472 QString sep = QString(QDir::separator());
2473#endif
2474 QString path = sep+"QtMovie_"+QDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+sep;
2475#if QT_VERSION < 0x040000
2476 QDir *d = new QDir(QDir::cleanDirPath(fTempFolderPath));
2477#else
2478 QDir *d = new QDir(QDir::cleanPath(fTempFolderPath));
2479#endif
2480 // check if it is already present
2481 if (d->exists(path)) {
2482 return "Folder "+path+" already exists.Please remove it first";
2483 }
2484 if (d->mkdir(fTempFolderPath+path)) {
2485 fMovieTempFolderPath = fTempFolderPath+path;
2486 return "";
2487 } else {
2488 return "Can't create "+fTempFolderPath+path;
2489 }
2490 return "-";
2491}
2492
2493/** Remove the Qt_temp folder in the temp folder
2494*/
2495QString G4OpenGLQtViewer::removeTempFolder() {
2496 // remove files in Qt_temp folder
2497 if (fMovieTempFolderPath == "") {
2498 return "";
2499 }
2500#if QT_VERSION < 0x040000
2501 QDir *d = new QDir(QDir::cleanDirPath(fMovieTempFolderPath));
2502#else
2503 QDir *d = new QDir(QDir::cleanPath(fMovieTempFolderPath));
2504#endif
2505 if (!d->exists()) {
2506 return ""; // already remove
2507 }
2508
2509 d->setFilter( QDir::Files );
2510 QStringList subDirList = d->entryList();
2511 int res = true;
2512 QString error = "";
2513 for (QStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
2514 const QString currentFile = *it;
2515 if (!d->remove(currentFile)) {
2516 res = false;
2517 QString file = fMovieTempFolderPath+currentFile;
2518 error +="Removing file failed : "+file;
2519 } else {
2520 }
2521 }
2522 if (res) {
2523 if (d->rmdir(fMovieTempFolderPath)) {
2524 fMovieTempFolderPath = "";
2525 return "";
2526 } else {
2527 return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
2528 }
2529
2530 }
2531 return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
2532}
2533
2534
2535
2536bool G4OpenGLQtViewer::hasPendingEvents () {
2537 return ((QApplication*)G4Qt::getInstance ())->hasPendingEvents ();
2538}
2539
2540bool G4OpenGLQtViewer::generateMpegEncoderParameters () {
2541
2542 // save the parameter file
2543 FILE* fp;
2544#if QT_VERSION < 0x040000
2545 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).ascii(), "w");
2546#else
2547 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).toStdString().c_str(), "w");
2548#endif
2549
2550 if (fp == NULL) {
2551 setRecordingInfos("Generation of parameter file failed");
2552 return false;
2553 }
2554
2555 fprintf (fp,"# parameter file template with lots of comments to assist you\n");
2556 fprintf (fp,"#\n");
2557 fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
2558 fprintf (fp,"# the copy\n");
2559 fprintf (fp,"#\n");
2560 fprintf (fp,"#\n");
2561 fprintf (fp,"# any line beginning with '#' is a comment\n");
2562 fprintf (fp,"#\n");
2563 fprintf (fp,"# no line should be longer than 255 characters\n");
2564 fprintf (fp,"#\n");
2565 fprintf (fp,"#\n");
2566 fprintf (fp,"# general format of each line is:\n");
2567 fprintf (fp,"# \n");
2568 fprintf (fp,"#\n");
2569 fprintf (fp,"# lines can generally be in any order\n");
2570 fprintf (fp,"#\n");
2571 fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
2572 fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
2573 fprintf (fp,"#\n");
2574 fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
2575 fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
2576 fprintf (fp,"# the INPUT parameter.\n");
2577 fprintf (fp,"#\n");
2578 fprintf (fp,"# MUST be in UPPER CASE\n");
2579 fprintf (fp,"#\n");
2580 fprintf (fp,"\n");
2581 fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
2582 fprintf (fp,"# for more info.\n");
2583 fprintf (fp,"\n");
2584 fprintf (fp,"PATTERN IBBPBBPBBPBBPBBP\n");
2585#if QT_VERSION < 0x040000
2586 fprintf (fp,"OUTPUT %s\n",getSaveFileName().ascii());
2587#else
2588 fprintf (fp,"OUTPUT %s\n",getSaveFileName().toStdString().c_str());
2589#endif
2590 fprintf (fp,"\n");
2591 fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
2592 fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
2593 fprintf (fp,"#\n");
2594 fprintf (fp,"# You must specify the type of the input files. The choices are:\n");
2595 fprintf (fp,"# YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
2596 fprintf (fp,"# (must be upper case)\n");
2597 fprintf (fp,"#\n");
2598 fprintf (fp,"BASE_FILE_FORMAT PPM\n");
2599 fprintf (fp,"\n");
2600 fprintf (fp,"#\n");
2601 fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
2602 fprintf (fp,"# YUV_SIZE widthxheight\n");
2603 fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
2604 fprintf (fp,"# on just one machine\n");
2605 fprintf (fp,"#\n");
2606 fprintf (fp,"YUV_SIZE 352x240\n");
2607 fprintf (fp,"\n");
2608 fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
2609 fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
2610 fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2611 fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
2612 fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
2613 fprintf (fp,"# to specify the file order.\n");
2614 fprintf (fp,"\n");
2615 fprintf (fp,"INPUT_FORMAT UCB\n");
2616 fprintf (fp,"\n");
2617 fprintf (fp,"# the conversion statement\n");
2618 fprintf (fp,"#\n");
2619 fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
2620 fprintf (fp,"#\n");
2621 fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
2622 fprintf (fp,"# INPUT_CONVERT giftoppm *\n");
2623 fprintf (fp,"#\n");
2624 fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2625 fprintf (fp,"# INPUT_CONVERT cat *.Y *.U *.V\n");
2626 fprintf (fp,"#\n");
2627 fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
2628 fprintf (fp,"# INPUT_CONVERT goto frame *; grabppm\n");
2629 fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2630 fprintf (fp,"#\n");
2631 fprintf (fp,"INPUT_CONVERT * \n");
2632 fprintf (fp,"\n");
2633 fprintf (fp,"# number of frames in a GOP.\n");
2634 fprintf (fp,"#\n");
2635 fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
2636 fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2637 fprintf (fp,"#\n");
2638 fprintf (fp,"# later, will add more flexible GOP signalling\n");
2639 fprintf (fp,"#\n");
2640 fprintf (fp,"GOP_SIZE 16\n");
2641 fprintf (fp,"\n");
2642 fprintf (fp,"# number of slices in a frame\n");
2643 fprintf (fp,"#\n");
2644 fprintf (fp,"# 1 is a good number. another possibility is the number of macroblock rows\n");
2645 fprintf (fp,"# (which is the height divided by 16)\n");
2646 fprintf (fp,"#\n");
2647 fprintf (fp,"SLICES_PER_FRAME 1\n");
2648 fprintf (fp,"\n");
2649 fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2650#if QT_VERSION < 0x040000
2651 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.ascii());
2652#else
2653 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.toStdString().c_str());
2654#endif
2655 fprintf (fp,"\n");
2656 fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2657 fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2658 fprintf (fp,"# way of numbering them. See the manual for more information.\n");
2659 fprintf (fp,"INPUT\n");
2660 fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2661 fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2662 fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2663 fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2664 fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2665 fprintf (fp,"# if you do, too bad!!!\n");
2666 fprintf (fp,"#\n");
2667 fprintf (fp,"#\n");
2668 fprintf (fp,"Test*.ppm [0-%d]\n",fRecordFrameNumber-1);
2669 fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2670 fprintf (fp,"# of files\n");
2671 fprintf (fp,"END_INPUT\n");
2672 fprintf (fp,"\n");
2673 fprintf (fp,"\n");
2674 fprintf (fp,"\n");
2675 fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2676 fprintf (fp,"\n");
2677 fprintf (fp,"# FULL or HALF -- must be upper case\n");
2678 fprintf (fp,"# Should be FULL for computer generated images\n");
2679 fprintf (fp,"PIXEL FULL\n");
2680 fprintf (fp,"\n");
2681 fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2682 fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2683 fprintf (fp,"RANGE 10\n");
2684 fprintf (fp,"\n");
2685 fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2686 fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2687 fprintf (fp,"\n");
2688 fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2689 fprintf (fp,"PSEARCH_ALG LOGARITHMIC\n");
2690 fprintf (fp,"\n");
2691 fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2692 fprintf (fp,"#\n");
2693 fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2694 fprintf (fp,"#\n");
2695 fprintf (fp,"BSEARCH_ALG SIMPLE\n");
2696 fprintf (fp,"\n");
2697 fprintf (fp,"#\n");
2698 fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2699 fprintf (fp,"# (values must be between 1 and 31)\n");
2700 fprintf (fp,"# These are the Qscale values for the entire frame in variable bit-rate\n");
2701 fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2702 fprintf (fp,"#\n");
2703 fprintf (fp,"\n");
2704 fprintf (fp,"# Qscale (Quantization scale) affects quality and compression,\n");
2705 fprintf (fp,"# but has very little effect on speed.\n");
2706 fprintf (fp,"\n");
2707 fprintf (fp,"IQSCALE 4\n");
2708 fprintf (fp,"PQSCALE 5\n");
2709 fprintf (fp,"BQSCALE 12\n");
2710 fprintf (fp,"\n");
2711 fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2712 fprintf (fp,"REFERENCE_FRAME ORIGINAL\n");
2713 fprintf (fp,"\n");
2714 fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2715 fprintf (fp,"\n");
2716 fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2717 fprintf (fp,"#BIT_RATE 1000000\n");
2718 fprintf (fp,"\n");
2719 fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2720 fprintf (fp,"BUFFER_SIZE 327680\n");
2721 fprintf (fp,"\n");
2722 fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2723 fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2724 fprintf (fp,"FRAME_RATE 30\n");
2725 fprintf (fp,"\n");
2726 fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2727 fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.\n");
2728 fprintf (fp,"\n");
2729 fprintf (fp,"\n");
2730 fclose (fp);
2731
2732 setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
2733 setRecordingStatus(READY_TO_ENCODE);
2734 return true;
2735}
2736
2737void G4OpenGLQtViewer::encodeVideo()
2738{
2739 if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
2740 setRecordingStatus(ENCODING);
2741
2742#if QT_VERSION < 0x040000
2743 QStringList args = QStringList(fEncoderPath);
2744 args.push_back(fMovieTempFolderPath+fParameterFileName);
2745 fProcess = new QProcess(args);
2746 QObject ::connect(fProcess,SIGNAL(processExited ()),
2747 this,SLOT(processEncodeFinished()));
2748 QObject ::connect(fProcess,SIGNAL(readyReadStdout ()),
2749 this,SLOT(processEncodeStdout()));
2750 fProcess->setCommunication(QProcess::DupStderr);
2751 fProcess->launch("");
2752#else
2753 fProcess = new QProcess();
2754#if QT_VERSION > 0x040100
2755 QObject ::connect(fProcess,SIGNAL(finished ( int,QProcess::ExitStatus)),
2756 this,SLOT(processEncodeFinished()));
2757 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2758 this,SLOT(processEncodeStdout()));
2759#else
2760 QObject ::connect(fProcess,SIGNAL(finished ( int)),
2761 this,SLOT(processEncodeFinished()));
2762 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2763 this,SLOT(processEncodeStdout()));
2764#endif
2765 fProcess->setReadChannelMode(QProcess::MergedChannels);
2766 fProcess->start (fEncoderPath, QStringList(fMovieTempFolderPath+fParameterFileName));
2767#endif
2768 }
2769}
2770
2771
2772// FIXME : does not work on Qt3
2773void G4OpenGLQtViewer::processEncodeStdout()
2774{
2775#if QT_VERSION > 0x040000
2776 QString tmp = fProcess->readAllStandardOutput ().data();
2777 int start = tmp.lastIndexOf("ESTIMATED TIME");
2778 tmp = tmp.mid(start,tmp.indexOf("\n",start)-start);
2779#else
2780 QString tmp = fProcess->readStdout ().data();
2781 int start = tmp.findRev("ESTIMATED TIME");
2782 tmp = tmp.mid(start,tmp.find("\n",start)-start);
2783#endif
2784 setRecordingInfos(tmp);
2785}
2786
2787
2788void G4OpenGLQtViewer::processEncodeFinished()
2789{
2790
2791 QString txt = "";
2792 txt = getProcessErrorMsg();
2793 if (txt == "") {
2794 setRecordingStatus(SUCCESS);
2795 } else {
2796 setRecordingStatus(FAILED);
2797 }
2798 // setRecordingInfos(txt+removeTempFolder());
2799}
2800
2801
2802void G4OpenGLQtViewer::processLookForFinished()
2803 {
2804
2805 QString txt = getProcessErrorMsg();
2806 if (txt != "") {
2807 fEncoderPath = "";
2808 } else {
2809#if QT_VERSION > 0x040000
2810 fEncoderPath = QString(fProcess->readAllStandardOutput ().data()).trimmed();
2811#else
2812 fEncoderPath = QString(fProcess->readStdout ().data()).simplifyWhiteSpace();
2813#endif
2814 // if not found, return "not found"
2815 if (fEncoderPath.contains(" ")) {
2816 fEncoderPath = "";
2817 } else if (!fEncoderPath.contains("mpeg_encode")) {
2818 fEncoderPath = "";
2819 }
2820 setEncoderPath(fEncoderPath);
2821 }
2822 // init temp folder
2823#if QT_VERSION > 0x040000
2824 setTempFolderPath(QDir::temp ().absolutePath ());
2825#else
2826 // Let's have a try
2827 setTempFolderPath("/tmp/");
2828#endif
2829}
2830
2831
2832QString G4OpenGLQtViewer::getProcessErrorMsg()
2833{
2834 QString txt = "";
2835#if QT_VERSION < 0x040000
2836 if (!fProcess->normalExit ()) {
2837 txt = "Exist status "+ fProcess->exitStatus ();
2838 }
2839#else
2840 if (fProcess->exitCode() != 0) {
2841 switch (fProcess->error()) {
2842 case QProcess::FailedToStart:
2843 txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2844 break;
2845 case QProcess::Crashed:
2846 txt = "The process crashed some time after starting successfully.\n";
2847 break;
2848 case QProcess::Timedout:
2849 txt = "The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.\n";
2850 break;
2851 case QProcess::WriteError:
2852 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";
2853 break;
2854 case QProcess::ReadError:
2855 txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2856 break;
2857 case QProcess::UnknownError:
2858 txt = "An unknown error occurred. This is the default return value of error().\n";
2859 break;
2860 }
2861 }
2862#endif
2863 return txt;
2864}
2865
2866
2867
2868
2869QWidget *G4OpenGLQtViewer::getParentWidget()
2870{
2871 // launch Qt if not
2872 G4Qt* interactorManager = G4Qt::getInstance ();
2873 // G4UImanager* UI =
2874 G4UImanager::GetUIpointer();
2875
2876 bool found = false;
2877
2878 // create window
2879 if (((QApplication*)interactorManager->GetMainInteractor())) {
2880 // look for the main window
2881#if QT_VERSION < 0x040000
2882 // theses lines does nothing exept this one "GLWindow = new QDialog(0..."
2883 // but if I comment them, it doesn't work...
2884 QWidgetList *list = QApplication::allWidgets();
2885 QWidgetListIt it( *list ); // iterate over the widgets
2886 QWidget * widget;
2887 while ( (widget=it.current()) != 0 ) { // for each widget...
2888 ++it;
2889 if ((found== false) && (widget->inherits("QMainWindow"))) {
2890 fGLWindow = new QDialog(0,0,FALSE,Qt::WStyle_Title | Qt::WStyle_SysMenu | Qt::WStyle_MinMax );
2891 found = true;
2892 }
2893 }
2894 delete list; // delete the list, not the widgets
2895#else
2896 foreach (QWidget *widget, QApplication::allWidgets()) {
2897 if ((found== false) && (widget->inherits("QMainWindow"))) {
2898 fGLWindow = new QDialog(widget,Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
2899 found = true;
2900 }
2901 }
2902#endif
2903
2904 if (found==false) {
2905#ifdef G4DEBUG_VIS_OGL
2906 printf("G4OpenGLQtViewer::CreateMainWindow case Qapp exist, but not found\n");
2907#endif
2908 fGLWindow = new QDialog();
2909 }
2910 } else {
2911#ifdef G4DEBUG_VIS_OGL
2912 printf("G4OpenGLQtViewer::CreateMainWindow case Qapp exist\n");
2913#endif
2914 fGLWindow = new QDialog();
2915#ifdef G4DEBUG_VIS_OGL
2916 printf("G4OpenGLQtViewer::GetParentWidget fGLWindow\n");
2917#endif
2918 }
2919 if (found) {
2920 return fGLWindow;
2921 } else {
2922 return NULL;
2923 }
2924}
2925
2926/*
2927
2928void MultiLayer::exportToSVG(const QString& fname)
2929{
2930 QPicture picture;
2931 QPainter p(&picture);
2932 for (int i=0;i<(int)graphsList->count();i++)
2933 {
2934 Graph *gr=(Graph *)graphsList->at(i);
2935 Plot *myPlot= (Plot *)gr->plotWidget();
2936
2937 QPoint pos=gr->pos();
2938
2939 int width=int(myPlot->frameGeometry().width());
2940 int height=int(myPlot->frameGeometry().height());
2941
2942 myPlot->print(&p, QRect(pos,QSize(width,height)));
2943 }
2944
2945 p.end();
2946 picture.save(fname, "svg");
2947}
2948*/
2949#endif
Note: See TracBrowser for help on using the repository browser.