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

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

shorcuts better implementation, Mouse move volume follow mouse position

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