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

Last change on this file since 900 was 898, checked in by garnier, 17 years ago

x,y position should be ok

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