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

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

for aspect radio. Ok for Qt, Xm, but not X. Debug mode

  • Property svn:mime-type set to text/cpp
File size: 85.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.31 2009/01/13 09:47:05 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
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
151 printf("G4OpenGLQtViewer::CreateMainWindow case Qapp exist, but not found\n");
152#endif
153 GLWindow = new QDialog();
154 }
155 } else {
156#ifdef G4DEBUG
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 unsigned 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
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
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// glViewport (0, 0, aWidth, aHeight);
1648// DrawView();
1649// returned = glRenderMode (GL_RENDER);
1650
1651}
1652
1653/**
1654 Generate Vectorial Encapsulated Postscript form image
1655 @param aFilename : name of file
1656 @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1657 @param aImage : Image to print
1658*/
1659bool G4OpenGLQtViewer::generateVectorEPS (
1660 QString aFilename
1661,int aWidth
1662,int aHeight
1663,QImage aImage
1664)
1665{
1666 // Print vectored PostScript
1667
1668 G4int size = 5000000;
1669
1670 GLfloat* feedback_buffer;
1671 GLint returned;
1672 FILE* file;
1673
1674 feedback_buffer = new GLfloat[size];
1675 glFeedbackBuffer (size, GL_3D_COLOR, feedback_buffer);
1676 glRenderMode (GL_FEEDBACK);
1677
1678 int side = aWidth;
1679 if (aHeight < aWidth) side = aHeight;
1680 glViewport((aWidth - side) / 2, (aHeight - side) / 2, side, side);
1681 DrawView();
1682
1683 returned = glRenderMode (GL_RENDER);
1684
1685
1686#if QT_VERSION < 0x040000
1687 file = fopen (aFilename.ascii(), "w");
1688#else
1689 file = fopen (aFilename.toStdString().c_str(), "w");
1690#endif
1691 if (file) {
1692 spewWireframeEPS (file, returned, feedback_buffer, "rendereps");
1693 } else {
1694#if QT_VERSION < 0x040000
1695 G4cerr << "Could not open "<< aFilename.ascii() << G4endl;
1696#else
1697 G4cerr << "Could not open "<< aFilename.toStdString().c_str() << G4endl;
1698#endif
1699 }
1700
1701 delete[] feedback_buffer;
1702
1703 return true;
1704}
1705
1706/**
1707 Generate Encapsulated Postscript form image
1708 @param aFilename : name of file
1709 @param aInColor : numbers of colors : 1->BW 2->RGB 3->RGB+Alpha
1710 @param aImage : Image to print
1711*/
1712bool G4OpenGLQtViewer::generateEPS (
1713 QString aFilename
1714,int aInColor
1715,QImage aImage
1716)
1717{
1718 // FIXME
1719
1720 FILE* fp;
1721
1722 if (aImage.bits () == NULL)
1723 return false;
1724
1725#if QT_VERSION < 0x040000
1726 fp = fopen (aFilename.ascii(), "w");
1727#else
1728 fp = fopen (aFilename.toStdString().c_str(), "w");
1729#endif
1730 if (fp == NULL) {
1731 return false;
1732 }
1733
1734 fprintf (fp, "%%!PS-Adobe-2.0 EPSF-1.2\n");
1735#if QT_VERSION < 0x040000
1736 fprintf (fp, "%%%%Title: %s\n", aFilename.ascii());
1737#else
1738 fprintf (fp, "%%%%Title: %s\n", aFilename.toStdString().c_str());
1739#endif
1740 fprintf (fp, "%%%%Creator: OpenGL pixmap render output\n");
1741 fprintf (fp, "%%%%BoundingBox: 0 0 %d %d\n", aImage.width(), aImage.height());
1742 fprintf (fp, "%%%%EndComments\n");
1743 fprintf (fp, "gsave\n");
1744 fprintf (fp, "/bwproc {\n");
1745 fprintf (fp, " rgbproc\n");
1746 fprintf (fp, " dup length 3 idiv string 0 3 0 \n");
1747 fprintf (fp, " 5 -1 roll {\n");
1748 fprintf (fp, " add 2 1 roll 1 sub dup 0 eq\n");
1749 fprintf (fp, " { pop 3 idiv 3 -1 roll dup 4 -1 roll dup\n");
1750 fprintf (fp, " 3 1 roll 5 -1 roll } put 1 add 3 0 \n");
1751 fprintf (fp, " { 2 1 roll } ifelse\n");
1752 fprintf (fp, " }forall\n");
1753 fprintf (fp, " pop pop pop\n");
1754 fprintf (fp, "} def\n");
1755 fprintf (fp, "systemdict /colorimage known not {\n");
1756 fprintf (fp, " /colorimage {\n");
1757 fprintf (fp, " pop\n");
1758 fprintf (fp, " pop\n");
1759 fprintf (fp, " /rgbproc exch def\n");
1760 fprintf (fp, " { bwproc } image\n");
1761 fprintf (fp, " } def\n");
1762 fprintf (fp, "} if\n");
1763 fprintf (fp, "/picstr %d string def\n", aImage.width() * aInColor);
1764 fprintf (fp, "%d %d scale\n", aImage.width(), aImage.height());
1765 fprintf (fp, "%d %d %d\n", aImage.width(), aImage.height(), 8);
1766 fprintf (fp, "[%d 0 0 %d 0 0]\n", aImage.width(), aImage.height());
1767 fprintf (fp, "{currentfile picstr readhexstring pop}\n");
1768 fprintf (fp, "false %d\n", aInColor);
1769 fprintf (fp, "colorimage\n");
1770
1771
1772 int width = aImage.width();
1773 int height = aImage.height();
1774 int depth = aImage.depth();
1775 int size = width*height;
1776
1777 if (depth == 1)
1778 size = (width+7)/8*height;
1779 else if (aInColor == 1)
1780 size = size*3;
1781
1782 int i = 0;
1783 // if ( aInColor ==1 ) {
1784 // FIXME : L. Garnier. For the moment 10 dec 2007, I could not find a way
1785 // to save correctly grayscale Image. I mean that color or grayscale image
1786 // have the same file save size !
1787
1788 /* } else*/ if (depth == 8) {
1789 for(int y=height-1; y >=0 ; y--) {
1790 const uchar * s = aImage.scanLine(y);
1791 for(int x=0; x <width; x++) {
1792 QRgb rgb = aImage.color(s[x]);
1793 if (aInColor == 1) {
1794 fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
1795 i++;
1796 } else {
1797 fprintf (fp, " %02hx %02hx %02hx",
1798 (unsigned char) qRed(rgb),
1799 (unsigned char) qGreen(rgb),
1800 (unsigned char) qBlue(rgb));
1801 i += 3;
1802 }
1803 }
1804 fprintf (fp, "\n");
1805 }
1806 } else {
1807#if QT_VERSION < 0x040000
1808 bool alpha = aImage.hasAlphaBuffer();
1809#else
1810 bool alpha = aImage.hasAlphaChannel();
1811#endif
1812 for(int y=height-1; y >=0 ; y--) {
1813 QRgb * s = (QRgb*)(aImage.scanLine(y));
1814 for(int x=0; x <width; x++) {
1815 QRgb rgb = (*s++);
1816 if (alpha && qAlpha(rgb) < 0x40) // 25% alpha, convert to white -
1817 rgb = qRgb(0xff, 0xff, 0xff);
1818 if (aInColor == 1) {
1819 fprintf (fp, " %02hx ",(unsigned char)qGray(rgb));
1820 i++;
1821 } else {
1822 fprintf (fp, " %02hx %02hx %02hx",
1823 (unsigned char) qRed(rgb),
1824 (unsigned char) qGreen(rgb),
1825 (unsigned char) qBlue(rgb));
1826 i += 3;
1827 }
1828 }
1829 fprintf (fp, "\n");
1830 }
1831
1832 }
1833
1834 fprintf (fp, "grestore\n");
1835 fprintf (fp, "showpage\n");
1836 fclose (fp);
1837
1838 return true;
1839}
1840/**
1841 Generate Postscript or PDF form image
1842 @param aFilename : name of file
1843 @param aInColor : numbers of colors : 1->BW 2->RGB
1844 @param aImage : Image to print
1845*/
1846bool G4OpenGLQtViewer::generatePS_PDF (
1847 QString aFilename
1848,int aInColor
1849,QImage aImage
1850)
1851{
1852
1853#if QT_VERSION < 0x040000
1854#ifdef Q_WS_MAC || Q_WS_X11
1855 QPrinter printer;
1856 // printer.setPageSize(pageSize);
1857 if (aInColor == 1) {
1858 printer.setColorMode(QPrinter::GrayScale);
1859 } else {
1860 printer.setColorMode(QPrinter::Color);
1861 }
1862
1863 /* FIXME : I don't know which format it will save...
1864 if (aFilename.endsWith(".ps")) {
1865 printer.setOutputFormat(QPrinter::PostScriptFormat);
1866 } else {
1867 printer.setOutputFormat(QPrinter::PdfFormat);
1868 }
1869 */
1870 printer.setOutputFileName(aFilename);
1871 // printer.setFullPage ( true);
1872 QPainter paint(&printer);
1873 paint.drawImage (0,0,aImage );
1874 paint.end();
1875#else
1876 G4cerr << "This fonction is only supported on Mac OsX or X11 with Qt3. Full platform supported with Qt4" << G4endl;
1877#endif
1878#else
1879 QPrinter printer;
1880 // printer.setPageSize(pageSize);
1881
1882 // FIXME : L. Garnier 4/12/07
1883 // This is not working, it does nothing. Image is staying in color mode
1884 // So I have desactivate the B/W button in GUI
1885 if ((!aImage.isGrayscale ()) &&(aInColor ==1 )) {
1886#if QT_VERSION < 0x040000
1887 aImage = aImage.convertDepth(1,Qt::MonoOnly);
1888#else
1889 aImage = aImage.convertToFormat ( aImage.format(), Qt::MonoOnly);
1890#endif
1891 }
1892
1893
1894 if (aFilename.endsWith(".ps")) {
1895#if QT_VERSION > 0x040200
1896 printer.setOutputFormat(QPrinter::PostScriptFormat);
1897#endif
1898 } else {
1899#if QT_VERSION > 0x040100
1900 printer.setOutputFormat(QPrinter::PdfFormat);
1901#endif
1902 }
1903#if QT_VERSION > 0x040100
1904 printer.setOutputFileName(aFilename);
1905#endif
1906 // printer.setFullPage ( true);
1907 QPainter paint(&printer);
1908 paint.drawImage (0,0,aImage);
1909 paint.end();
1910#endif
1911 return true;
1912}
1913
1914
1915void G4OpenGLQtViewer::G4wheelEvent (QWheelEvent * event)
1916{
1917 fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.GetZoomFactor()*(event->delta())/1200));
1918 updateQWidget();
1919}
1920
1921
1922void G4OpenGLQtViewer::G4keyPressEvent (QKeyEvent * event)
1923{
1924 if (fHoldKeyEvent)
1925 return;
1926
1927 fHoldKeyEvent = true;
1928
1929#if QT_VERSION < 0x040000
1930 if ((event->key() == Qt::Key_Down) && (event->state() & Qt::AltButton )) { // go backward
1931#else
1932 if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::AltModifier )) { // go backward
1933#endif
1934
1935 moveScene(0,0,1,false);
1936 }
1937#if QT_VERSION < 0x040000
1938 else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::AltButton)) { // go forward
1939#else
1940 else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::AltModifier)) { // go forward
1941#endif
1942 moveScene(0,0,-1,false);
1943 }
1944#if QT_VERSION < 0x040000
1945 if ((event->key() == Qt::Key_Down) && (event->state() & Qt::ShiftButton)) { // rotate phi
1946#else
1947 if ((event->key() == Qt::Key_Down) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
1948#endif
1949 rotateQtCamera(0,-1);
1950 }
1951#if QT_VERSION < 0x040000
1952 else if ((event->key() == Qt::Key_Up) && (event->state() & Qt::ShiftButton)) { // rotate phi
1953#else
1954 else if ((event->key() == Qt::Key_Up) && (event->modifiers() & Qt::ShiftModifier)) { // rotate phi
1955#endif
1956 rotateQtCamera(0,1);
1957 }
1958#if QT_VERSION < 0x040000
1959 if ((event->key() == Qt::Key_Left) && (event->state() & Qt::ShiftButton)) { // rotate theta
1960#else
1961 if ((event->key() == Qt::Key_Left) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
1962#endif
1963 rotateQtCamera(1,0);
1964 }
1965#if QT_VERSION < 0x040000
1966 else if ((event->key() == Qt::Key_Right) && (event->state() & Qt::ShiftButton)) { // rotate theta
1967#else
1968 else if ((event->key() == Qt::Key_Right) && (event->modifiers() & Qt::ShiftModifier)) { // rotate theta
1969#endif
1970 rotateQtCamera(-1,0);
1971 }
1972
1973#if QT_VERSION < 0x040000
1974 if ((event->state() & Qt::AltButton)) {
1975#else
1976 if ((event->modifiers() & Qt::AltModifier)) {
1977#endif
1978 if (event->key() == Qt::Key_Plus) {
1979 fDeltaRotation = fDeltaRotation/0.7;
1980 }
1981 else if (event->key() == Qt::Key_Minus) {
1982 fDeltaRotation = fDeltaRotation*0.7;
1983 }
1984 } else {
1985 if (event->key() == Qt::Key_Plus) {
1986 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1+fDeltaZoom));
1987 updateQWidget();
1988 }
1989 else if (event->key() == Qt::Key_Minus) {
1990 fVP.SetZoomFactor(fVP.GetZoomFactor()*(1-fDeltaZoom));
1991 updateQWidget();
1992 }
1993 }
1994
1995
1996 if (event->key() == Qt::Key_Escape) { // escaped from full screen
1997#if QT_VERSION >= 0x030200
1998 toggleFullScreen(false);
1999#endif
2000 }
2001 // several case here : If return is pressed, in every case -> display the movie parameters dialog
2002 // If one parameter is wrong -> put it in red (only save filenam could be wrong..)
2003 // If encoder not found-> does nothing.Only display a message in status box
2004 // If all ok-> generate parameter file
2005 // If ok -> put encoder button enabled
2006
2007 if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)){ // end of video
2008 stopVideo();
2009 }
2010 if (event->key() == Qt::Key_Space){ // start/pause of video
2011 startPauseVideo();
2012 }
2013
2014 // with no modifiers
2015#if QT_VERSION < 0x040000
2016 if (event->state() == Qt::NoButton) {
2017#else
2018 if ((event->modifiers() == Qt::NoModifier) || (event->modifiers() == Qt::KeypadModifier )) {
2019#endif
2020 if (event->key() == Qt::Key_Down) { // go down
2021 moveScene(0,1,0,false);
2022 }
2023 else if (event->key() == Qt::Key_Up) { // go up
2024 moveScene(0,-1,0,false);
2025 }
2026 if (event->key() == Qt::Key_Left) { // go left
2027 moveScene(-1,0,0,false);
2028 }
2029 else if (event->key() == Qt::Key_Right) { // go right
2030 moveScene(1,0,0,false);
2031 }
2032 }
2033 fHoldKeyEvent = false;
2034}
2035
2036
2037/** Stop the video. Check all parameters and enable encoder button if all is ok.
2038*/
2039void G4OpenGLQtViewer::stopVideo() {
2040
2041 // if encoder parameter is wrong, display parameters dialog and return
2042 if (!fMovieParametersDialog) {
2043 showMovieParametersDialog();
2044 }
2045 setRecordingStatus(STOP);
2046
2047 if (fRecordFrameNumber >0) {
2048 // check parameters if they were modified (Re APPLY them...)
2049 if (!(fMovieParametersDialog->checkEncoderSwParameters())) {
2050 setRecordingStatus(BAD_ENCODER);
2051 } else if (!(fMovieParametersDialog->checkSaveFileNameParameters())) {
2052 setRecordingStatus(BAD_OUTPUT);
2053 }
2054 } else {
2055 resetRecording();
2056 setRecordingInfos("No frame to encode.");
2057 }
2058}
2059
2060/** Stop the video. Check all parameters and enable encoder button if all is ok.
2061*/
2062void G4OpenGLQtViewer::saveVideo() {
2063
2064 // if encoder parameter is wrong, display parameters dialog and return
2065 if (!fMovieParametersDialog) {
2066 showMovieParametersDialog();
2067 }
2068
2069 fMovieParametersDialog->checkEncoderSwParameters();
2070 fMovieParametersDialog->checkSaveFileNameParameters();
2071
2072 if (fRecordingStep == STOP) {
2073 setRecordingStatus(SAVE);
2074 generateMpegEncoderParameters();
2075 encodeVideo();
2076 }
2077}
2078
2079
2080/** Start/Pause the video..
2081*/
2082void G4OpenGLQtViewer::startPauseVideo() {
2083
2084 // first time, if temp parameter is wrong, display parameters dialog and return
2085
2086 if (( fRecordingStep == WAIT)) {
2087 if ( fRecordFrameNumber == 0) {
2088 if (getTempFolderPath() == "") { // BAD_OUTPUT
2089 showMovieParametersDialog();
2090 setRecordingInfos("You should specified the temp folder in order to make movie");
2091 return;
2092 } else {
2093 // remove temp folder if it was create
2094 QString tmp = removeTempFolder();
2095 if (tmp !="") {
2096 setRecordingInfos(tmp);
2097 return;
2098 }
2099 tmp = createTempFolder();
2100 if (tmp != "") {
2101 setRecordingInfos("Can't create temp folder."+tmp);
2102 return;
2103 }
2104 }
2105 }
2106 }
2107 if ((fRecordingStep == WAIT)) {
2108 setRecordingStatus(START);
2109 } else if (fRecordingStep == START) {
2110 setRecordingStatus(PAUSE);
2111 } else if (fRecordingStep == PAUSE) {
2112 setRecordingStatus(CONTINUE);
2113 } else if (fRecordingStep == CONTINUE) {
2114 setRecordingStatus(PAUSE);
2115 }
2116}
2117
2118void G4OpenGLQtViewer::setRecordingStatus(RECORDING_STEP step) {
2119
2120 fRecordingStep = step;
2121 displayRecordingStatus();
2122}
2123
2124
2125void G4OpenGLQtViewer::displayRecordingStatus() {
2126
2127 QString txtStatus = "";
2128 if (fRecordingStep == WAIT) {
2129 txtStatus = "Waiting to start...";
2130 fRecordFrameNumber = 0; // reset the frame number
2131 } else if (fRecordingStep == START) {
2132 txtStatus = "Start Recording...";
2133 } else if (fRecordingStep == PAUSE) {
2134 txtStatus = "Pause Recording...";
2135 } else if (fRecordingStep == CONTINUE) {
2136 txtStatus = "Continue Recording...";
2137 } else if (fRecordingStep == STOP) {
2138 txtStatus = "Stop Recording...";
2139 } else if (fRecordingStep == READY_TO_ENCODE) {
2140 txtStatus = "Ready to Encode...";
2141 } else if (fRecordingStep == ENCODING) {
2142 txtStatus = "Encoding...";
2143 } else if (fRecordingStep == FAILED) {
2144 txtStatus = "Failed to encode...";
2145 } else if ((fRecordingStep == BAD_ENCODER)
2146 || (fRecordingStep == BAD_OUTPUT)
2147 || (fRecordingStep == BAD_TMP)) {
2148 txtStatus = "Correct above errors first";
2149 } else if (fRecordingStep == SUCCESS) {
2150 txtStatus = "File encoded successfully";
2151 } else {
2152 }
2153
2154 if (fMovieParametersDialog) {
2155 fMovieParametersDialog->setRecordingStatus(txtStatus);
2156 } else {
2157#if QT_VERSION < 0x040000
2158 G4cout << txtStatus.ascii() << G4endl;
2159#else
2160 G4cout << txtStatus.toStdString().c_str() << G4endl;
2161#endif
2162 }
2163 setRecordingInfos("");
2164}
2165
2166
2167void G4OpenGLQtViewer::setRecordingInfos(QString txt) {
2168 if (fMovieParametersDialog) {
2169 fMovieParametersDialog->setRecordingInfos(txt);
2170 } else {
2171#if QT_VERSION < 0x040000
2172 G4cout << txt.ascii() << G4endl;
2173#else
2174 G4cout << txt.toStdString().c_str() << G4endl;
2175#endif
2176 }
2177}
2178
2179/** Init the movie parameters. Temp dir and encoder path
2180*/
2181void G4OpenGLQtViewer::initMovieParameters() {
2182 //init encoder
2183
2184 //look for encoderPath
2185 fProcess = new QProcess();
2186
2187#if QT_VERSION < 0x040000
2188 QObject ::connect(fProcess,SIGNAL(processExited ()),
2189 this,SLOT(processLookForFinished()));
2190 fProcess->setCommunication(QProcess::DupStderr);
2191 fProcess->setArguments(QStringList("which mpeg_encode"));
2192 fProcess->start();
2193#else
2194 QObject ::connect(fProcess,SIGNAL(finished ( int)),
2195 this,SLOT(processLookForFinished()));
2196 fProcess->setReadChannelMode(QProcess::MergedChannels);
2197 fProcess->start ("which mpeg_encode");
2198#endif
2199
2200}
2201
2202/** @return encoder path or "" if it does not exist
2203 */
2204QString G4OpenGLQtViewer::getEncoderPath() {
2205 return fEncoderPath;
2206}
2207
2208
2209/**
2210 * set the new encoder path
2211 * @return "" if correct. The error otherwise
2212*/
2213QString G4OpenGLQtViewer::setEncoderPath(QString path) {
2214 if (path == "") {
2215 return "File does not exist";
2216 }
2217
2218#if QT_VERSION < 0x040000
2219 path = QDir::cleanDirPath(path);
2220#else
2221 path = QDir::cleanPath(path);
2222#endif
2223 QFileInfo *f = new QFileInfo(path);
2224 if (!f->exists()) {
2225 return "File does not exist";
2226 } else if (f->isDir()) {
2227 return "This is a directory";
2228 } else if (!f->isExecutable()) {
2229 return "File exist but is not executable";
2230 } else if (!f->isFile()) {
2231 return "This is not a file";
2232 }
2233 fEncoderPath = path;
2234
2235 if ((fRecordingStep == BAD_ENCODER)) {
2236 setRecordingStatus(STOP);
2237 }
2238 return "";
2239}
2240
2241
2242bool G4OpenGLQtViewer::isRecording(){
2243 if ((fRecordingStep == START) || (fRecordingStep == CONTINUE)) {
2244 return true;
2245 }
2246 return false;
2247}
2248
2249bool G4OpenGLQtViewer::isPaused(){
2250 if (fRecordingStep == PAUSE) {
2251 return true;
2252 }
2253 return false;
2254}
2255
2256bool G4OpenGLQtViewer::isEncoding(){
2257 if (fRecordingStep == ENCODING) {
2258 return true;
2259 }
2260 return false;
2261}
2262
2263bool G4OpenGLQtViewer::isWaiting(){
2264 if (fRecordingStep == WAIT) {
2265 return true;
2266 }
2267 return false;
2268}
2269
2270bool G4OpenGLQtViewer::isStopped(){
2271 if (fRecordingStep == STOP) {
2272 return true;
2273 }
2274 return false;
2275}
2276
2277bool G4OpenGLQtViewer::isFailed(){
2278 if (fRecordingStep == FAILED) {
2279 return true;
2280 }
2281 return false;
2282}
2283
2284bool G4OpenGLQtViewer::isSuccess(){
2285 if (fRecordingStep == SUCCESS) {
2286 return true;
2287 }
2288 return false;
2289}
2290
2291bool G4OpenGLQtViewer::isBadEncoder(){
2292 if (fRecordingStep == BAD_ENCODER) {
2293 return true;
2294 }
2295 return false;
2296}
2297bool G4OpenGLQtViewer::isBadTmp(){
2298 if (fRecordingStep == BAD_TMP) {
2299 return true;
2300 }
2301 return false;
2302}
2303bool G4OpenGLQtViewer::isBadOutput(){
2304 if (fRecordingStep == BAD_OUTPUT) {
2305 return true;
2306 }
2307 return false;
2308}
2309
2310void G4OpenGLQtViewer::setBadEncoder(){
2311 fRecordingStep = BAD_ENCODER;
2312 displayRecordingStatus();
2313}
2314void G4OpenGLQtViewer::setBadTmp(){
2315 fRecordingStep = BAD_TMP;
2316 displayRecordingStatus();
2317}
2318void G4OpenGLQtViewer::setBadOutput(){
2319 fRecordingStep = BAD_OUTPUT;
2320 displayRecordingStatus();
2321}
2322
2323void G4OpenGLQtViewer::setWaiting(){
2324 fRecordingStep = WAIT;
2325 displayRecordingStatus();
2326}
2327
2328
2329bool G4OpenGLQtViewer::isReadyToEncode(){
2330 if (fRecordingStep == READY_TO_ENCODE) {
2331 return true;
2332 }
2333 return false;
2334}
2335
2336void G4OpenGLQtViewer::resetRecording() {
2337 setRecordingStatus(WAIT);
2338}
2339
2340/**
2341 * set the temp folder path
2342 * @return "" if correct. The error otherwise
2343*/
2344QString G4OpenGLQtViewer::setTempFolderPath(QString path) {
2345
2346 if (path == "") {
2347 return "Path does not exist";
2348 }
2349#if QT_VERSION < 0x040000
2350 path = QDir::cleanDirPath(path);
2351#else
2352 path = QDir::cleanPath(path);
2353#endif
2354 QFileInfo *d = new QFileInfo(path);
2355 if (!d->exists()) {
2356 return "Path does not exist";
2357 } else if (!d->isDir()) {
2358 return "This is not a directory";
2359 } else if (!d->isReadable()) {
2360 return path +" is read protected";
2361 } else if (!d->isWritable()) {
2362 return path +" is write protected";
2363 }
2364
2365 if ((fRecordingStep == BAD_TMP)) {
2366 setRecordingStatus(WAIT);
2367 }
2368 fTempFolderPath = path;
2369 return "";
2370}
2371
2372/** @return the temp folder path or "" if it does not exist
2373 */
2374QString G4OpenGLQtViewer::getTempFolderPath() {
2375 return fTempFolderPath;
2376}
2377
2378/**
2379 * set the save file name path
2380 * @return "" if correct. The error otherwise
2381*/
2382QString G4OpenGLQtViewer::setSaveFileName(QString path) {
2383
2384 if (path == "") {
2385 return "Path does not exist";
2386 }
2387
2388 QFileInfo *file = new QFileInfo(path);
2389 QDir dir = file->dir();
2390#if QT_VERSION < 0x040000
2391 path = QDir::cleanDirPath(path);
2392#else
2393 path = QDir::cleanPath(path);
2394#endif
2395 if (file->exists()) {
2396 return "File already exist, please choose a new one";
2397 } else if (!dir.exists()) {
2398 return "Dir does not exist";
2399 } else if (!dir.isReadable()) {
2400 return path +" is read protected";
2401 }
2402
2403 if ((fRecordingStep == BAD_OUTPUT)) {
2404 setRecordingStatus(STOP);
2405 }
2406 fSaveFileName = path;
2407 return "";
2408}
2409
2410/** @return the save file path
2411 */
2412QString G4OpenGLQtViewer::getSaveFileName() {
2413 return fSaveFileName ;
2414}
2415
2416/** Create a Qt_temp folder in the temp folder given
2417* The temp folder will be like this /tmp/QtMovie_12-02-2008_12_12_58/
2418* @return "" if success. Error message if not.
2419*/
2420QString G4OpenGLQtViewer::createTempFolder() {
2421 fMovieTempFolderPath = "";
2422 //check
2423 QString tmp = setTempFolderPath(fTempFolderPath);
2424 if (tmp != "") {
2425 return tmp;
2426 }
2427#if QT_VERSION < 0x040000
2428 QString sep = QChar(QDir::separator());
2429#else
2430 QString sep = QString(QDir::separator());
2431#endif
2432 QString path = sep+"QtMovie_"+QDateTime::currentDateTime ().toString("dd-MM-yyyy_hh-mm-ss")+sep;
2433#if QT_VERSION < 0x040000
2434 QDir *d = new QDir(QDir::cleanDirPath(fTempFolderPath));
2435#else
2436 QDir *d = new QDir(QDir::cleanPath(fTempFolderPath));
2437#endif
2438 // check if it is already present
2439 if (d->exists(path)) {
2440 return "Folder "+path+" already exists.Please remove it first";
2441 }
2442 if (d->mkdir(fTempFolderPath+path)) {
2443 fMovieTempFolderPath = fTempFolderPath+path;
2444 return "";
2445 } else {
2446 return "Can't create "+fTempFolderPath+path;
2447 }
2448 return "-";
2449}
2450
2451/** Remove the Qt_temp folder in the temp folder
2452*/
2453QString G4OpenGLQtViewer::removeTempFolder() {
2454 // remove files in Qt_temp folder
2455 if (fMovieTempFolderPath == "") {
2456 return "";
2457 }
2458#if QT_VERSION < 0x040000
2459 QDir *d = new QDir(QDir::cleanDirPath(fMovieTempFolderPath));
2460#else
2461 QDir *d = new QDir(QDir::cleanPath(fMovieTempFolderPath));
2462#endif
2463 if (!d->exists()) {
2464 return ""; // already remove
2465 }
2466
2467 d->setFilter( QDir::Files );
2468 QStringList subDirList = d->entryList();
2469 int res = true;
2470 QString error = "";
2471 for (QStringList::ConstIterator it = subDirList.begin() ;(it != subDirList.end()) ; it++) {
2472 const QString currentFile = *it;
2473 if (!d->remove(currentFile)) {
2474 res = false;
2475 QString file = fMovieTempFolderPath+currentFile;
2476 error +="Removing file failed : "+file;
2477 } else {
2478 }
2479 }
2480 if (res) {
2481 if (d->rmdir(fMovieTempFolderPath)) {
2482 fMovieTempFolderPath = "";
2483 return "";
2484 } else {
2485 return "Dir "+fMovieTempFolderPath+" should be empty, but could not remove it";
2486 }
2487
2488 }
2489 return "Could not remove "+fMovieTempFolderPath+" because of the following errors :"+error;
2490}
2491
2492
2493
2494bool G4OpenGLQtViewer::hasPendingEvents () {
2495 return ((QApplication*)G4Qt::getInstance ())->hasPendingEvents ();
2496}
2497
2498bool G4OpenGLQtViewer::generateMpegEncoderParameters () {
2499
2500 // save the parameter file
2501 FILE* fp;
2502#if QT_VERSION < 0x040000
2503 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).ascii(), "w");
2504#else
2505 fp = fopen (QString(fMovieTempFolderPath+fParameterFileName).toStdString().c_str(), "w");
2506#endif
2507
2508 if (fp == NULL) {
2509 setRecordingInfos("Generation of parameter file failed");
2510 return false;
2511 }
2512
2513 fprintf (fp,"# parameter file template with lots of comments to assist you\n");
2514 fprintf (fp,"#\n");
2515 fprintf (fp,"# you can use this as a template, copying it to a separate file then modifying\n");
2516 fprintf (fp,"# the copy\n");
2517 fprintf (fp,"#\n");
2518 fprintf (fp,"#\n");
2519 fprintf (fp,"# any line beginning with '#' is a comment\n");
2520 fprintf (fp,"#\n");
2521 fprintf (fp,"# no line should be longer than 255 characters\n");
2522 fprintf (fp,"#\n");
2523 fprintf (fp,"#\n");
2524 fprintf (fp,"# general format of each line is:\n");
2525 fprintf (fp,"# \n");
2526 fprintf (fp,"#\n");
2527 fprintf (fp,"# lines can generally be in any order\n");
2528 fprintf (fp,"#\n");
2529 fprintf (fp,"# an exception is the option 'INPUT' which must be followed by input\n");
2530 fprintf (fp,"# files in the order in which they must appear, followed by 'END_INPUT'\n");
2531 fprintf (fp,"#\n");
2532 fprintf (fp,"# Also, if you use the `command` method of generating input file names,\n");
2533 fprintf (fp,"# the command will only be executed in the INPUT_DIR if INPUT_DIR preceeds\n");
2534 fprintf (fp,"# the INPUT parameter.\n");
2535 fprintf (fp,"#\n");
2536 fprintf (fp,"# MUST be in UPPER CASE\n");
2537 fprintf (fp,"#\n");
2538 fprintf (fp,"\n");
2539 fprintf (fp,"# Pattern affects speed, quality and compression. See the User's Guide\n");
2540 fprintf (fp,"# for more info.\n");
2541 fprintf (fp,"\n");
2542 fprintf (fp,"PATTERN IBBPBBPBBPBBPBBP\n");
2543#if QT_VERSION < 0x040000
2544 fprintf (fp,"OUTPUT %s\n",getSaveFileName().ascii());
2545#else
2546 fprintf (fp,"OUTPUT %s\n",getSaveFileName().toStdString().c_str());
2547#endif
2548 fprintf (fp,"\n");
2549 fprintf (fp,"# mpeg_encode really only accepts 3 different file formats, but using a\n");
2550 fprintf (fp,"# conversion statement it can effectively handle ANY file format\n");
2551 fprintf (fp,"#\n");
2552 fprintf (fp,"# You must specify the type of the input files. The choices are:\n");
2553 fprintf (fp,"# YUV, PPM, JMOVIE, Y, JPEG, PNM\n");
2554 fprintf (fp,"# (must be upper case)\n");
2555 fprintf (fp,"#\n");
2556 fprintf (fp,"BASE_FILE_FORMAT PPM\n");
2557 fprintf (fp,"\n");
2558 fprintf (fp,"#\n");
2559 fprintf (fp,"# if YUV format (or using parallel version), must provide width and height\n");
2560 fprintf (fp,"# YUV_SIZE widthxheight\n");
2561 fprintf (fp,"# this option is ignored if BASE_FILE_FORMAT is not YUV and you're running\n");
2562 fprintf (fp,"# on just one machine\n");
2563 fprintf (fp,"#\n");
2564 fprintf (fp,"YUV_SIZE 352x240\n");
2565 fprintf (fp,"\n");
2566 fprintf (fp,"# If you are using YUV, there are different supported file formats.\n");
2567 fprintf (fp,"# EYUV or UCB are the same as previous versions of this encoder.\n");
2568 fprintf (fp,"# (All the Y's, then U's then V's, in 4:2:0 subsampling.)\n");
2569 fprintf (fp,"# Other formats, such as Abekas, Phillips, or a general format are\n");
2570 fprintf (fp,"# permissible, the general format is a string of Y's, U's, and V's\n");
2571 fprintf (fp,"# to specify the file order.\n");
2572 fprintf (fp,"\n");
2573 fprintf (fp,"INPUT_FORMAT UCB\n");
2574 fprintf (fp,"\n");
2575 fprintf (fp,"# the conversion statement\n");
2576 fprintf (fp,"#\n");
2577 fprintf (fp,"# Each occurrence of '*' will be replaced by the input file\n");
2578 fprintf (fp,"#\n");
2579 fprintf (fp,"# e.g., if you have a bunch of GIF files, then this might be:\n");
2580 fprintf (fp,"# INPUT_CONVERT giftoppm *\n");
2581 fprintf (fp,"#\n");
2582 fprintf (fp,"# e.g., if you have a bunch of files like a.Y a.U a.V, etc., then:\n");
2583 fprintf (fp,"# INPUT_CONVERT cat *.Y *.U *.V\n");
2584 fprintf (fp,"#\n");
2585 fprintf (fp,"# e.g., if you are grabbing from laser disc you might have something like\n");
2586 fprintf (fp,"# INPUT_CONVERT goto frame *; grabppm\n");
2587 fprintf (fp,"# 'INPUT_CONVERT *' means the files are already in the base file format\n");
2588 fprintf (fp,"#\n");
2589 fprintf (fp,"INPUT_CONVERT * \n");
2590 fprintf (fp,"\n");
2591 fprintf (fp,"# number of frames in a GOP.\n");
2592 fprintf (fp,"#\n");
2593 fprintf (fp,"# since each GOP must have at least one I-frame, the encoder will find the\n");
2594 fprintf (fp,"# the first I-frame after GOP_SIZE frames to start the next GOP\n");
2595 fprintf (fp,"#\n");
2596 fprintf (fp,"# later, will add more flexible GOP signalling\n");
2597 fprintf (fp,"#\n");
2598 fprintf (fp,"GOP_SIZE 16\n");
2599 fprintf (fp,"\n");
2600 fprintf (fp,"# number of slices in a frame\n");
2601 fprintf (fp,"#\n");
2602 fprintf (fp,"# 1 is a good number. another possibility is the number of macroblock rows\n");
2603 fprintf (fp,"# (which is the height divided by 16)\n");
2604 fprintf (fp,"#\n");
2605 fprintf (fp,"SLICES_PER_FRAME 1\n");
2606 fprintf (fp,"\n");
2607 fprintf (fp,"# directory to get all input files from (makes this file easier to read)\n");
2608#if QT_VERSION < 0x040000
2609 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.ascii());
2610#else
2611 fprintf (fp,"INPUT_DIR %s\n",fMovieTempFolderPath.toStdString().c_str());
2612#endif
2613 fprintf (fp,"\n");
2614 fprintf (fp,"# There are a bunch of ways to specify the input files.\n");
2615 fprintf (fp,"# from a simple one-per-line listing, to the following \n");
2616 fprintf (fp,"# way of numbering them. See the manual for more information.\n");
2617 fprintf (fp,"INPUT\n");
2618 fprintf (fp,"# '*' is replaced by the numbers 01, 02, 03, 04\n");
2619 fprintf (fp,"# if I instead do [01-11], it would be 01, 02, ..., 09, 10, 11\n");
2620 fprintf (fp,"# if I instead do [1-11], it would be 1, 2, 3, ..., 9, 10, 11\n");
2621 fprintf (fp,"# if I instead do [1-11+3], it would be 1, 4, 7, 10\n");
2622 fprintf (fp,"# the program assumes none of your input files has a name ending in ']'\n");
2623 fprintf (fp,"# if you do, too bad!!!\n");
2624 fprintf (fp,"#\n");
2625 fprintf (fp,"#\n");
2626 fprintf (fp,"Test*.ppm [0-%d]\n",fRecordFrameNumber-1);
2627 fprintf (fp,"# can have more files here if you want...there is no limit on the number\n");
2628 fprintf (fp,"# of files\n");
2629 fprintf (fp,"END_INPUT\n");
2630 fprintf (fp,"\n");
2631 fprintf (fp,"\n");
2632 fprintf (fp,"\n");
2633 fprintf (fp,"# Many of the remaining options have to do with the motion search and qscale\n");
2634 fprintf (fp,"\n");
2635 fprintf (fp,"# FULL or HALF -- must be upper case\n");
2636 fprintf (fp,"# Should be FULL for computer generated images\n");
2637 fprintf (fp,"PIXEL FULL\n");
2638 fprintf (fp,"\n");
2639 fprintf (fp,"# means +/- this many pixels for both P and B frame searches\n");
2640 fprintf (fp,"# specify two numbers if you wish to serc different ranges in the two.\n");
2641 fprintf (fp,"RANGE 10\n");
2642 fprintf (fp,"\n");
2643 fprintf (fp,"# The two search algorithm parameters below mostly affect speed,\n");
2644 fprintf (fp,"# with some affect on compression and almost none on quality.\n");
2645 fprintf (fp,"\n");
2646 fprintf (fp,"# this must be one of {EXHAUSTIVE, SUBSAMPLE, LOGARITHMIC}\n");
2647 fprintf (fp,"PSEARCH_ALG LOGARITHMIC\n");
2648 fprintf (fp,"\n");
2649 fprintf (fp,"# this must be one of {SIMPLE, CROSS2, EXHAUSTIVE}\n");
2650 fprintf (fp,"#\n");
2651 fprintf (fp,"# note that EXHAUSTIVE is really, really, really slow\n");
2652 fprintf (fp,"#\n");
2653 fprintf (fp,"BSEARCH_ALG SIMPLE\n");
2654 fprintf (fp,"\n");
2655 fprintf (fp,"#\n");
2656 fprintf (fp,"# these specify the q-scale for I, P, and B frames\n");
2657 fprintf (fp,"# (values must be between 1 and 31)\n");
2658 fprintf (fp,"# These are the Qscale values for the entire frame in variable bit-rate\n");
2659 fprintf (fp,"# mode, and starting points (but not important) for constant bit rate\n");
2660 fprintf (fp,"#\n");
2661 fprintf (fp,"\n");
2662 fprintf (fp,"# Qscale (Quantization scale) affects quality and compression,\n");
2663 fprintf (fp,"# but has very little effect on speed.\n");
2664 fprintf (fp,"\n");
2665 fprintf (fp,"IQSCALE 4\n");
2666 fprintf (fp,"PQSCALE 5\n");
2667 fprintf (fp,"BQSCALE 12\n");
2668 fprintf (fp,"\n");
2669 fprintf (fp,"# this must be ORIGINAL or DECODED\n");
2670 fprintf (fp,"REFERENCE_FRAME ORIGINAL\n");
2671 fprintf (fp,"\n");
2672 fprintf (fp,"# for parallel parameters see parallel.param in the exmaples subdirectory\n");
2673 fprintf (fp,"\n");
2674 fprintf (fp,"# if you want constant bit-rate mode, specify it as follows (number is bits/sec):\n");
2675 fprintf (fp,"#BIT_RATE 1000000\n");
2676 fprintf (fp,"\n");
2677 fprintf (fp,"# To specify the buffer size (327680 is default, measused in bits, for 16bit words)\n");
2678 fprintf (fp,"BUFFER_SIZE 327680\n");
2679 fprintf (fp,"\n");
2680 fprintf (fp,"# The frame rate is the number of frames/second (legal values:\n");
2681 fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 50 ,59.94, 60\n");
2682 fprintf (fp,"FRAME_RATE 30\n");
2683 fprintf (fp,"\n");
2684 fprintf (fp,"# There are many more options, see the users manual for examples....\n");
2685 fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAMMA, IQTABLE, etc.\n");
2686 fprintf (fp,"\n");
2687 fprintf (fp,"\n");
2688 fclose (fp);
2689
2690 setRecordingInfos("Parameter file "+fParameterFileName+" generated in "+fMovieTempFolderPath);
2691 setRecordingStatus(READY_TO_ENCODE);
2692 return true;
2693}
2694
2695void G4OpenGLQtViewer::encodeVideo()
2696{
2697 if ((getEncoderPath() != "") && (getSaveFileName() != "")) {
2698 setRecordingStatus(ENCODING);
2699
2700#if QT_VERSION < 0x040000
2701 QStringList args = QStringList(fEncoderPath);
2702 args.push_back(fMovieTempFolderPath+fParameterFileName);
2703 fProcess = new QProcess(args);
2704 QObject ::connect(fProcess,SIGNAL(processExited ()),
2705 this,SLOT(processEncodeFinished()));
2706 QObject ::connect(fProcess,SIGNAL(readyReadStdout ()),
2707 this,SLOT(processEncodeStdout()));
2708 fProcess->setCommunication(QProcess::DupStderr);
2709 fProcess->launch("");
2710#else
2711 fProcess = new QProcess();
2712#if QT_VERSION > 0x040100
2713 QObject ::connect(fProcess,SIGNAL(finished ( int,QProcess::ExitStatus)),
2714 this,SLOT(processEncodeFinished()));
2715 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2716 this,SLOT(processEncodeStdout()));
2717#else
2718 QObject ::connect(fProcess,SIGNAL(finished ( int)),
2719 this,SLOT(processEncodeFinished()));
2720 QObject ::connect(fProcess,SIGNAL(readyReadStandardOutput ()),
2721 this,SLOT(processEncodeStdout()));
2722#endif
2723 fProcess->setReadChannelMode(QProcess::MergedChannels);
2724 fProcess->start (fEncoderPath, QStringList(fMovieTempFolderPath+fParameterFileName));
2725#endif
2726 }
2727}
2728
2729
2730// FIXME : does not work on Qt3
2731void G4OpenGLQtViewer::processEncodeStdout()
2732{
2733#if QT_VERSION > 0x040000
2734 QString tmp = fProcess->readAllStandardOutput ().data();
2735 int start = tmp.lastIndexOf("ESTIMATED TIME");
2736 tmp = tmp.mid(start,tmp.indexOf("\n",start)-start);
2737#else
2738 QString tmp = fProcess->readStdout ().data();
2739 int start = tmp.findRev("ESTIMATED TIME");
2740 tmp = tmp.mid(start,tmp.find("\n",start)-start);
2741#endif
2742 setRecordingInfos(tmp);
2743}
2744
2745
2746void G4OpenGLQtViewer::processEncodeFinished()
2747{
2748
2749 QString txt = "";
2750 txt = getProcessErrorMsg();
2751 if (txt == "") {
2752 setRecordingStatus(SUCCESS);
2753 } else {
2754 setRecordingStatus(FAILED);
2755 }
2756 // setRecordingInfos(txt+removeTempFolder());
2757}
2758
2759
2760void G4OpenGLQtViewer::processLookForFinished()
2761 {
2762
2763 QString txt = getProcessErrorMsg();
2764 if (txt != "") {
2765 fEncoderPath = "";
2766 } else {
2767#if QT_VERSION > 0x040000
2768 fEncoderPath = QString(fProcess->readAllStandardOutput ().data()).trimmed();
2769#else
2770 fEncoderPath = QString(fProcess->readStdout ().data()).simplifyWhiteSpace();
2771#endif
2772 // if not found, return "not found"
2773 if (fEncoderPath.contains(" ")) {
2774 fEncoderPath = "";
2775 } else if (!fEncoderPath.contains("mpeg_encode")) {
2776 fEncoderPath = "";
2777 }
2778 setEncoderPath(fEncoderPath);
2779 }
2780 // init temp folder
2781#if QT_VERSION > 0x040000
2782 setTempFolderPath(QDir::temp ().absolutePath ());
2783#else
2784 // Let's have a try
2785 setTempFolderPath("/tmp/");
2786#endif
2787}
2788
2789
2790QString G4OpenGLQtViewer::getProcessErrorMsg()
2791{
2792 QString txt = "";
2793#if QT_VERSION < 0x040000
2794 if (!fProcess->normalExit ()) {
2795 txt = "Exist status "+ fProcess->exitStatus ();
2796 }
2797#else
2798 if (fProcess->exitCode() != 0) {
2799 switch (fProcess->error()) {
2800 case QProcess::FailedToStart:
2801 txt = "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.\n";
2802 break;
2803 case QProcess::Crashed:
2804 txt = "The process crashed some time after starting successfully.\n";
2805 break;
2806 case QProcess::Timedout:
2807 txt = "The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.\n";
2808 break;
2809 case QProcess::WriteError:
2810 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";
2811 break;
2812 case QProcess::ReadError:
2813 txt = "An error occurred when attempting to read from the process. For example, the process may not be running.\n";
2814 break;
2815 case QProcess::UnknownError:
2816 txt = "An unknown error occurred. This is the default return value of error().\n";
2817 break;
2818 }
2819 }
2820#endif
2821 return txt;
2822}
2823
2824/*
2825
2826void MultiLayer::exportToSVG(const QString& fname)
2827{
2828 QPicture picture;
2829 QPainter p(&picture);
2830 for (int i=0;i<(int)graphsList->count();i++)
2831 {
2832 Graph *gr=(Graph *)graphsList->at(i);
2833 Plot *myPlot= (Plot *)gr->plotWidget();
2834
2835 QPoint pos=gr->pos();
2836
2837 int width=int(myPlot->frameGeometry().width());
2838 int height=int(myPlot->frameGeometry().height());
2839
2840 myPlot->print(&p, QRect(pos,QSize(width,height)));
2841 }
2842
2843 p.end();
2844 picture.save(fname, "svg");
2845}
2846*/
2847#endif
Note: See TracBrowser for help on using the repository browser.