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

Last change on this file since 875 was 873, checked in by garnier, 17 years ago

Update in code, try to mutualise everything between Stored and immediate Qt Viewers

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