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

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

change debug definition, and tag for files

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