Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/visualization/OpenGL/src/G4OpenGLQtViewer.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /visualization/OpenGL/src/G4OpenGLQtViewer.cc (Version 11.3.0) and /visualization/OpenGL/src/G4OpenGLQtViewer.cc (Version 8.3)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 // G4OpenGLQtViewer : Class to provide Qt spec    
 27 //                     functionality for OpenG    
 28 //                                                
 29 // 27/06/2003 : G.Barrand : implementation (at    
 30 // 30/06/2014 : M.Kelsey :  Change QPixmap obj    
 31                                                   
 32 #include "G4LogicalVolumeStore.hh"                
 33 #include "G4PhysicalVolumeStore.hh"               
 34 #include "G4VisCommandsGeometrySet.hh"            
 35 #include "G4PhysicalVolumeModel.hh"               
 36 #include "G4Text.hh"                              
 37 #include "G4UnitsTable.hh"                        
 38 #include "G4OpenGLStoredQtViewer.hh"              
 39 #include "G4Threading.hh"                         
 40                                                   
 41 #include "G4OpenGLQtViewer.hh"                    
 42 #include "G4OpenGLSceneHandler.hh"                
 43 #include "G4OpenGLQtExportDialog.hh"              
 44 #include "G4OpenGLQtMovieDialog.hh"               
 45 #include "G4Qt.hh"                                
 46 #include "G4UIQt.hh"                              
 47 #include "G4UImanager.hh"                         
 48 #include "G4UIcommandTree.hh"                     
 49                                                   
 50 #include <CLHEP/Units/SystemOfUnits.h>            
 51                                                   
 52 #include <typeinfo>                               
 53 #include <mutex>                                  
 54                                                   
 55 #include <qlayout.h>                              
 56 #include <qlabel.h>                               
 57 #include <qdialog.h>                              
 58 #include <qpushbutton.h>                          
 59 #include <qprocess.h>                             
 60 #include <qmenu.h>                                
 61 #include <qimagewriter.h>                         
 62                                                   
 63 #include <qtextedit.h>                            
 64 #include <qtreewidget.h>                          
 65 #include <qapplication.h>                         
 66 #include <qmessagebox.h>                          
 67 #include <qfiledialog.h>                          
 68 #include <qdatetime.h>                            
 69 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))    
 70   #include <qelapsedtimer.h>                      
 71 #endif                                            
 72 #if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0))     
 73   #include "qdesktopwidget.h"                     
 74 #endif                                            
 75 #include <qpainter.h>                             
 76 #include <qdialog.h>                              
 77 #include <qcolordialog.h>                         
 78 #include <qevent.h> //include <qcontextmenueve    
 79 #include <qobject.h>                              
 80 #include <qgroupbox.h>                            
 81 #include <qcombobox.h>                            
 82 #include <qlineedit.h>                            
 83 #include <qscreen.h>                              
 84 #include <qmainwindow.h>                          
 85 #include <qtablewidget.h>                         
 86 #include <qheaderview.h>                          
 87 #include <qscrollarea.h>                          
 88 #include <qsplitter.h>                            
 89 #include <qcheckbox.h>                            
 90 #include <qcursor.h>                              
 91 #include <qthread.h>                              
 92                                                   
 93 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))      
 94 #include <QGLContext>                             
 95 #else                                             
 96 #include <QOpenGLContext>                         
 97 #endif                                            
 98                                                   
 99 #ifndef G4GMAKE                                   
100 #include "moc_G4OpenGLQtViewer.cpp"               
101 #endif                                            
102                                                   
103 //////////////////////////////////////////////    
104 void G4OpenGLQtViewer::CreateMainWindow (         
105  G4QGLWidgetType* glWidget                        
106  ,const QString& name                             
107 )                                                 
108 //////////////////////////////////////////////    
109 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!    
110 {                                                 
111                                                   
112   if(fGLWidget) return; //Done.                   
113                                                   
114   fGLWidget = glWidget ;                          
115                                                   
116 #if QT_VERSION < 0x060000                         
117   ResizeWindow(fVP.GetWindowSizeHintX(),fVP.Ge    
118 #else                                             
119   ResizeWindow(glWidget->devicePixelRatio()*fV    
120 #endif                                            
121                                                   
122   // FIXME L.Garnier 9/11/09 Has to be check !    
123   // Qt UI with Qt Vis                            
124   // Qt UI with X Vis                             
125   // X UI with Qt Vis                             
126   // X UI with X Vis                              
127   // Ne marche pas avec un UIBatch !! (ecran b    
128                                                   
129   // return false if G4UIQt was not launch        
130                                                   
131   G4UImanager* UI = G4UImanager::GetUIpointer(    
132   if (UI == NULL) return;                         
133                                                   
134   if (! static_cast<G4UIQt*> (UI->GetG4UIWindo    
135     // NO UI, should be batch mode                
136     fBatchMode = true;                            
137     return;                                       
138   }                                               
139   fUiQt = static_cast<G4UIQt*> (UI->GetG4UIWin    
140                                                   
141   bool isTabbedView = false;                      
142   if ( fUiQt) {                                   
143     if (!fBatchMode) {                            
144       G4Qt* interactorManager = G4Qt::getInsta    
145       if (!interactorManager->IsExternalApp())    
146         // INIT size                              
147         fWinSize_x = fVP.GetWindowSizeHintX();    
148         fWinSize_y = fVP.GetWindowSizeHintY();    
149                                                   
150         isTabbedView = fUiQt->AddTabWidget((QW    
151         QObject::connect(fUiQt->GetViewerTabWi    
152                          SIGNAL(currentChanged    
153                          this,                    
154                          SLOT(currentTabActiva    
155                                                   
156 #if QT_VERSION < 0x060000                         
157 #else                                             
158         createViewerPropertiesWidget();           
159 #endif                                            
160                                                   
161       }                                           
162       createSceneTreeWidget();                    
163       // activate them                            
164     }                                             
165   }                                               
166                                                   
167   if (!isTabbedView) { // we have to do a dial    
168                                                   
169     QWidget *glDialogWidget = getParentWidget(    
170     if (glDialogWidget == NULL) {                 
171       return;                                     
172     }                                             
173     glWidget->setParent(glDialogWidget);          
174     QHBoxLayout *mainLayout = new QHBoxLayout(    
175                                                   
176     mainLayout->setContentsMargins(0,0,0,0);      
177     mainLayout->setSpacing(0);                    
178     mainLayout->addWidget(fGLWidget);             
179     if (fGLWidget->inherits("QMainWindow")) {     
180       fGLWidget->setWindowTitle( name);           
181     }                                             
182     glDialogWidget->setLayout(mainLayout);        
183                                                   
184                                                   
185     //useful for MACOSX, we have to compt the     
186 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))    
187       G4int offset = QGuiApplication::primaryS    
188           - QGuiApplication::screenAt(QPoint(2    
189 #else                                             
190       G4int offset = QApplication::desktop()->    
191           - QApplication::desktop()->available    
192 #endif                                            
193                                                   
194     G4int YPos= fVP.GetWindowAbsoluteLocationH    
195     if (fVP.GetWindowAbsoluteLocationHintY(QGu    
196       YPos = offset;                              
197     }                                             
198     glDialogWidget->resize(getWinWidth(), getW    
199     glDialogWidget->move(fVP.GetWindowAbsolute    
200     glDialogWidget->show();                       
201   }                                               
202                                                   
203   if(!fGLWidget) return;                          
204                                                   
205   if (!fContextMenu)                              
206     createPopupMenu();                            
207                                                   
208 }                                                 
209                                                   
210                                                   
211 //////////////////////////////////////////////    
212 G4OpenGLQtViewer::G4OpenGLQtViewer (              
213  G4OpenGLSceneHandler& scene                      
214 )                                                 
215   :G4VViewer (scene, -1)                          
216   ,G4OpenGLViewer (scene)                         
217   ,fUiQt(NULL)                                    
218   ,fGLWidget(NULL)                                
219   ,fRecordFrameNumber(0)                          
220   ,fMouseOnSceneTree(false)                       
221   ,fContextMenu(0)                                
222   ,fLastPickPoint(-1,-1)                          
223   ,fDeltaDepth(0.01)                              
224   ,fDeltaZoom(0.05)                               
225   ,fHoldKeyEvent(false)                           
226   ,fHoldMoveEvent(false)                          
227   ,fHoldRotateEvent(false)                        
228   ,fAutoMove(false)                               
229   ,fEncoderPath("")                               
230   ,fTempFolderPath("")                            
231   ,fMovieTempFolderPath("")                       
232   ,fSaveFileName("")                              
233   ,fParameterFileName("ppmtompeg_encode_parame    
234   ,fMovieParametersDialog(NULL)                   
235   ,fRecordingStep(WAIT)                           
236   ,fProcess(NULL)                                 
237   ,fNbMaxFramesPerSec(100)                        
238   ,fNbMaxAnglePerSec(360)                         
239   ,fLaunchSpinDelay(100)                          
240   ,fUISceneTreeWidget(NULL)                       
241   ,fUIViewerPropertiesWidget(NULL)                
242   ,fUIPickInfosWidget(NULL)                       
243   ,fNoKeyPress(true)                              
244   ,fAltKeyPress(false)                            
245   ,fControlKeyPress(false)                        
246   ,fShiftKeyPress(false)                          
247   ,fBatchMode(false)                              
248   ,fCheckSceneTreeComponentSignalLock(false)      
249   ,fViewerPropertiesTableWidgetIsInit(false)      
250   ,fSceneTreeComponentTreeWidget(NULL)            
251   ,fSceneTreeWidget(NULL)                         
252   ,fPVRootNodeCreate(false)                       
253   ,fFilterOutput(NULL)                            
254   ,fNbRotation(0)                                 
255   ,fTimeRotation(0)                               
256   ,fTouchableVolumes("Touchables")                
257   ,fShortcutsDialog(NULL)                         
258   ,fViewerPropertiesTableWidget(NULL)             
259   ,fPickInfosWidget(NULL)                         
260   ,fPickInfosScrollArea(NULL)                     
261   ,fTreeWidgetInfosIgnoredCommands(0)             
262   ,fSceneTreeDepthSlider(NULL)                    
263   ,fSceneTreeDepth(1)                             
264   ,fModelShortNameItem(NULL)                      
265   ,fMaxPOindexInserted(-1)                        
266   ,fTreeIconOpen(NULL)                            
267   ,fTreeIconClosed(NULL)                          
268   ,fLastExportSliderValue(80)                     
269   ,fLastHighlightColor(G4Color(0,0,0,0))          
270   ,fLastHighlightName(0)                          
271   ,fIsDeleting(false)                             
272 {                                                 
273   // launch Qt if not                             
274   if (QCoreApplication::instance () == NULL) {    
275     fBatchMode = true;                            
276   }                                               
277   G4Qt::getInstance ();                           
278                                                   
279   fLastPos3 = QPoint(-1,-1);                      
280   fLastPos2 = QPoint(-1,-1);                      
281   fLastPos1 = QPoint(-1,-1);                      
282                                                   
283   initMovieParameters();                          
284                                                   
285 #if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))     
286   fLastEventTime = new QTime();                   
287 #else                                             
288   fLastEventTime = new QElapsedTimer();           
289 #endif                                            
290   // Set default path and format                  
291   fFileSavePath = QDir::currentPath();            
292                                                   
293   // add available export format                  
294   QList<QByteArray> formats =  QImageWriter::s    
295   for (int i = 0; i < formats.size(); ++i) {      
296     addExportImageFormat(formats.at(i).data())    
297   }                                               
298                                                   
299   const char * const icon1[]={                    
300     /* columns rows colors chars-per-pixel */     
301           "20 20 34 1",                           
302      "  c None",                                  
303      ". c #7C7C7C7C7C7C",                         
304      "X c #7D7D7D7D7D7D",                         
305      "o c #828282828282",                         
306      "O c #838383838383",                         
307      "+ c #848484848484",                         
308      "@ c #858585858585",                         
309      "# c #878787878787",                         
310      "$ c #888888888888",                         
311      "% c #8B8B8B8B8B8B",                         
312      "& c #8C8C8C8C8C8C",                         
313      "* c #8F8F8F8F8F8F",                         
314      "= c #909090909090",                         
315      "- c #919191919191",                         
316      "; c #999999999999",                         
317      ": c #9D9D9D9D9D9D",                         
318      "> c #A2A2A2A2A2A2",                         
319      ", c #A3A3A3A3A3A3",                         
320      "< c #A5A5A5A5A5A5",                         
321      "1 c #A6A6A6A6A6A6",                         
322      "2 c #B3B3B3B3B3B3",                         
323      "3 c #B6B6B6B6B6B6",                         
324      "4 c #C2C2C2C2C2C2",                         
325      "5 c #C6C6C6C6C6C6",                         
326      "6 c #CACACACACACA",                         
327      "7 c #CFCFCFCFCFCF",                         
328      "8 c #D0D0D0D0D0D0",                         
329      "9 c #D4D4D4D4D4D4",                         
330      "0 c #D7D7D7D7D7D7",                         
331      "q c #DEDEDEDEDEDE",                         
332      "w c #E0E0E0E0E0E0",                         
333      "e c #E7E7E7E7E7E7",                         
334      "r c #F4F4F4F4F4F4",                         
335      "t c #F7F7F7F7F7F7",                         
336      "                               ",           
337      "                               ",           
338      "                               ",           
339      "                               ",           
340      "                               ",           
341      "                               ",           
342      "    =========>                 ",           
343      "    7&X+++Oo<e                 ",           
344      "     2o+@@+-8                  ",           
345      "     w;.#@+3                   ",           
346      "      4$o@:q                   ",           
347      "      r1X%5                    ",           
348      "       9*,t                    ",           
349      "        60                     ",           
350      "                               ",           
351      "                               ",           
352      "                               ",           
353      "                               ",           
354      "                               ",           
355      "                               "            
356   };                                              
357   const char * const icon2[]={                    
358     "20 20 68 1",                                 
359     "  c None",                                   
360     ". c #5F5F10102323",                          
361     "X c #40405F5F1010",                          
362     "o c #696963632E2E",                          
363     "O c #101019194C4C",                          
364     "+ c #101023237070",                          
365     "@ c #70702D2D6363",                          
366     "# c #73732D2D6464",                          
367     "$ c #79792E2E6767",                          
368     "% c #19194C4C5353",                          
369     "& c #2D2D63636161",                          
370     "* c #2E2E61617070",                          
371     "= c #6F6F6E6E4343",                          
372     "- c #707065655F5F",                          
373     "; c #727279795454",                          
374     ": c #535341417070",                          
375     "> c #797954547979",                          
376     ", c #434361617474",                          
377     "< c #414170707070",                          
378     "1 c #686869696363",                          
379     "2 c #6C6C69696363",                          
380     "3 c #656567676F6F",                          
381     "4 c #69696F6F6E6E",                          
382     "5 c #747465656767",                          
383     "6 c #757562626C6C",                          
384     "7 c #70706C6C6969",                          
385     "8 c #616174746565",                          
386     "9 c #656573736969",                          
387     "0 c #616174746969",                          
388     "q c #707075756262",                          
389     "w c #797970706565",                          
390     "e c #636361617474",                          
391     "r c #67676F6F7272",                          
392     "t c #727261617070",                          
393     "y c #616170707070",                          
394     "u c #6F6F72727979",                          
395     "i c #67676E6ED1D1",                          
396     "p c #808080808080",                          
397     "a c #828282828282",                          
398     "s c #838383838383",                          
399     "d c #848484848484",                          
400     "f c #858585858585",                          
401     "g c #868686868686",                          
402     "h c #888888888888",                          
403     "j c #8A8A8A8A8A8A",                          
404     "k c #8D8D8D8D8D8D",                          
405     "l c #8F8F8F8F8F8F",                          
406     "z c #909090909090",                          
407     "x c #949494949494",                          
408     "c c #9C9C9C9C9C9C",                          
409     "v c #9F9F9F9F9F9F",                          
410     "b c #A2A2A2A2A2A2",                          
411     "n c #AEAEAEAEAEAE",                          
412     "m c #B7B7B7B7B7B7",                          
413     "M c #C7C7C7C7C7C7",                          
414     "N c #C9C9C9C9C9C9",                          
415     "B c #D1D1D1D1D1D1",                          
416     "V c #D4D4D4D4D4D4",                          
417     "C c #D9D9D9D9D9D9",                          
418     "Z c #E0E0E0E0E0E0",                          
419     "A c #E2E2E2E2E2E2",                          
420     "S c #EEEEEEEEEEEE",                          
421     "D c #F0F0F0F0F0F0",                          
422     "F c #F5F5F5F5F5F5",                          
423     "G c #F6F6F6F6F6F6",                          
424     "H c #F9F9F9F9F9F9",                          
425     "J c #FCFCFCFCFCFC",                          
426     "K c #FDFDFDFDFDFD",                          
427     "                    ",                       
428     "                    ",                       
429     "                    ",                       
430     "                    ",                       
431     "                    ",                       
432     "     bC             ",                       
433     "     zjnD           ",                       
434     "     ldjjMK         ",                       
435     "     zdhdjcA        ",                       
436     "     zddhdddVK      ",                       
437     "     zghdalBH       ",                       
438     "     zghamSK        ",                       
439     "     lubZH          ",                       
440     "     xMF            ",                       
441     "     G              ",                       
442     "                    ",                       
443     "                    ",                       
444     "                    ",                       
445     "                    ",                       
446     "                    ",                       
447                                                   
448   };                                              
449                                                   
450   const char * const search[]  = {                
451     /* columns rows colors chars-per-pixel */     
452     "19 19 8 1",                                  
453     "  c #5C5C5C",                                
454     ". c #7D7D7D",                                
455     "X c #9B9B9B",                                
456     "o c #C3C3C3",                                
457     "O c None",                                   
458     "+ c #000000",                                
459     "@ c #000000",                                
460     "# c None",                                   
461     /* pixels */                                  
462     "OOOOOOOOOOOOOOOOOOO",                        
463     "OOOOOOOOOOOOOOOOOOO",                        
464     "OOOOOOOo.  .oOOOOOO",                        
465     "OOOOOOX      XOOOOO",                        
466     "OOOOOo  XOOX  oOOOO",                        
467     "OOOOO. XOOOOX .OOOO",                        
468     "OOOOO  OOOOOO  OOOO",                        
469     "OOOOO  OOOOOO  OOOO",                        
470     "OOOOO. XOOOOo .OOOO",                        
471     "OOOOOo  oOOo  oOOOO",                        
472     "OOOOOOX       XOOOO",                        
473     "OOOOOOOo.  .   XOOO",                        
474     "OOOOOOOOOOOOO.  XOO",                        
475     "OOOOOOOOOOOOOO. XOO",                        
476     "OOOOOOOOOOOOOOOoOOO",                        
477     "OOOOOOOOOOOOOOOOOOO",                        
478     "OOOOOOOOOOOOOOOOOOO",                        
479     "OOOOOOOOOOOOOOOOOOO",                        
480     "OOOOOOOOOOOOOOOOOOO"                         
481   };                                              
482                                                   
483   fSearchIcon = new QPixmap(search);              
484   fTreeIconOpen = new QPixmap(icon1);             
485   fTreeIconClosed = new QPixmap(icon2);           
486                                                   
487 }                                                 
488                                                   
489 //////////////////////////////////////////////    
490 G4OpenGLQtViewer::~G4OpenGLQtViewer (             
491 )                                                 
492 //////////////////////////////////////////////    
493 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!    
494 {                                                 
495   fIsDeleting = true;                             
496                                                   
497   // remove scene tree from layout                
498   // Delete all the existing buttons in the la    
499   QLayoutItem *wItem;                             
500   if (fSceneTreeWidget != NULL) {                 
501     if (fSceneTreeWidget->layout() != NULL) {     
502       while ((wItem = fSceneTreeWidget->layout    
503   delete wItem->widget();                         
504   delete wItem;                                   
505       }                                           
506     }                                             
507   }                                               
508                                                   
509   // Delete the open/close icons                  
510   delete fTreeIconOpen;                           
511   delete fTreeIconClosed;                         
512                                                   
513 #if QT_VERSION < 0x060000                         
514   G4cout <<removeTempFolder().toStdString().c_    
515 #endif                                            
516                                                   
517 }                                                 
518                                                   
519 G4bool G4OpenGLQtViewer::ReadyToDraw() {          
520 #if QT_VERSION < 0x060000                         
521   return true;                                    
522 #else                                             
523   if(!fGLWidget) return false;                    
524   auto* qGLW = dynamic_cast<G4QGLWidgetType*>(    
525   if (!qGLW) return false;                        
526   return qGLW->isValid();                         
527 #endif                                            
528 }                                                 
529                                                   
530 //                                                
531 //   Create a popup menu for the widget. This     
532 //                                                
533 void G4OpenGLQtViewer::createPopupMenu()    {     
534                                                   
535   fContextMenu = new QMenu("All");                
536                                                   
537   QMenu *mMouseAction = fContextMenu->addMenu(    
538   fMouseRotateAction = mMouseAction->addAction    
539   fMouseMoveAction = mMouseAction->addAction("    
540   fMousePickAction = mMouseAction->addAction("    
541   fMouseZoomOutAction = mMouseAction->addActio    
542   fMouseZoomInAction = mMouseAction->addAction    
543   QAction *shortcutsAction = mMouseAction->add    
544                                                   
545   fMouseRotateAction->setCheckable(true);         
546   fMouseMoveAction->setCheckable(true);           
547   fMousePickAction->setCheckable(true);           
548   fMouseZoomOutAction->setCheckable(true);        
549   fMouseZoomInAction->setCheckable(true);         
550   shortcutsAction->setCheckable(false);           
551                                                   
552   QObject::connect(shortcutsAction,               
553                     SIGNAL(triggered(bool)),      
554                     this,                         
555                     SLOT(showShortcuts()));       
556                                                   
557   // === Style Menu ===                           
558   QMenu *mStyle = fContextMenu->addMenu("&Styl    
559                                                   
560   QMenu *mProjection = mStyle->addMenu("&Proje    
561                                                   
562   // no more radioAction, not realy useful and    
563   fProjectionOrtho = mProjection->addAction("O    
564   fProjectionPerspective = mProjection->addAct    
565   // === Drawing Menu ===                         
566   QMenu *mDrawing = mStyle->addMenu("&Drawing"    
567   fDrawingWireframe = mDrawing->addAction("Wir    
568   fDrawingLineRemoval = mDrawing->addAction("H    
569   fDrawingSurfaceRemoval = mDrawing->addAction    
570   fDrawingLineSurfaceRemoval = mDrawing->addAc    
571                                                   
572   fDrawingWireframe->setCheckable(true);          
573   fDrawingLineRemoval->setCheckable(true);        
574   fDrawingSurfaceRemoval->setCheckable(true);     
575   fDrawingLineSurfaceRemoval->setCheckable(tru    
576                                                   
577   // Background Color                             
578                                                   
579   QAction *backgroundColorChooser ;               
580   // === Action Menu ===                          
581   backgroundColorChooser = mStyle->addAction("    
582   QObject ::connect(backgroundColorChooser,       
583                     SIGNAL(triggered()),          
584                     this,                         
585                     SLOT(actionChangeBackgroun    
586                                                   
587   // Text Color                                   
588                                                   
589   QAction *textColorChooser ;                     
590   // === Action Menu ===                          
591   textColorChooser = mStyle->addAction("Text c    
592   QObject ::connect(textColorChooser,             
593                     SIGNAL(triggered()),          
594                     this,                         
595                     SLOT(actionChangeTextColor    
596                                                   
597   // Default Color                                
598                                                   
599   QAction *defaultColorChooser ;                  
600   // === Action Menu ===                          
601   defaultColorChooser = mStyle->addAction("Def    
602   QObject ::connect(defaultColorChooser,          
603                     SIGNAL(triggered()),          
604                     this,                         
605                     SLOT(actionChangeDefaultCo    
606                                                   
607                                                   
608   // === Action Menu ===                          
609   QMenu *mActions = fContextMenu->addMenu("&Ac    
610   QAction *createEPS = mActions->addAction("Sa    
611   QObject ::connect(createEPS,                    
612                     SIGNAL(triggered()),          
613                     this,                         
614                     SLOT(actionSaveImage()));     
615                                                   
616   // === Action Menu ===                          
617   QAction *movieParameters = mActions->addActi    
618   QObject ::connect(movieParameters,              
619                     SIGNAL(triggered()),          
620                     this,                         
621                     SLOT(actionMovieParameters    
622                                                   
623                                                   
624                                                   
625                                                   
626   // === Special Menu ===                         
627   QMenu *mSpecial = fContextMenu->addMenu("S&p    
628   QMenu *mTransparency = mSpecial->addMenu("Tr    
629   QAction *transparencyOn = mTransparency->add    
630   QAction *transparencyOff = mTransparency->ad    
631                                                   
632   if (transparency_enabled == false) {            
633     createRadioAction(transparencyOn,transpare    
634   } else if (transparency_enabled == true) {      
635     createRadioAction(transparencyOn,transpare    
636   } else {                                        
637     mSpecial->clear();                            
638   }                                               
639                                                   
640                                                   
641   QMenu *mAntialiasing = mSpecial->addMenu("An    
642   QAction *antialiasingOn = mAntialiasing->add    
643   QAction *antialiasingOff = mAntialiasing->ad    
644                                                   
645   if (antialiasing_enabled == false) {            
646     createRadioAction(antialiasingOn,antialias    
647   } else if (antialiasing_enabled == true) {      
648     createRadioAction(antialiasingOn,antialias    
649   } else {                                        
650     mAntialiasing->clear();                       
651   }                                               
652                                                   
653   QMenu *mHaloing = mSpecial->addMenu("Haloing    
654   QAction *haloingOn = mHaloing->addAction("On    
655   QAction *haloingOff = mHaloing->addAction("O    
656   if (haloing_enabled == false) {                 
657     createRadioAction(haloingOn,haloingOff,SLO    
658   } else if (haloing_enabled == true) {           
659     createRadioAction(haloingOn,haloingOff,SLO    
660   } else {                                        
661     mHaloing->clear();                            
662   }                                               
663                                                   
664   QMenu *mAux = mSpecial->addMenu("Auxiliary e    
665   QAction *auxOn = mAux->addAction("On");         
666   QAction *auxOff = mAux->addAction("Off");       
667   if (!fVP.IsAuxEdgeVisible()) {                  
668     createRadioAction(auxOn,auxOff,SLOT(toggle    
669   } else {                                        
670     createRadioAction(auxOn,auxOff,SLOT(toggle    
671   }                                               
672                                                   
673                                                   
674   QMenu *mHiddenMarkers = mSpecial->addMenu("H    
675   QAction *hiddenMarkersOn = mHiddenMarkers->a    
676   QAction *hiddenMarkersOff = mHiddenMarkers->    
677   if (fVP.IsMarkerNotHidden()) {                  
678     createRadioAction(hiddenMarkersOn,hiddenMa    
679   } else {                                        
680     createRadioAction(hiddenMarkersOn,hiddenMa    
681   }                                               
682                                                   
683                                                   
684                                                   
685   QMenu *mFullScreen = mSpecial->addMenu("&Ful    
686   fFullScreenOn = mFullScreen->addAction("On")    
687   fFullScreenOff = mFullScreen->addAction("Off    
688   createRadioAction(fFullScreenOn,fFullScreenO    
689                                                   
690   // INIT All                                     
691   updateToolbarAndMouseContextMenu();             
692 }                                                 
693                                                   
694 void G4OpenGLQtViewer::G4manageContextMenuEven    
695 {                                                 
696   if (!fGLWidget) {                               
697     G4cerr << "Visualization window not define    
698   } else {                                        
699                                                   
700     if (!fContextMenu)                            
701       createPopupMenu();                          
702                                                   
703     // launch menu                                
704     if ( fContextMenu ) {                         
705       fContextMenu->exec( e->globalPos() );       
706       //    delete fContextMenu;                  
707     }                                             
708   }                                               
709   e->accept();                                    
710 }                                                 
711                                                   
712                                                   
713 /**                                               
714    Create a radio button menu. The two menu wi    
715    eatch state will be invert and callback met    
716    @param action1 first action to connect         
717    @param action2 second action to connect        
718    @param method callback method                  
719    @param nCheck: 1 : first action will be set    
720 */                                                
721 void G4OpenGLQtViewer::createRadioAction(QActi    
722                                                   
723   action1->setCheckable(true);                    
724   action2->setCheckable(true);                    
725                                                   
726   if (nCheck ==1)                                 
727     action1->setChecked (true);                   
728   else                                            
729     action2->setChecked (true);                   
730                                                   
731   QObject ::connect(action1, SIGNAL(triggered(    
732   QObject ::connect(action2, SIGNAL(triggered(    
733                                                   
734   QObject ::connect(action1, SIGNAL(toggled(bo    
735                                                   
736 }                                                 
737                                                   
738                                                   
739                                                   
740 /**                                               
741    Show shortcuts for this mouse action           
742 */                                                
743 void G4OpenGLQtViewer::showShortcuts() {          
744   G4String text;                                  
745                                                   
746   text = "========= Mouse Shortcuts =========\    
747   if (fUiQt != NULL) {                            
748     if (fUiQt->IsIconRotateSelected()) {  // r    
749       text += "Click and move mouse to rotate     
750       text += "ALT + Click and move mouse to r    
751       text += "CTRL + Click and move mouse to     
752       text += "SHIFT + Click and move mouse to    
753     } else  if (fUiQt->IsIconMoveSelected()) {    
754       text += "Move camera point of view with     
755     } else  if (fUiQt->IsIconPickSelected()) {    
756       text += "Click and pick \n";                
757     }                                             
758   } else {                                        
759     text += "Click and move mouse to rotate vo    
760     text += "ALT + Click and move mouse to rot    
761     text += "CTRL + Click and zoom mouse to zo    
762     text += "SHIFT + Click and zoommove camera    
763   }                                               
764   text += "========= Move Shortcuts =========     
765   text += "Press left/right arrows to move vol    
766   text += "Press up/down arrows to move volume    
767   text += "Press '+'/'-' to move volume toward    
768   text += "\n";                                   
769   text += "========= Rotation (Theta/Phi) Shor    
770   text += "Press SHIFT + left/right arrows to     
771   text += "Press SHIFT + up/down arrows to rot    
772   text += "\n";                                   
773   text += "========= Rotation (View Direction)    
774   text += "Press ALT + left/right to rotate vo    
775   text += "Press ALT + up/down to rotate volum    
776   text += "\n";                                   
777   text += "========= Zoom View ========= \n";     
778   text += "Press CTRL + '+'/'-' to zoom into v    
779   text += "\n";                                   
780   text += "========= Misc ========= \n";          
781   text += "Press ALT +/- to slow/speed rotatio    
782   text += "Press H to reset view \n";             
783   text += "Press Esc to exit FullScreen \n";      
784   text += "\n";                                   
785   text += "========= Video ========= \n";         
786   text += "In video mode : \n";                   
787   text += " Press SPACE to Start/Pause video r    
788   text += " Press RETURN to Stop video recordi    
789   text += "\n";                                   
790                                                   
791   G4cout << text;                                 
792                                                   
793   if (  fShortcutsDialog == NULL) {               
794     fShortcutsDialog = new QDialog();             
795     fShortcutsDialogInfos = new QTextEdit() ;     
796     QVBoxLayout *mainLayout = new QVBoxLayout;    
797     mainLayout->addWidget(fShortcutsDialogInfo    
798     fShortcutsDialog->setLayout(mainLayout);      
799     fShortcutsDialog->setWindowTitle(tr("Short    
800   }                                               
801                                                   
802   fShortcutsDialogInfos->setPlainText(text.dat    
803   fShortcutsDialog->show();                       
804 }                                                 
805                                                   
806                                                   
807                                                   
808 /**                                               
809    Slot activated when mouse action is toggle     
810    @param aAction : 1 rotate, 2 move, 3 pick,     
811    @see G4OpenGLStoredQtViewer::DrawView          
812    @see G4XXXStoredViewer::CompareForKernelVis    
813 */                                                
814 void G4OpenGLQtViewer::toggleMouseAction(int a    
815                                                   
816   if (aAction == 1) {                             
817     fUiQt->SetIconRotateSelected();               
818   } else  if (aAction == 2) {                     
819     fUiQt->SetIconMoveSelected();                 
820   } else  if (aAction == 3) {                     
821     togglePicking();                              
822   } else  if (aAction == 4) {                     
823     fUiQt->SetIconZoomOutSelected();              
824   } else  if (aAction == 5) {                     
825     fUiQt->SetIconZoomInSelected();               
826   }                                               
827                                                   
828   updateQWidget();                                
829   updateToolbarAndMouseContextMenu();             
830 }                                                 
831                                                   
832                                                   
833 /**                                               
834    Slot activated when drawing menu is toggle     
835    Warning : When G4OpenGLStoredQtViewer::Draw    
836    KernelVisitDecision () will be call and wil    
837    to 1. See G4XXXStoredViewer::CompareForKern    
838    It will cause a redraw of the view             
839    @param aAction : 1 wireframe, 2 line remova    
840    @see G4OpenGLStoredQtViewer::DrawView          
841    @see G4XXXStoredViewer::CompareForKernelVis    
842 */                                                
843 void G4OpenGLQtViewer::toggleSurfaceAction(int    
844                                                   
845   G4ViewParameters::DrawingStyle d_style = G4V    
846                                                   
847   if (aAction ==1) {                              
848     d_style = G4ViewParameters::wireframe;        
849                                                   
850   } else  if (aAction ==2) {                      
851     d_style = G4ViewParameters::hlr;              
852                                                   
853   } else  if (aAction ==3) {                      
854     d_style = G4ViewParameters::hsr;              
855                                                   
856   } else  if (aAction ==4) {                      
857     d_style = G4ViewParameters::hlhsr;            
858   }                                               
859   fVP.SetDrawingStyle(d_style);                   
860                                                   
861   updateToolbarAndMouseContextMenu();             
862   updateQWidget();                                
863 }                                                 
864                                                   
865                                                   
866 /**                                               
867    SLOT Activate by a click on the projection     
868    Warning : When G4OpenGLStoredQtViewer::Draw    
869    KernelVisitDecision () will be call and wil    
870    to 1. See G4XXXStoredViewer::CompareForKern    
871    It will cause a redraw of the view             
872    @param check : 1 orthographic, 2 perspectiv    
873    @see G4OpenGLStoredQtViewer::DrawView          
874    @see G4XXXStoredViewer::CompareForKernelVis    
875 */                                                
876 void G4OpenGLQtViewer::toggleProjection(bool c    
877                                                   
878   if (check) {                                    
879     fVP.SetOrthogonalProjection ();               
880   } else {                                        
881     fVP.SetPerspectiveProjection();               
882   }                                               
883   updateToolbarAndMouseContextMenu();             
884   updateQWidget();                                
885 }                                                 
886                                                   
887                                                   
888 /**                                               
889    SLOT Activate by a click on the transparenc    
890    @param check : 1 , 0                           
891 */                                                
892 void G4OpenGLQtViewer::toggleTransparency(bool    
893                                                   
894   if (check) {                                    
895     transparency_enabled = true;                  
896   } else {                                        
897     transparency_enabled = false;                 
898   }                                               
899   SetNeedKernelVisit (true);                      
900   updateToolbarAndMouseContextMenu();             
901   updateQWidget();                                
902 }                                                 
903                                                   
904 /**                                               
905    SLOT Activate by a click on the antialiasin    
906    @param check : 1 , 0                           
907 */                                                
908 void G4OpenGLQtViewer::toggleAntialiasing(bool    
909                                                   
910   if (!check) {                                   
911     antialiasing_enabled = false;                 
912     glDisable (GL_LINE_SMOOTH);                   
913     glDisable (GL_POLYGON_SMOOTH);                
914   } else {                                        
915     antialiasing_enabled = true;                  
916     glEnable (GL_LINE_SMOOTH);                    
917     glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);      
918     glEnable (GL_POLYGON_SMOOTH);                 
919     glHint (GL_POLYGON_SMOOTH_HINT, GL_NICEST)    
920   }                                               
921                                                   
922   updateToolbarAndMouseContextMenu();             
923   updateQWidget();                                
924 }                                                 
925                                                   
926 /**                                               
927    SLOT Activate by a click on the haloing men    
928    @param check : 1 , 0                           
929 */                                                
930 //FIXME : I SEE NOTHING...                        
931 void G4OpenGLQtViewer::toggleHaloing(bool chec    
932   if (check) {                                    
933     haloing_enabled = false;                      
934   } else {                                        
935     haloing_enabled = true;                       
936   }                                               
937                                                   
938   updateToolbarAndMouseContextMenu();             
939   updateQWidget();                                
940                                                   
941 }                                                 
942                                                   
943 /**                                               
944    SLOT Activate by a click on the auxiliaire     
945    @param check : 1 , 0                           
946 */                                                
947 void G4OpenGLQtViewer::toggleAux(bool check) {    
948   if (check) {                                    
949     fVP.SetAuxEdgeVisible(true);                  
950   } else {                                        
951     fVP.SetAuxEdgeVisible(false);                 
952   }                                               
953   SetNeedKernelVisit (true);                      
954   updateToolbarAndMouseContextMenu();             
955   updateQWidget();                                
956 }                                                 
957                                                   
958                                                   
959 void G4OpenGLQtViewer::togglePicking() {          
960   // FIXME : Not the good way to do, we should    
961   if (fUiQt) {                                    
962     if (!fVP.IsPicking()) {                       
963       fUiQt->SetIconPickSelected();               
964     } else {                                      
965       fUiQt->SetIconRotateSelected();             
966     }                                             
967   }                                               
968                                                   
969   G4UImanager* UI = G4UImanager::GetUIpointer(    
970   if(UI != NULL)  {                               
971     if (!fVP.IsPicking()) {                       
972       UI->ApplyCommand(std::string("/vis/viewe    
973     } else {                                      
974       UI->ApplyCommand(std::string("/vis/viewe    
975     }                                             
976   }                                               
977                                                   
978 }                                                 
979                                                   
980                                                   
981 /**                                               
982    SLOT Activate by a click on the hidden mark    
983    @param check : 1 , 0                           
984 */                                                
985 void G4OpenGLQtViewer::toggleHiddenMarkers(boo    
986   if (check) {                                    
987     fVP.SetMarkerHidden();                        
988   } else {                                        
989     fVP.SetMarkerNotHidden();                     
990   }                                               
991   //  SetNeedKernelVisit (true);                  
992   updateToolbarAndMouseContextMenu();             
993   updateQWidget();                                
994 }                                                 
995                                                   
996 /**                                               
997    SLOT Activate by a click on the full screen    
998 */                                                
999 void G4OpenGLQtViewer::toggleFullScreen(bool c    
1000   if (check != fGLWidget->isFullScreen()) { /    
1001     fGLWidget->setWindowState(fGLWidget->wind    
1002   }                                              
1003 }                                                
1004                                                  
1005                                                  
1006 void G4OpenGLQtViewer::savePPMToTemp() {         
1007   if (fMovieTempFolderPath == "") {              
1008     return;                                      
1009   }                                              
1010   auto qGLW = dynamic_cast<G4QGLWidgetType*>     
1011   if (! qGLW) {                                  
1012     return;                                      
1013   }                                              
1014   QString fileName ="Test"+QString::number(fR    
1015   QString filePath =fMovieTempFolderPath+file    
1016                                                  
1017   QImage image;                                  
1018 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))     
1019   image = qGLW->grabFrameBuffer();               
1020 #else                                            
1021   image = qGLW->grabFramebuffer();               
1022 #endif                                           
1023   bool res = false;                              
1024                                                  
1025   res = image.save(filePath,0);                  
1026   if (res == false) {                            
1027     resetRecording();                            
1028     setRecordingInfos("Can't save tmp file "+    
1029     return;                                      
1030   }                                              
1031                                                  
1032   setRecordingInfos("File "+fileName+" saved"    
1033   fRecordFrameNumber++;                          
1034 }                                                
1035                                                  
1036                                                  
1037                                                  
1038 void G4OpenGLQtViewer::actionSaveImage() {       
1039   QString filters;                               
1040   for (unsigned int i = 0; i < fExportImageFo    
1041     filters += QString("*.") + fExportImageFo    
1042   }                                              
1043                                                  
1044   QString* selectedFormat = new QString(fDefa    
1045   QString qFilename;                             
1046   qFilename =  QFileDialog::getSaveFileName (    
1047                                          tr("    
1048                                          fFil    
1049                                          filt    
1050                                          sele    
1051                                                  
1052                                                  
1053   std::string name = qFilename.toStdString().    
1054                                                  
1055   // bmp jpg jpeg png ppm xbm xpm                
1056   if (name.empty()) {                            
1057     return;                                      
1058   }                                              
1059                                                  
1060   fFileSavePath = QFileInfo(qFilename).path()    
1061                                                  
1062   std::string format = selectedFormat->toLowe    
1063                                                  
1064   // set the format to current                   
1065   fExportImageFormat = format.substr(format.f    
1066                                                  
1067   std::string filename = name;                   
1068   std::string extension = "";                    
1069   if (name.find_last_of(".") != std::string::    
1070     filename = name.substr(0,name.find_last_o    
1071     extension = name.substr(name.find_last_of    
1072   } else {                                       
1073     extension = fExportImageFormat;              
1074   }                                              
1075                                                  
1076   filename+= "."+ extension;                     
1077                                                  
1078   if (!setExportFilename(filename.c_str(),0))    
1079     return;                                      
1080   }                                              
1081                                                  
1082   G4OpenGLQtExportDialog* exportDialog= new G    
1083   if(  exportDialog->exec()) {                   
1084                                                  
1085     if ((exportDialog->getWidth() !=fGLWidget    
1086         (exportDialog->getHeight() !=fGLWidge    
1087       setExportSize(exportDialog->getWidth(),    
1088                                                  
1089     }                                            
1090     if (fExportImageFormat == "eps") {           
1091       fVectoredPs = exportDialog->getVectorEP    
1092     } else if (fExportImageFormat == "ps") {     
1093       fVectoredPs = true;                        
1094     }                                            
1095     fLastExportSliderValue = exportDialog->ge    
1096                                                  
1097     if (exportImage(filename)) {                 
1098       // set the default format to current       
1099       fDefaultExportImageFormat = format;        
1100     }                                            
1101   } else { // cancel selected                    
1102     return;                                      
1103   }                                              
1104                                                  
1105 }                                                
1106                                                  
1107                                                  
1108 void G4OpenGLQtViewer::actionChangeBackground    
1109                                                  
1110   //   //I need to revisit the kernel if the     
1111   //   //hidden line removal is enabled, beca    
1112   //   //background colour in its drawing...     
1113   //   // (Note added by JA 13/9/2005) Backgr    
1114   //   // parameters.  A kernel visit is trig    
1115   const QColor color =                           
1116     QColorDialog::getColor(Qt::black,            
1117                            fGLWidget,            
1118                            " Get background c    
1119                            QColorDialog::Show    
1120   if (color.isValid()) {                         
1121     G4Colour colour(((G4double)color.red())/2    
1122                     ((G4double)color.green())    
1123                     ((G4double)color.blue())/    
1124                     ((G4double)color.alpha())    
1125     fVP.SetBackgroundColour(colour);             
1126                                                  
1127     updateToolbarAndMouseContextMenu();          
1128     updateQWidget();                             
1129   }                                              
1130 }                                                
1131                                                  
1132 void G4OpenGLQtViewer::actionChangeTextColor(    
1133   const QColor& color =                          
1134     QColorDialog::getColor(Qt::yellow,           
1135                            fGLWidget,            
1136                            " Get text color a    
1137                            QColorDialog::Show    
1138   if (color.isValid()) {                         
1139     G4Colour colour(((G4double)color.red())/2    
1140                     ((G4double)color.green())    
1141                     ((G4double)color.blue())/    
1142                     ((G4double)color.alpha())    
1143                                                  
1144     fVP.SetDefaultTextColour(colour);            
1145                                                  
1146     updateToolbarAndMouseContextMenu();          
1147     updateQWidget();                             
1148   }                                              
1149 }                                                
1150                                                  
1151 void G4OpenGLQtViewer::actionChangeDefaultCol    
1152   const QColor& color =                          
1153     QColorDialog::getColor(Qt::white,            
1154                            fGLWidget,            
1155                            " Get default colo    
1156                            QColorDialog::Show    
1157   if (color.isValid()) {                         
1158     G4Colour colour(((G4double)color.red())/2    
1159                     ((G4double)color.green())    
1160                     ((G4double)color.blue())/    
1161                     ((G4double)color.alpha())    
1162                                                  
1163     fVP.SetDefaultColour(colour);                
1164                                                  
1165     updateToolbarAndMouseContextMenu();          
1166     updateQWidget();                             
1167   }                                              
1168 }                                                
1169                                                  
1170                                                  
1171 void G4OpenGLQtViewer::actionMovieParameters(    
1172   showMovieParametersDialog();                   
1173 }                                                
1174                                                  
1175                                                  
1176 void G4OpenGLQtViewer::showMovieParametersDia    
1177   if (!fMovieParametersDialog) {                 
1178     fMovieParametersDialog= new G4OpenGLQtMov    
1179     displayRecordingStatus();                    
1180     fMovieParametersDialog->checkEncoderSwPar    
1181     fMovieParametersDialog->checkSaveFileName    
1182     fMovieParametersDialog->checkTempFolderPa    
1183     if (getEncoderPath() == "") {                
1184       setRecordingInfos("ppmtompeg is needed     
1185     }                                            
1186   }                                              
1187   fMovieParametersDialog->show();                
1188 }                                                
1189                                                  
1190                                                  
1191                                                  
1192 void G4OpenGLQtViewer::FinishView()              
1193 {                                                
1194  /* From Apple doc:                              
1195   CGLFlushDrawable : Copies the back buffer o    
1196   If the backing store attribute is set to fa    
1197  */                                              
1198   glFlush ();                                    
1199                                                  
1200   // L. Garnier 10/2009 : Not necessary and c    
1201   //  fGLWidget->swapBuffers ();                 
1202 }                                                
1203                                                  
1204 /**                                              
1205    Save the current mouse press point            
1206    @param p mouse click point                    
1207 */                                               
1208 void G4OpenGLQtViewer::G4MousePressEvent(QMou    
1209 {                                                
1210   if (evnt->button() == Qt::RightButton) {       
1211     return;                                      
1212   }                                              
1213   if ((evnt->button() & Qt::LeftButton) && (!    
1214     fGLWidget->setMouseTracking(true);           
1215     fAutoMove = false; // stop automove          
1216     fLastPos1 = evnt->pos();                     
1217     fLastPos2 = fLastPos1;                       
1218     fLastPos3 = fLastPos2;                       
1219     fLastEventTime->start();                     
1220     if (fUiQt != NULL) {                         
1221                                                  
1222       if (fUiQt->IsIconZoomInSelected()) {  /    
1223         // Move click point to center of OGL     
1224                                                  
1225         float deltaX = ((float)getWinWidth()/    
1226         float deltaY = ((float)getWinHeight()    
1227                                                  
1228         G4double coefTrans = 0;                  
1229         coefTrans = ((G4double)getSceneNearWi    
1230         if (getWinHeight() <getWinWidth()) {     
1231           coefTrans = ((G4double)getSceneNear    
1232         }                                        
1233         fVP.IncrementPan(-deltaX*coefTrans,de    
1234         fVP.SetZoomFactor(1.5 * fVP.GetZoomFa    
1235                                                  
1236         updateQWidget();                         
1237                                                  
1238       } else if (fUiQt->IsIconZoomOutSelected    
1239         // Move click point to center of OGL     
1240         moveScene(((float)getWinWidth()/2-evn    
1241                                                  
1242         fVP.SetZoomFactor(0.75 * fVP.GetZoomF    
1243         updateQWidget();                         
1244                                                  
1245       } else if (fUiQt->IsIconRotateSelected(    
1246                                                  
1247         if (fShiftKeyPress) { // move            
1248           fGLWidget->setCursor(QCursor(Qt::Si    
1249                                                  
1250         } else {  // rotate                      
1251           fGLWidget->setCursor(QCursor(Qt::Cl    
1252         }                                        
1253       } else if (fUiQt->IsIconMoveSelected())    
1254         fGLWidget->setCursor(QCursor(Qt::Size    
1255       } else if (fUiQt->IsIconPickSelected())    
1256         fGLWidget->setCursor(QCursor(Qt::Poin    
1257       }                                          
1258     }                                            
1259   }                                              
1260 }                                                
1261                                                  
1262 /**                                              
1263  */                                              
1264 void G4OpenGLQtViewer::G4MouseReleaseEvent(QM    
1265 {                                                
1266 #if QT_VERSION < 0x060000                        
1267 #else                                            
1268  {auto* qGLW = dynamic_cast<G4QGLWidgetType*>    
1269   if (qGLW) qGLW->makeCurrent();}                
1270   ResizeGLView();                                
1271 #endif                                           
1272   GLint viewport[4];                             
1273   glGetIntegerv(GL_VIEWPORT, viewport);          
1274                                                  
1275   // factorX == factorY                          
1276   double factorX =  ((double)viewport[2]/fGLW    
1277   double factorY =  ((double)viewport[3]/fGLW    
1278   fSpinningDelay = (int)fLastEventTime->elaps    
1279   QPoint delta = (fLastPos3-fLastPos1)*factor    
1280                                                  
1281   // reset cursor state                          
1282   fGLWidget->setCursor(QCursor(Qt::ArrowCurso    
1283                                                  
1284   if (fVP.IsPicking()){  // pick                 
1285     if ((delta.x() != 0) || (delta.y() != 0))    
1286       return;                                    
1287     }                                            
1288     updatePickInfosWidget(evnt->pos().x()*fac    
1289                                                  
1290   } else if (fSpinningDelay < fLaunchSpinDela    
1291     if ((delta.x() == 0) && (delta.y() == 0))    
1292       return;                                    
1293     }                                            
1294                                                  
1295     fAutoMove = true;                            
1296 #if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))    
1297     QTime lastMoveTime;                          
1298 #else                                            
1299     QElapsedTimer lastMoveTime;                  
1300 #endif                                           
1301     lastMoveTime.start();                        
1302     // try to addapt speed move/rotate lookin    
1303     float correctionFactor = 5;                  
1304     while (fAutoMove) {                          
1305       if ( lastMoveTime.elapsed() >= (int)(10    
1306         float lTime = 1000.0f/lastMoveTime.el    
1307         if (((((float)delta.x())/correctionFa    
1308             ((((float)delta.x())/correctionFa    
1309           correctionFactor = (float)delta.x()    
1310           if (delta.x() <0 ) {                   
1311             correctionFactor = -correctionFac    
1312           }                                      
1313         }                                        
1314         if (((((float)delta.y())/correctionFa    
1315             ((((float)delta.y())/correctionFa    
1316           correctionFactor = (float)delta.y()    
1317           if (delta.y() <0 ) {                   
1318             correctionFactor = -correctionFac    
1319           }                                      
1320         }                                        
1321                                                  
1322         // Check Qt Versions for META Keys       
1323                                                  
1324         // Click and move mouse to rotate vol    
1325         // ALT + Click and move mouse to rota    
1326         // SHIFT + Click and move camera poin    
1327         // CTRL + Click and zoom mouse to zoo    
1328                                                  
1329         lastMoveTime.start();                    
1330                                                  
1331         bool rotate = false;                     
1332         bool move = false;                       
1333                                                  
1334         if (fUiQt != NULL) {                     
1335           if (fUiQt->IsIconRotateSelected())     
1336             rotate = true;                       
1337           } else if (fUiQt->IsIconMoveSelecte    
1338             move = true;                         
1339           }                                      
1340         } else {                                 
1341           rotate = true;                         
1342         }                                        
1343         // prevent from closing widget when r    
1344         if (fIsDeleting) {                       
1345           return;                                
1346         }                                        
1347                                                  
1348         if (rotate) {  // rotate                 
1349           if (fNoKeyPress) {                     
1350             rotateQtScene(((float)delta.x())/    
1351           } else if (fAltKeyPress) {             
1352             rotateQtSceneToggle(((float)delta    
1353           }                                      
1354                                                  
1355         } else if (move) {  // move              
1356           moveScene(-((float)delta.x())/corre    
1357         }                                        
1358       }                                          
1359       ((QApplication*)G4Qt::getInstance ())->    
1360     }                                            
1361   }                                              
1362   fGLWidget->setMouseTracking(false);            
1363                                                  
1364 }                                                
1365                                                  
1366                                                  
1367 void G4OpenGLQtViewer::G4MouseDoubleClickEven    
1368 {                                                
1369   fGLWidget->setMouseTracking(true);             
1370 }                                                
1371                                                  
1372                                                  
1373 /**                                              
1374    @param pos_x mouse x position                 
1375    @param pos_y mouse y position                 
1376    @param mButtons mouse button active           
1377    @param mAutoMove true: apply this move til    
1378 */                                               
1379                                                  
1380 void G4OpenGLQtViewer::G4MouseMoveEvent(QMous    
1381 {                                                
1382                                                  
1383   Qt::MouseButtons mButtons = evnt->buttons()    
1384                                                  
1385   updateKeyModifierState(evnt->modifiers());     
1386                                                  
1387   if (fAutoMove) {                               
1388     return;                                      
1389   }                                              
1390                                                  
1391   fLastPos3 = fLastPos2;                         
1392   fLastPos2 = fLastPos1;                         
1393                                                  
1394 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))     
1395   fLastPos1 = QPoint(evnt->x(), evnt->y());      
1396 #else                                            
1397   fLastPos1 = QPoint(evnt->position().x(), ev    
1398 #endif                                           
1399                                                  
1400   int deltaX = fLastPos2.x()-fLastPos1.x();      
1401   int deltaY = fLastPos2.y()-fLastPos1.y();      
1402                                                  
1403   bool move = false;                             
1404   if (fUiQt != NULL) {                           
1405     if (fUiQt->IsIconMoveSelected()) {  // mo    
1406       move = true;                               
1407     }                                            
1408   }                                              
1409   if (!move) {  // rotate, pick, zoom...         
1410     if (mButtons & Qt::LeftButton) {             
1411       if (fNoKeyPress) {                         
1412         rotateQtScene(((float)deltaX),((float    
1413       } else if (fAltKeyPress) {                 
1414         rotateQtSceneToggle(((float)deltaX),(    
1415       } else if (fShiftKeyPress) {               
1416         unsigned int sizeWin;                    
1417         sizeWin = getWinWidth();                 
1418         if (getWinHeight() < getWinWidth()) {    
1419           sizeWin = getWinHeight();              
1420         }                                        
1421                                                  
1422         // L.Garnier : 08/2010 100 is the goo    
1423         float factor = ((float)100/(float)siz    
1424         moveScene(-(float)deltaX*factor,-(flo    
1425       } else if (fControlKeyPress) {             
1426         fVP.SetZoomFactor(fVP.GetZoomFactor()    
1427       }                                          
1428     }                                            
1429   } else if (move) {  // move                    
1430     if (mButtons & Qt::LeftButton) {             
1431       moveScene(-(float)deltaX,-(float)deltaY    
1432     }                                            
1433   }                                              
1434                                                  
1435   fLastEventTime->start();                       
1436 }                                                
1437                                                  
1438                                                  
1439 /**                                              
1440    Move the scene of dx, dy, dz values.          
1441    @param dx delta mouse x position              
1442    @param dy delta mouse y position              
1443    @param mouseMove : true if event comes fro    
1444 */                                               
1445                                                  
1446 void G4OpenGLQtViewer::moveScene(float dx,flo    
1447 {                                                
1448   if (fHoldMoveEvent)                            
1449     return;                                      
1450   fHoldMoveEvent = true;                         
1451                                                  
1452   G4double coefTrans = 0;                        
1453   GLdouble coefDepth = 0;                        
1454   if(mouseMove) {                                
1455     coefTrans = ((G4double)getSceneNearWidth(    
1456     if (getWinHeight() <getWinWidth()) {         
1457       coefTrans = ((G4double)getSceneNearWidt    
1458     }                                            
1459   } else {                                       
1460     coefTrans = getSceneNearWidth()*fPan_sens    
1461     coefDepth = getSceneDepth()*fDeltaDepth;     
1462   }                                              
1463   fVP.IncrementPan(-dx*coefTrans,dy*coefTrans    
1464                                                  
1465   updateQWidget();                               
1466   if (fAutoMove)                                 
1467     ((QApplication*)G4Qt::getInstance ())->pr    
1468                                                  
1469   fHoldMoveEvent = false;                        
1470 }                                                
1471                                                  
1472                                                  
1473 /**                                              
1474    @param dx delta mouse x position              
1475    @param dy delta mouse y position              
1476 */                                               
1477                                                  
1478 void G4OpenGLQtViewer::rotateQtScene(float dx    
1479 {                                                
1480   if (fHoldRotateEvent)                          
1481     return;                                      
1482   fHoldRotateEvent = true;                       
1483                                                  
1484   rotateScene(dx,dy);                            
1485                                                  
1486   updateQWidget();                               
1487                                                  
1488   fHoldRotateEvent = false;                      
1489 }                                                
1490                                                  
1491 /**                                              
1492    @param dx delta mouse x position              
1493    @param dy delta mouse y position              
1494 */                                               
1495                                                  
1496 void G4OpenGLQtViewer::rotateQtSceneToggle(fl    
1497 {                                                
1498   if (fHoldRotateEvent)                          
1499     return;                                      
1500   fHoldRotateEvent = true;                       
1501                                                  
1502   rotateSceneToggle(dx,dy);                      
1503                                                  
1504   updateQWidget();                               
1505                                                  
1506   fHoldRotateEvent = false;                      
1507 }                                                
1508                                                  
1509                                                  
1510                                                  
1511                                                  
1512                                                  
1513 /** This is the benning of a rescale function    
1514     @param aWidth : new width                    
1515     @param aHeight : new height                  
1516 */                                               
1517 void G4OpenGLQtViewer::rescaleImage(             
1518  int /* aWidth */                                
1519 ,int /* aHeight */                               
1520 ){                                               
1521   //  GLfloat* feedback_buffer;                  
1522   //  GLint returned;                            
1523   //  FILE* file;                                
1524                                                  
1525   //   feedback_buffer = new GLfloat[size];      
1526   //   glFeedbackBuffer (size, GL_3D_COLOR, f    
1527   //   glRenderMode (GL_FEEDBACK);               
1528                                                  
1529   //   DrawView();                               
1530   //   returned = glRenderMode (GL_RENDER);      
1531                                                  
1532 }                                                
1533                                                  
1534                                                  
1535                                                  
1536                                                  
1537 void G4OpenGLQtViewer::G4wheelEvent (QWheelEv    
1538 {                                                
1539 #if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))    
1540   fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.    
1541 #else                                            
1542   fVP.SetZoomFactor(fVP.GetZoomFactor()+(fVP.    
1543 #endif                                           
1544   updateQWidget();                               
1545 }                                                
1546                                                  
1547                                                  
1548 void G4OpenGLQtViewer::G4keyPressEvent (QKeyE    
1549 {                                                
1550   if (fHoldKeyEvent)                             
1551     return;                                      
1552                                                  
1553   fHoldKeyEvent = true;                          
1554                                                  
1555                                                  
1556   // with no modifiers                           
1557   updateKeyModifierState(evnt->modifiers());     
1558   if ((fNoKeyPress) || (evnt->modifiers() ==     
1559     if (evnt->key() == Qt::Key_Down) { // go     
1560       moveScene(0,1,0,false);                    
1561     }                                            
1562     else if (evnt->key() == Qt::Key_Up) {  //    
1563       moveScene(0,-1,0,false);                   
1564     }                                            
1565     if (evnt->key() == Qt::Key_Left) { // go     
1566       moveScene(-1,0,0,false);                   
1567     }                                            
1568     else if (evnt->key() == Qt::Key_Right) {     
1569       moveScene(1,0,0,false);                    
1570     }                                            
1571     if (evnt->key() == Qt::Key_Minus) { // go    
1572       moveScene(0,0,1,false);                    
1573     }                                            
1574     else if (evnt->key() == Qt::Key_Plus) { /    
1575       moveScene(0,0,-1,false);                   
1576     }                                            
1577     // escaped from full screen                  
1578     if (evnt->key() == Qt::Key_Escape) {         
1579       toggleFullScreen(false);                   
1580     }                                            
1581   }                                              
1582   // several case here : If return is pressed    
1583   // If one parameter is wrong -> put it in r    
1584   // If encoder not found-> does nothing.Only    
1585   // If all ok-> generate parameter file         
1586   // If ok -> put encoder button enabled         
1587                                                  
1588   if ((evnt->key() == Qt::Key_Return) || (evn    
1589     stopVideo();                                 
1590   }                                              
1591   if (evnt->key() == Qt::Key_Space){ // start    
1592     startPauseVideo();                           
1593   }                                              
1594                                                  
1595   // H : Return Home view                        
1596   if (evnt->key() == Qt::Key_H){ // go Home      
1597     ResetView();                                 
1598                                                  
1599     updateQWidget();                             
1600   }                                              
1601                                                  
1602   // Shift Modifier                              
1603   if (fShiftKeyPress) {                          
1604     fGLWidget->setCursor(QCursor(Qt::SizeAllC    
1605                                                  
1606     if (evnt->key() == Qt::Key_Down) { // rot    
1607       rotateQtScene(0,-fRot_sens);               
1608     }                                            
1609     else if (evnt->key() == Qt::Key_Up) { //     
1610       rotateQtScene(0,fRot_sens);                
1611     }                                            
1612     if (evnt->key() == Qt::Key_Left) { // rot    
1613       rotateQtScene(fRot_sens,0);                
1614     }                                            
1615     else if (evnt->key() == Qt::Key_Right) {     
1616       rotateQtScene(-fRot_sens,0);               
1617     }                                            
1618     if (evnt->key() == Qt::Key_Plus) { // go     
1619       // "Shift" on Mac French keyboard          
1620       moveScene(0,0,-1,false);                   
1621     }                                            
1622                                                  
1623     // Alt Modifier                              
1624   }                                              
1625   if ((fAltKeyPress)) {                          
1626     fGLWidget->setCursor(QCursor(Qt::ClosedHa    
1627                                                  
1628     if (evnt->key() == Qt::Key_Down) { // rot    
1629       rotateQtSceneToggle(0,-fRot_sens);         
1630     }                                            
1631     else if (evnt->key() == Qt::Key_Up) { //     
1632       rotateQtSceneToggle(0,fRot_sens);          
1633     }                                            
1634     if (evnt->key() == Qt::Key_Left) { // rot    
1635       rotateQtSceneToggle(fRot_sens,0);          
1636     }                                            
1637     else if (evnt->key() == Qt::Key_Right) {     
1638       rotateQtSceneToggle(-fRot_sens,0);         
1639     }                                            
1640                                                  
1641     // Rotatio +/-                               
1642     if (evnt->key() == Qt::Key_Plus) {           
1643       fRot_sens = fRot_sens/0.7;                 
1644       G4cout << "Auto-rotation set to : " <<     
1645     }                                            
1646     else if (evnt->key() == Qt::Key_Minus) {     
1647       fRot_sens = fRot_sens*0.7;                 
1648       G4cout << "Auto-rotation set to : " <<     
1649     }                                            
1650                                                  
1651     // Control Modifier OR Command on MAC        
1652   }                                              
1653   if ((fControlKeyPress)) {                      
1654     if (evnt->key() == Qt::Key_Plus) {           
1655       fVP.SetZoomFactor(fVP.GetZoomFactor()*(    
1656       updateQWidget();                           
1657     }                                            
1658     else if (evnt->key() == Qt::Key_Minus) {     
1659       fVP.SetZoomFactor(fVP.GetZoomFactor()*(    
1660       updateQWidget();                           
1661     }                                            
1662   }                                              
1663                                                  
1664   fHoldKeyEvent = false;                         
1665 }                                                
1666                                                  
1667                                                  
1668 void G4OpenGLQtViewer::G4keyReleaseEvent (QKe    
1669 {                                                
1670   fGLWidget->setCursor(QCursor(Qt::ArrowCurso    
1671 }                                                
1672                                                  
1673                                                  
1674 void  G4OpenGLQtViewer::updateKeyModifierStat    
1675   // Check Qt Versions for META Keys             
1676                                                  
1677   fNoKeyPress = true;                            
1678   fAltKeyPress = false;                          
1679   fShiftKeyPress = false;                        
1680   fControlKeyPress = false;                      
1681                                                  
1682   if (modifier & Qt::AltModifier ) {             
1683     fAltKeyPress = true;                         
1684     fNoKeyPress = false;                         
1685   }                                              
1686   if (modifier & Qt::ShiftModifier ) {           
1687     fShiftKeyPress = true;                       
1688     fNoKeyPress = false;                         
1689   }                                              
1690   if (modifier & Qt::ControlModifier ) {         
1691     fControlKeyPress = true;                     
1692     fNoKeyPress = false;                         
1693   }                                              
1694 }                                                
1695                                                  
1696                                                  
1697 /** Stop the video. Check all parameters and     
1698  */                                              
1699 void G4OpenGLQtViewer::stopVideo() {             
1700                                                  
1701   // if encoder parameter is wrong, display p    
1702   if (!fMovieParametersDialog) {                 
1703     showMovieParametersDialog();                 
1704   }                                              
1705   setRecordingStatus(STOP);                      
1706                                                  
1707   if (fRecordFrameNumber >0) {                   
1708     // check parameters if they were modified    
1709     if (!(fMovieParametersDialog->checkEncode    
1710       setRecordingStatus(BAD_ENCODER);           
1711     }  else if (!(fMovieParametersDialog->che    
1712       setRecordingStatus(BAD_OUTPUT);            
1713     }                                            
1714   } else {                                       
1715     resetRecording();                            
1716     setRecordingInfos("No frame to encode.");    
1717   }                                              
1718 }                                                
1719                                                  
1720 /** Stop the video. Check all parameters and     
1721  */                                              
1722 void G4OpenGLQtViewer::saveVideo() {             
1723                                                  
1724   // if encoder parameter is wrong, display p    
1725   if (!fMovieParametersDialog) {                 
1726     showMovieParametersDialog();                 
1727   }                                              
1728                                                  
1729   fMovieParametersDialog->checkEncoderSwParam    
1730   fMovieParametersDialog->checkSaveFileNamePa    
1731                                                  
1732   if (fRecordingStep == STOP) {                  
1733     setRecordingStatus(SAVE);                    
1734     generateMpegEncoderParameters();             
1735     encodeVideo();                               
1736   }                                              
1737 }                                                
1738                                                  
1739                                                  
1740 /** Start/Pause the video..                      
1741  */                                              
1742 void G4OpenGLQtViewer::startPauseVideo() {       
1743                                                  
1744   // first time, if temp parameter is wrong,     
1745                                                  
1746   if ( fRecordingStep == WAIT) {                 
1747     if ( fRecordFrameNumber == 0) {              
1748       if (getTempFolderPath() == "") { // BAD    
1749         showMovieParametersDialog();             
1750         setRecordingInfos("You should specifi    
1751         return;                                  
1752       } else  {                                  
1753         // remove temp folder if it was creat    
1754         QString tmp = removeTempFolder();        
1755         if (tmp !="") {                          
1756           setRecordingInfos(tmp);                
1757           return;                                
1758         }                                        
1759         tmp = createTempFolder();                
1760         if (tmp != "") {                         
1761           setRecordingInfos("Can't create tem    
1762           return;                                
1763         }                                        
1764       }                                          
1765     }                                            
1766   }                                              
1767   if (fRecordingStep == WAIT) {                  
1768     setRecordingStatus(START);                   
1769   } else if (fRecordingStep == START) {          
1770     setRecordingStatus(PAUSE);                   
1771   } else if (fRecordingStep == PAUSE) {          
1772     setRecordingStatus(CONTINUE);                
1773   } else if (fRecordingStep == CONTINUE) {       
1774     setRecordingStatus(PAUSE);                   
1775   }                                              
1776 }                                                
1777                                                  
1778 void G4OpenGLQtViewer::setRecordingStatus(REC    
1779                                                  
1780   fRecordingStep = step;                         
1781   displayRecordingStatus();                      
1782 }                                                
1783                                                  
1784                                                  
1785 void G4OpenGLQtViewer::displayRecordingStatus    
1786                                                  
1787   QString txtStatus = "";                        
1788   if (fRecordingStep == WAIT) {                  
1789     txtStatus  = "Waiting to start...";          
1790     fRecordFrameNumber = 0; // reset the fram    
1791   } else if (fRecordingStep == START) {          
1792     txtStatus  = "Start Recording...";           
1793   } else if (fRecordingStep == PAUSE) {          
1794     txtStatus  = "Pause Recording...";           
1795   } else if (fRecordingStep == CONTINUE) {       
1796     txtStatus  = "Continue Recording...";        
1797   } else if (fRecordingStep == STOP) {           
1798     txtStatus  = "Stop Recording...";            
1799   } else if (fRecordingStep == READY_TO_ENCOD    
1800     txtStatus  = "Ready to Encode...";           
1801   } else if (fRecordingStep == ENCODING) {       
1802     txtStatus  = "Encoding...";                  
1803   } else if (fRecordingStep == FAILED) {         
1804     txtStatus  = "Failed to encode...";          
1805   } else if ((fRecordingStep == BAD_ENCODER)     
1806              || (fRecordingStep == BAD_OUTPUT    
1807              || (fRecordingStep == BAD_TMP))     
1808     txtStatus  = "Correct above errors first"    
1809   } else if (fRecordingStep == SUCCESS) {        
1810     txtStatus  = "File encoded successfully";    
1811   } else {                                       
1812   }                                              
1813                                                  
1814   if (fMovieParametersDialog) {                  
1815     fMovieParametersDialog->setRecordingStatu    
1816   } else {                                       
1817     G4cout << txtStatus.toStdString().c_str()    
1818   }                                              
1819   setRecordingInfos("");                         
1820 }                                                
1821                                                  
1822                                                  
1823 void G4OpenGLQtViewer::setRecordingInfos(cons    
1824   if (fMovieParametersDialog) {                  
1825     fMovieParametersDialog->setRecordingInfos    
1826   } else {                                       
1827     G4cout << txt.toStdString().c_str() << G4    
1828   }                                              
1829 }                                                
1830                                                  
1831 /** Init the movie parameters. Temp dir and e    
1832  */                                              
1833 void G4OpenGLQtViewer::initMovieParameters()     
1834   //init encoder                                 
1835                                                  
1836   //look for encoderPath                         
1837   fProcess = new QProcess();                     
1838                                                  
1839   QObject ::connect(fProcess,SIGNAL(finished     
1840                     this,SLOT(processLookForF    
1841   fProcess->setProcessChannelMode(QProcess::M    
1842 #if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))    
1843   fProcess->start ("which ppmtompeg");           
1844 #else                                            
1845   fProcess->start ("which ppmtompeg", QString    
1846 #endif                                           
1847 }                                                
1848                                                  
1849 /** @return encoder path or "" if it does not    
1850  */                                              
1851 QString G4OpenGLQtViewer::getEncoderPath() {     
1852   return fEncoderPath;                           
1853 }                                                
1854                                                  
1855                                                  
1856 /**                                              
1857  * set the new encoder path                      
1858  * @return "" if correct. The error otherwise    
1859  */                                              
1860 QString G4OpenGLQtViewer::setEncoderPath(QStr    
1861   if (path == "") {                              
1862     return "ppmtompeg is needed to encode in     
1863   }                                              
1864                                                  
1865   path =  QDir::cleanPath(path);                 
1866   QFileInfo *f = new QFileInfo(path);            
1867   if (!f->exists()) {                            
1868     return "File does not exist";                
1869   } else if (f->isDir()) {                       
1870     return "This is a directory";                
1871   } else if (!f->isExecutable()) {               
1872     return "File exist but is not executable"    
1873   } else if (!f->isFile()) {                     
1874     return "This is not a file";                 
1875   }                                              
1876   fEncoderPath = path;                           
1877                                                  
1878   if (fRecordingStep == BAD_ENCODER) {           
1879     setRecordingStatus(STOP);                    
1880   }                                              
1881   return "";                                     
1882 }                                                
1883                                                  
1884                                                  
1885 bool G4OpenGLQtViewer::isRecording(){            
1886   if ((fRecordingStep == START) || (fRecordin    
1887     return true;                                 
1888   }                                              
1889   return false;                                  
1890 }                                                
1891                                                  
1892 bool G4OpenGLQtViewer::isPaused(){               
1893   if (fRecordingStep == PAUSE) {                 
1894     return true;                                 
1895   }                                              
1896   return false;                                  
1897 }                                                
1898                                                  
1899 bool G4OpenGLQtViewer::isEncoding(){             
1900   if (fRecordingStep == ENCODING) {              
1901     return true;                                 
1902   }                                              
1903   return false;                                  
1904 }                                                
1905                                                  
1906 bool G4OpenGLQtViewer::isWaiting(){              
1907   if (fRecordingStep == WAIT) {                  
1908     return true;                                 
1909   }                                              
1910   return false;                                  
1911 }                                                
1912                                                  
1913 bool G4OpenGLQtViewer::isStopped(){              
1914   if (fRecordingStep == STOP) {                  
1915     return true;                                 
1916   }                                              
1917   return false;                                  
1918 }                                                
1919                                                  
1920 bool G4OpenGLQtViewer::isFailed(){               
1921   if (fRecordingStep == FAILED) {                
1922     return true;                                 
1923   }                                              
1924   return false;                                  
1925 }                                                
1926                                                  
1927 bool G4OpenGLQtViewer::isSuccess(){              
1928   if (fRecordingStep == SUCCESS) {               
1929     return true;                                 
1930   }                                              
1931   return false;                                  
1932 }                                                
1933                                                  
1934 bool G4OpenGLQtViewer::isBadEncoder(){           
1935   if (fRecordingStep == BAD_ENCODER) {           
1936     return true;                                 
1937   }                                              
1938   return false;                                  
1939 }                                                
1940 bool G4OpenGLQtViewer::isBadTmp(){               
1941   if (fRecordingStep == BAD_TMP) {               
1942     return true;                                 
1943   }                                              
1944   return false;                                  
1945 }                                                
1946 bool G4OpenGLQtViewer::isBadOutput(){            
1947   if (fRecordingStep == BAD_OUTPUT) {            
1948     return true;                                 
1949   }                                              
1950   return false;                                  
1951 }                                                
1952                                                  
1953 void G4OpenGLQtViewer::setBadEncoder(){          
1954   fRecordingStep = BAD_ENCODER;                  
1955   displayRecordingStatus();                      
1956 }                                                
1957 void G4OpenGLQtViewer::setBadTmp(){              
1958   fRecordingStep = BAD_TMP;                      
1959   displayRecordingStatus();                      
1960 }                                                
1961 void G4OpenGLQtViewer::setBadOutput(){           
1962   fRecordingStep = BAD_OUTPUT;                   
1963   displayRecordingStatus();                      
1964 }                                                
1965                                                  
1966 void G4OpenGLQtViewer::setWaiting(){             
1967   fRecordingStep = WAIT;                         
1968   displayRecordingStatus();                      
1969 }                                                
1970                                                  
1971                                                  
1972 bool G4OpenGLQtViewer::isReadyToEncode(){        
1973   if (fRecordingStep == READY_TO_ENCODE) {       
1974     return true;                                 
1975   }                                              
1976   return false;                                  
1977 }                                                
1978                                                  
1979 void G4OpenGLQtViewer::resetRecording() {        
1980   setRecordingStatus(WAIT);                      
1981 }                                                
1982                                                  
1983 /**                                              
1984  * set the temp folder path                      
1985  * @return "" if correct. The error otherwise    
1986  */                                              
1987 QString G4OpenGLQtViewer::setTempFolderPath(Q    
1988                                                  
1989   if (path == "") {                              
1990     return "Path does not exist";                
1991   }                                              
1992   path =  QDir::cleanPath(path);                 
1993   QFileInfo *d = new QFileInfo(path);            
1994   if (!d->exists()) {                            
1995     return "Path does not exist";                
1996   } else if (!d->isDir()) {                      
1997     return "This is not a directory";            
1998   } else if (!d->isReadable()) {                 
1999     return path +" is read protected";           
2000   } else if (!d->isWritable()) {                 
2001     return path +" is write protected";          
2002   }                                              
2003                                                  
2004   if (fRecordingStep == BAD_TMP) {               
2005     setRecordingStatus(WAIT);                    
2006   }                                              
2007   fTempFolderPath = path;                        
2008   return "";                                     
2009 }                                                
2010                                                  
2011 /** @return the temp folder path or "" if it     
2012  */                                              
2013 QString G4OpenGLQtViewer::getTempFolderPath()    
2014   return fTempFolderPath;                        
2015 }                                                
2016                                                  
2017 /**                                              
2018  * set the save file name path                   
2019  * @return "" if correct. The error otherwise    
2020  */                                              
2021 QString G4OpenGLQtViewer::setSaveFileName(QSt    
2022                                                  
2023   if (path == "") {                              
2024     return "Path does not exist";                
2025   }                                              
2026                                                  
2027   QFileInfo *file = new QFileInfo(path);         
2028   QDir dir = file->dir();                        
2029   path =  QDir::cleanPath(path);                 
2030   if (file->exists()) {                          
2031     return "File already exist, please choose    
2032   } else if (!dir.exists()) {                    
2033     return "Dir does not exist";                 
2034   } else if (!dir.isReadable()) {                
2035     return path +" is read protected";           
2036   }                                              
2037                                                  
2038   if (fRecordingStep == BAD_OUTPUT) {            
2039     setRecordingStatus(STOP);                    
2040   }                                              
2041   fSaveFileName = path;                          
2042   return "";                                     
2043 }                                                
2044                                                  
2045 /** @return the save file path                   
2046  */                                              
2047 QString G4OpenGLQtViewer::getSaveFileName() {    
2048   return fSaveFileName ;                         
2049 }                                                
2050                                                  
2051 /** Create a Qt_temp folder in the temp folde    
2052  * The temp folder will be like this /tmp/QtM    
2053  * @return "" if success. Error message if no    
2054  */                                              
2055 QString G4OpenGLQtViewer::createTempFolder()     
2056   fMovieTempFolderPath = "";                     
2057   //check                                        
2058   QString tmp = setTempFolderPath(fTempFolder    
2059   if (tmp != "") {                               
2060     return tmp;                                  
2061   }                                              
2062   QString sep = QString(QDir::separator());      
2063   QString path = sep+"QtMovie_"+QDateTime::cu    
2064   QDir *d = new QDir(QDir::cleanPath(fTempFol    
2065   // check if it is already present              
2066   if (d->exists(path)) {                         
2067     return "Folder "+path+" already exists.Pl    
2068   }                                              
2069   if (d->mkdir(fTempFolderPath+path)) {          
2070     fMovieTempFolderPath = fTempFolderPath+pa    
2071     return "";                                   
2072   }                                              
2073   return "Can't create "+fTempFolderPath+path    
2074 }                                                
2075                                                  
2076 /** Remove the Qt_temp folder in the temp fol    
2077  */                                              
2078 QString G4OpenGLQtViewer::removeTempFolder()     
2079   // remove files in Qt_temp folder              
2080   if (fMovieTempFolderPath == "") {              
2081     return "";                                   
2082   }                                              
2083   QDir *d = new QDir(QDir::cleanPath(fMovieTe    
2084   if (!d->exists()) {                            
2085     return "";  // already remove                
2086   }                                              
2087                                                  
2088   d->setFilter( QDir::Files );                   
2089   QStringList subDirList = d->entryList();       
2090   int res = true;                                
2091   QString error = "";                            
2092   for (QStringList::ConstIterator it = subDir    
2093     const QString currentFile = *it;             
2094     if (!d->remove(currentFile)) {               
2095       res = false;                               
2096       QString file = fMovieTempFolderPath+cur    
2097       error +="Removing file failed : "+file;    
2098     } else {                                     
2099     }                                            
2100   }                                              
2101   if (res) {                                     
2102     if (d->rmdir(fMovieTempFolderPath)) {        
2103       fMovieTempFolderPath = "";                 
2104       return "";                                 
2105     } else {                                     
2106       return "Dir "+fMovieTempFolderPath+" sh    
2107     }                                            
2108                                                  
2109   }                                              
2110   return "Could not remove "+fMovieTempFolder    
2111 }                                                
2112                                                  
2113 /**                                              
2114   Export image. Try to get the format accordi    
2115   If not present, the last one choosen by /vi    
2116   If not, will take the default format : eps     
2117   Best format actually available is pdf (vect    
2118   If name is not set, it will take the defaul    
2119  */                                              
2120 bool G4OpenGLQtViewer::exportImage(std::strin    
2121                                                  
2122   auto* qGLW = dynamic_cast<G4QGLWidgetType*>    
2123   if (! qGLW) {                                  
2124     return false;                                
2125   }                                              
2126   // If there is already an extention            
2127   bool increaseFileNumber = true;                
2128   // if                                          
2129   if (name.size() != name.substr(name.find_la    
2130     increaseFileNumber = false;                  
2131   }                                              
2132   if (! setExportFilename(name,increaseFileNu    
2133     return false;                                
2134   }                                              
2135   if ((width !=-1) && (height != -1)) {          
2136     setExportSize(width, height);                
2137   }                                              
2138   // first, try to do it with generic functio    
2139   if (G4OpenGLViewer::exportImage(name, width    
2140     return true;                                 
2141                                                  
2142   // Then try Qt saving functions                
2143   } else {                                       
2144     QImage image;                                
2145 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))     
2146     image = qGLW->grabFrameBuffer();             
2147 #else                                            
2148     image = qGLW->grabFramebuffer();             
2149 #endif                                           
2150                                                  
2151     bool res = image.save(QString(getRealPrin    
2152                                                  
2153     if (!res) {                                  
2154       G4cerr << "Error saving file... " << ge    
2155       return false;                              
2156     } else {                                     
2157       G4cout << "File " << getRealPrintFilena    
2158       fExportFilenameIndex++;                    
2159     }                                            
2160   }                                              
2161   return true;                                   
2162 }                                                
2163                                                  
2164 bool G4OpenGLQtViewer::generateMpegEncoderPar    
2165                                                  
2166   // save the parameter file                     
2167   FILE* fp;                                      
2168   fp = fopen (QString(fMovieTempFolderPath+fP    
2169                                                  
2170   if (fp == NULL) {                              
2171     setRecordingInfos("Generation of paramete    
2172     return false;                                
2173   }                                              
2174                                                  
2175   fprintf (fp,"# Pattern affects speed, quali    
2176   fprintf (fp,"# for more info.\n");             
2177   fprintf (fp,"\n");                             
2178   fprintf (fp,"PATTERN    I\n");                 
2179   fprintf (fp,"OUTPUT   %s\n",getSaveFileName    
2180   fprintf (fp,"\n");                             
2181   fprintf (fp,"# You must specify the type of    
2182   fprintf (fp,"#    YUV, PPM, JMOVIE, Y, JPEG    
2183   fprintf (fp,"#  (must be upper case)\n");      
2184   fprintf (fp,"#\n");                            
2185   fprintf (fp,"BASE_FILE_FORMAT PPM\n");         
2186   fprintf (fp,"\n");                             
2187   fprintf (fp,"\n");                             
2188   fprintf (fp,"# If you are using YUV, there     
2189   fprintf (fp,"# EYUV or UCB are the same as     
2190   fprintf (fp,"# (All the Y's, then U's then     
2191   fprintf (fp,"# Other formats, such as Abeka    
2192   fprintf (fp,"# permissible, the general for    
2193   fprintf (fp,"# to specify the file order.\n    
2194   fprintf (fp,"\n");                             
2195   fprintf (fp,"INPUT_FORMAT UCB\n");             
2196   fprintf (fp,"\n");                             
2197   fprintf (fp,"# the conversion statement\n")    
2198   fprintf (fp,"#\n");                            
2199   fprintf (fp,"# Each occurrence of '*' will     
2200   fprintf (fp,"#\n");                            
2201   fprintf (fp,"# e.g., if you have a bunch of    
2202   fprintf (fp,"#  INPUT_CONVERT giftoppm *\n"    
2203   fprintf (fp,"#\n");                            
2204   fprintf (fp,"# e.g., if you have a bunch of    
2205   fprintf (fp,"#  INPUT_CONVERT cat *.Y *.U *    
2206   fprintf (fp,"#\n");                            
2207   fprintf (fp,"# e.g., if you are grabbing fr    
2208   fprintf (fp,"#  INPUT_CONVERT goto frame *;    
2209   fprintf (fp,"# 'INPUT_CONVERT *' means the     
2210   fprintf (fp,"#\n");                            
2211   fprintf (fp,"INPUT_CONVERT  * \n");            
2212   fprintf (fp,"\n");                             
2213   fprintf (fp,"# number of frames in a GOP.\n    
2214   fprintf (fp,"#\n");                            
2215   fprintf (fp,"# since each GOP must have at     
2216   fprintf (fp,"# the first I-frame after GOP_    
2217   fprintf (fp,"#\n");                            
2218   fprintf (fp,"# later, will add more flexibl    
2219   fprintf (fp,"#\n");                            
2220   fprintf (fp,"GOP_SIZE 1\n");                   
2221   fprintf (fp,"\n");                             
2222   fprintf (fp,"# number of slices in a frame\    
2223   fprintf (fp,"#\n");                            
2224   fprintf (fp,"# 1 is a good number.  another    
2225   fprintf (fp,"# (which is the height divided    
2226   fprintf (fp,"#\n");                            
2227   fprintf (fp,"SLICES_PER_FRAME 1\n");           
2228   fprintf (fp,"PIXEL HALF");                     
2229   fprintf (fp,"\n");                             
2230   fprintf (fp,"# directory to get all input f    
2231   fprintf (fp,"INPUT_DIR  %s\n",fMovieTempFol    
2232   fprintf (fp,"\n");                             
2233   fprintf (fp,"# There are a bunch of ways to    
2234   fprintf (fp,"# from a simple one-per-line l    
2235   fprintf (fp,"# way of numbering them.  See     
2236   fprintf (fp,"INPUT\n");                        
2237   fprintf (fp,"# '*' is replaced by the numbe    
2238   fprintf (fp,"# if I instead do [01-11], it     
2239   fprintf (fp,"# if I instead do [1-11], it w    
2240   fprintf (fp,"# if I instead do [1-11+3], it    
2241   fprintf (fp,"# the program assumes none of     
2242   fprintf (fp,"# if you do, too bad!!!\n");      
2243   fprintf (fp,"#\n");                            
2244   fprintf (fp,"#\n");                            
2245   fprintf (fp,"Test*.ppm  [0-%d]\n",fRecordFr    
2246   fprintf (fp,"# can have more files here if     
2247   fprintf (fp,"# of files\n");                   
2248   fprintf (fp,"END_INPUT\n");                    
2249   fprintf (fp,"\n");                             
2250   fprintf (fp,"\n");                             
2251   fprintf (fp,"\n");                             
2252   fprintf (fp,"# Many of the remaining option    
2253   fprintf (fp,"\n");                             
2254   fprintf (fp,"# FULL or HALF -- must be uppe    
2255   fprintf (fp,"# Should be FULL for computer     
2256   fprintf (fp,"PIXEL    FULL\n");                
2257   fprintf (fp,"\n");                             
2258   fprintf (fp,"# means +/- this many pixels f    
2259   fprintf (fp,"# specify two numbers if you w    
2260   fprintf (fp,"RANGE    10\n");                  
2261   fprintf (fp,"\n");                             
2262   fprintf (fp,"# The two search algorithm par    
2263   fprintf (fp,"# with some affect on compress    
2264   fprintf (fp,"\n");                             
2265   fprintf (fp,"# this must be one of {EXHAUST    
2266   fprintf (fp,"PSEARCH_ALG  LOGARITHMIC\n");     
2267   fprintf (fp,"\n");                             
2268   fprintf (fp,"# this must be one of {SIMPLE,    
2269   fprintf (fp,"#\n");                            
2270   fprintf (fp,"# note that EXHAUSTIVE is real    
2271   fprintf (fp,"#\n");                            
2272   fprintf (fp,"BSEARCH_ALG  SIMPLE\n");          
2273   fprintf (fp,"\n");                             
2274   fprintf (fp,"#\n");                            
2275   fprintf (fp,"# these specify the q-scale fo    
2276   fprintf (fp,"# (values must be between 1 an    
2277   fprintf (fp,"# These are the Qscale values     
2278   fprintf (fp,"# mode, and starting points (b    
2279   fprintf (fp,"#\n");                            
2280   fprintf (fp,"\n");                             
2281   fprintf (fp,"# Qscale (Quantization scale)     
2282   fprintf (fp,"# but has very little effect o    
2283   fprintf (fp,"\n");                             
2284   fprintf (fp,"IQSCALE    4\n");                 
2285   fprintf (fp,"PQSCALE    5\n");                 
2286   fprintf (fp,"BQSCALE    12\n");                
2287   fprintf (fp,"\n");                             
2288   fprintf (fp,"# this must be ORIGINAL or DEC    
2289   fprintf (fp,"REFERENCE_FRAME  ORIGINAL\n");    
2290   fprintf (fp,"\n");                             
2291   fprintf (fp,"# for parallel parameters see     
2292   fprintf (fp,"\n");                             
2293   fprintf (fp,"# if you want constant bit-rat    
2294   fprintf (fp,"#BIT_RATE  1000000\n");           
2295   fprintf (fp,"\n");                             
2296   fprintf (fp,"# To specify the buffer size (    
2297   fprintf (fp,"BUFFER_SIZE 327680\n");           
2298   fprintf (fp,"\n");                             
2299   fprintf (fp,"# The frame rate is the number    
2300   fprintf (fp,"# 23.976, 24, 25, 29.97, 30, 5    
2301   fprintf (fp,"FRAME_RATE 30\n");                
2302   fprintf (fp,"\n");                             
2303   fprintf (fp,"# There are many more options,    
2304   fprintf (fp,"# ASPECT_RATIO, USER_DATA, GAM    
2305   fprintf (fp,"\n");                             
2306   fprintf (fp,"\n");                             
2307   fclose (fp);                                   
2308                                                  
2309   setRecordingInfos("Parameter file "+fParame    
2310   setRecordingStatus(READY_TO_ENCODE);           
2311   return true;                                   
2312 }                                                
2313                                                  
2314 void G4OpenGLQtViewer::encodeVideo()             
2315 {                                                
2316   if ((getEncoderPath() != "") && (getSaveFil    
2317     setRecordingStatus(ENCODING);                
2318                                                  
2319     fProcess = new QProcess();                   
2320     QObject ::connect(fProcess,SIGNAL(finishe    
2321                       this,SLOT(processEncode    
2322     QObject ::connect(fProcess,SIGNAL(readyRe    
2323                       this,SLOT(processEncode    
2324 #if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0))    
2325     fProcess->setReadChannelMode(QProcess::Me    
2326 #else                                            
2327     fProcess->setProcessChannelMode(QProcess:    
2328 #endif                                           
2329     fProcess->start (fEncoderPath, QStringLis    
2330   }                                              
2331 }                                                
2332                                                  
2333                                                  
2334 // FIXME : does not work on Qt3                  
2335 void G4OpenGLQtViewer::processEncodeStdout()     
2336 {                                                
2337   QString tmp = fProcess->readAllStandardOutp    
2338   auto start = tmp.lastIndexOf("ESTIMATED TIM    
2339   tmp = tmp.mid(start,tmp.indexOf("\n",start)    
2340   setRecordingInfos(tmp);                        
2341 }                                                
2342                                                  
2343                                                  
2344 void G4OpenGLQtViewer::processEncodeFinished(    
2345 {                                                
2346                                                  
2347   QString txt = "";                              
2348   txt = getProcessErrorMsg();                    
2349   if (txt == "") {                               
2350     setRecordingStatus(SUCCESS);                 
2351   } else {                                       
2352     setRecordingStatus(FAILED);                  
2353   }                                              
2354   //  setRecordingInfos(txt+removeTempFolder(    
2355 }                                                
2356                                                  
2357                                                  
2358 void G4OpenGLQtViewer::processLookForFinished    
2359 {                                                
2360                                                  
2361   QString txt = getProcessErrorMsg();            
2362   if (txt != "") {                               
2363     fEncoderPath = "";                           
2364   } else {                                       
2365     fEncoderPath = QString(fProcess->readAllS    
2366     // if not found, return "not found"          
2367     if (fEncoderPath.contains(" ")) {            
2368       fEncoderPath = "";                         
2369     } else if (!fEncoderPath.contains("ppmtom    
2370       fEncoderPath = "";                         
2371     }                                            
2372     setEncoderPath(fEncoderPath);                
2373   }                                              
2374   // init temp folder                            
2375   setTempFolderPath(QDir::temp ().absolutePat    
2376 }                                                
2377                                                  
2378                                                  
2379 QString G4OpenGLQtViewer::getProcessErrorMsg(    
2380 {                                                
2381   QString txt = "";                              
2382   if (fProcess->exitCode() != 0) {               
2383     switch (fProcess->error()) {                 
2384     case QProcess::FailedToStart:                
2385       txt = "The process failed to start. Eit    
2386       break;                                     
2387     case QProcess::Crashed:                      
2388       txt = "The process crashed some time af    
2389       break;                                     
2390     case QProcess::Timedout:                     
2391       txt = "The last waitFor...() function t    
2392       break;                                     
2393     case QProcess::WriteError:                   
2394       txt = "An error occurred when attemptin    
2395       break;                                     
2396     case QProcess::ReadError:                    
2397       txt = "An error occurred when attemptin    
2398       break;                                     
2399     case QProcess::UnknownError:                 
2400       txt = "An unknown error occurred. This     
2401       break;                                     
2402     }                                            
2403   }                                              
2404   return txt;                                    
2405 }                                                
2406                                                  
2407                                                  
2408                                                  
2409                                                  
2410 QWidget *G4OpenGLQtViewer::getParentWidget()     
2411 {                                                
2412   // launch Qt if not                            
2413   G4Qt* interactorManager = G4Qt::getInstance    
2414                                                  
2415   bool found = false;                            
2416   QDialog* dialog = NULL;                        
2417   // create window                               
2418   if (((QApplication*)interactorManager->GetM    
2419     // look for the main window                  
2420     QWidgetList wl = QApplication::allWidgets    
2421     QWidget *widget = NULL;                      
2422     for (int i=0; i < wl.size(); i++) {          
2423       widget = wl.at(i);                         
2424       if ((found== false) && (widget->inherit    
2425         dialog = new QDialog(widget,Qt::Windo    
2426         found = true;                            
2427       }                                          
2428     }                                            
2429                                                  
2430     if (found==false) {                          
2431       dialog = new QDialog();                    
2432     }                                            
2433   } else {                                       
2434     dialog= new QDialog();                       
2435   }                                              
2436   if (found) {                                   
2437     return dialog;                               
2438   } else {                                       
2439     return NULL;                                 
2440   }                                              
2441 }                                                
2442                                                  
2443                                                  
2444 void G4OpenGLQtViewer::createSceneTreeWidget(    
2445   fUISceneTreeWidget = fUiQt->GetSceneTreeWid    
2446                                                  
2447   if (!fUISceneTreeWidget) {                     
2448     return;                                      
2449   }                                              
2450                                                  
2451   // do not remove previous widgets, hide the    
2452   QLayoutItem * wItem;                           
2453   bool found = false;                            
2454   if (fUISceneTreeWidget->layout()->count() )    
2455     for(int idx = 0; idx < fUISceneTreeWidget    
2456       wItem = fUISceneTreeWidget->layout()->i    
2457       if (fSceneTreeWidget) {                    
2458         if(dynamic_cast<QWidget *>(wItem->wid    
2459           if (wItem->widget()->windowTitle()     
2460             wItem->widget()->show();             
2461             found = true;                        
2462           } else {                               
2463             wItem->widget()->hide();             
2464           }                                      
2465         }                                        
2466       } else {                                   
2467 //        wItem->widget()->hide();               
2468       }                                          
2469     }                                            
2470   }                                              
2471                                                  
2472   if (!found) {                                  
2473     // initialize scene tree / viewer propert    
2474     fSceneTreeWidget = new QWidget();            
2475     QVBoxLayout* layoutSceneTree = new QVBoxL    
2476     fSceneTreeWidget->setStyleSheet ("padding    
2477                                                  
2478     fSceneTreeWidget->setLayout(layoutSceneTr    
2479     fSceneTreeWidget->layout()->setContentsMa    
2480     fSceneTreeWidget->setWindowTitle(QString(    
2481                                                  
2482     if (fUISceneTreeWidget != NULL) {            
2483 //      fUISceneTreeWidget->layout()->addWidg    
2484     }                                            
2485                                                  
2486     // not available for Immediate mode          
2487     if (dynamic_cast<G4OpenGLStoredQtViewer*>    
2488       createSceneTreeComponent();                
2489     }                                            
2490   }                                              
2491 }                                                
2492                                                  
2493                                                  
2494 void G4OpenGLQtViewer::createSceneTreeCompone    
2495                                                  
2496   QLayout* vLayout = fSceneTreeWidget->layout    
2497                                                  
2498   // Search line                                 
2499   QWidget* coutButtonWidget = new QWidget();     
2500   QHBoxLayout* layoutCoutTBButtons = new QHBo    
2501                                                  
2502   fFilterOutput = new QLineEdit();               
2503   fFilterOutput->setToolTip("Filter output by    
2504   fFilterOutput->setStyleSheet ("padding: 0px    
2505                                                  
2506   QPixmap* searchIcon = fUiQt->getSearchIcon(    
2507   fFilterOutput->addAction(*searchIcon,QLineE    
2508   fFilterOutput->setStyleSheet ("border-radiu    
2509   layoutCoutTBButtons->addWidget(fFilterOutpu    
2510                                                  
2511   coutButtonWidget->setLayout(layoutCoutTBBut    
2512   vLayout->addWidget(coutButtonWidget);          
2513                                                  
2514   // reduce margins                              
2515   vLayout->setContentsMargins(0,0,0,0);          
2516                                                  
2517                                                  
2518   fSceneTreeComponentTreeWidget = new QTreeWi    
2519   fSceneTreeComponentTreeWidget->setSelection    
2520   fSceneTreeComponentTreeWidget->setHeaderLab    
2521   fSceneTreeComponentTreeWidget->setColumnHid    
2522   fSceneTreeComponentTreeWidget->setColumnHid    
2523   fSceneTreeComponentTreeWidget->setColumnHid    
2524   //   data(0) : POindex                         
2525   //   data(1) : copy number                     
2526   //   data(2) : g4color                         
2527                                                  
2528   vLayout->addWidget(fSceneTreeComponentTreeW    
2529                                                  
2530   connect(fSceneTreeComponentTreeWidget,SIGNA    
2531   connect(fSceneTreeComponentTreeWidget,SIGNA    
2532   connect(fSceneTreeComponentTreeWidget,SIGNA    
2533                                                  
2534                                                  
2535   // Depth slider                                
2536   QWidget *helpWidget = new QWidget();           
2537   QHBoxLayout *helpLayout = new QHBoxLayout()    
2538                                                  
2539   QWidget* depthWidget = new QWidget();          
2540   QWidget *showBox = new QWidget(depthWidget)    
2541   QHBoxLayout *showBoxLayout = new QHBoxLayou    
2542                                                  
2543   // reduce margins                              
2544   showBoxLayout->setContentsMargins(5,5,5,5);    
2545                                                  
2546   QLabel *zero = new QLabel();                   
2547   zero->setText("Show all");                     
2548   QLabel *one = new QLabel();                    
2549   one->setText("Hide all");                      
2550   fSceneTreeDepthSlider = new QSlider ( Qt::H    
2551   fSceneTreeDepthSlider->setMaximum (1000);      
2552   fSceneTreeDepthSlider->setMinimum (0);         
2553   fSceneTreeDepthSlider->setTickPosition(QSli    
2554   // set a minimum size                          
2555   fSceneTreeDepthSlider->setMinimumWidth (40)    
2556                                                  
2557   showBoxLayout->addWidget(zero);                
2558   showBoxLayout->addWidget(fSceneTreeDepthSli    
2559   showBoxLayout->addWidget(one);                 
2560                                                  
2561   showBox->setLayout(showBoxLayout);             
2562                                                  
2563   helpLayout->addWidget(showBox);                
2564   helpWidget->setLayout(helpLayout);             
2565   helpLayout->setContentsMargins(0,0,0,0);       
2566                                                  
2567   vLayout->addWidget(helpWidget);                
2568                                                  
2569   connect( fSceneTreeDepthSlider, SIGNAL( val    
2570   connect( fFilterOutput, SIGNAL( textEdited     
2571   fTreeItemModels.clear();                       
2572                                                  
2573   fPVRootNodeCreate = false;                     
2574                                                  
2575   fMaxPOindexInserted = -1;                      
2576                                                  
2577                                                  
2578 }                                                
2579                                                  
2580                                                  
2581 void G4OpenGLQtViewer::createViewerProperties    
2582                                                  
2583   // Get the pointer to the Viewer Properties    
2584   fUIViewerPropertiesWidget = fUiQt->GetViewe    
2585                                                  
2586   if (!fUIViewerPropertiesWidget) {              
2587     return;                                      
2588   }                                              
2589                                                  
2590   // remove previous widgets                     
2591   QLayoutItem * wItem;                           
2592   if (fUIViewerPropertiesWidget->layout()->co    
2593     while ((wItem = fUIViewerPropertiesWidget    
2594       delete wItem->widget();                    
2595       delete wItem;                              
2596     }                                            
2597   }                                              
2598                                                  
2599   // add properties                              
2600   QGroupBox *groupBox = new QGroupBox();         
2601   groupBox->setTitle(GetName().data());          
2602   QVBoxLayout *vbox = new QVBoxLayout;           
2603                                                  
2604   // add properties content                      
2605   fViewerPropertiesTableWidget = new QTableWi    
2606                                                  
2607   QSizePolicy vPolicy = fViewerPropertiesTabl    
2608   vPolicy.setVerticalStretch(4);                 
2609                                                  
2610   vbox->addWidget(fViewerPropertiesTableWidge    
2611   groupBox->setLayout(vbox);                     
2612   fUIViewerPropertiesWidget->layout()->addWid    
2613                                                  
2614   connect(fViewerPropertiesTableWidget, SIGNA    
2615                                                  
2616   updateViewerPropertiesTableWidget();           
2617                                                  
2618   QDialog* dial = static_cast<QDialog*> (fUIV    
2619   if (dial) {                                    
2620     // change name                               
2621     dial->setWindowTitle(QString("Viewer prop    
2622   }                                              
2623 }                                                
2624                                                  
2625                                                  
2626 void G4OpenGLQtViewer::createPickInfosWidget(    
2627                                                  
2628   // Get the pointer to the Pick infos widget    
2629   fUIPickInfosWidget = fUiQt->GetPickInfosWid    
2630                                                  
2631   if (!fUIPickInfosWidget) {                     
2632     return;                                      
2633   }                                              
2634                                                  
2635   // remove previous widgets                     
2636   QLayoutItem * wItem;                           
2637   if (fUIPickInfosWidget->layout()->count())     
2638     while ((wItem = fUIPickInfosWidget->layou    
2639       delete wItem->widget();                    
2640       delete wItem;                              
2641     }                                            
2642   }                                              
2643                                                  
2644   QGroupBox *groupBox = new QGroupBox("");       
2645   QVBoxLayout *vbox = new QVBoxLayout;           
2646                                                  
2647   // add picking infos                           
2648   QWidget *pickingInfoWidget = new QWidget();    
2649   QHBoxLayout *pickingInfoLayout = new QHBoxL    
2650                                                  
2651   pickingInfoWidget->setStyleSheet ("padding-    
2652   pickingInfoWidget->setLayout(pickingInfoLay    
2653                                                  
2654   vbox->addWidget(pickingInfoWidget);            
2655   // add picking content                         
2656                                                  
2657   fPickInfosScrollArea = new QScrollArea();      
2658   fPickInfosScrollArea->setWidgetResizable(tr    
2659                                                  
2660                                                  
2661   fPickInfosWidget = new QWidget();              
2662   fPickInfosWidget->setStyleSheet ("padding:     
2663                                                  
2664   QVBoxLayout* vLayout = new QVBoxLayout();      
2665   fPickInfosWidget->setLayout (vLayout);         
2666   fPickInfosScrollArea->setWidget(fPickInfosW    
2667                                                  
2668   QSizePolicy vPolicy = fPickInfosWidget->siz    
2669   vPolicy.setVerticalStretch(4);                 
2670   vbox->addWidget(fPickInfosScrollArea);         
2671   pickingInfoLayout->setContentsMargins(0,0,0    
2672   vLayout->setContentsMargins(0,0,0,0);          
2673   vbox->setContentsMargins(1,1,1,1);             
2674                                                  
2675   groupBox->setLayout(vbox);                     
2676   fUIPickInfosWidget->layout()->addWidget(gro    
2677                                                  
2678   updatePickInfosWidget(fLastPickPoint.x(),fL    
2679 }                                                
2680                                                  
2681                                                  
2682 // set the component to check/unchecked, also    
2683 // and set the same status to all his childs     
2684 void G4OpenGLQtViewer::setCheckComponent(QTre    
2685 {                                                
2686   if (item) {                                    
2687                                                  
2688     const PVPath& fullPath = fTreeItemModels[    
2689     // If a physical volume                      
2690     if (fullPath.size() > 0) {                   
2691       SetTouchable(fullPath);                    
2692       TouchableSetVisibility(fullPath, check)    
2693       fMouseOnSceneTree = true;                  
2694     }                                            
2695   }                                              
2696                                                  
2697   if (item != NULL) {                            
2698     if (check) {                                 
2699       item->setCheckState(0,Qt::Checked);        
2700     } else {                                     
2701       item->setCheckState(0,Qt::Unchecked);      
2702     }                                            
2703     updatePositivePoIndexSceneTreeWidgetQuick    
2704     int nChildCount = item->childCount();        
2705     for (int i = 0; i < nChildCount; i++) {      
2706       setCheckComponent(item->child(i),check)    
2707     }                                            
2708   }                                              
2709 }                                                
2710                                                  
2711 #if QT_VERSION < 0x060000                        
2712 #else                                            
2713 //G.Barrand : from stackoverflow "How to rend    
2714 static void transform_point(GLdouble out[4],     
2715 {                                                
2716 #define M(row,col)  m[col*4+row]                 
2717     out[0] =                                     
2718         M(0, 0) * in[0] + M(0, 1) * in[1] + M    
2719     out[1] =                                     
2720         M(1, 0) * in[0] + M(1, 1) * in[1] + M    
2721     out[2] =                                     
2722         M(2, 0) * in[0] + M(2, 1) * in[1] + M    
2723     out[3] =                                     
2724         M(3, 0) * in[0] + M(3, 1) * in[1] + M    
2725 #undef M                                         
2726 }                                                
2727 inline GLint project_point(GLdouble objx, GLd    
2728     const GLdouble model[16], const GLdouble     
2729     const GLint viewport[4],                     
2730     GLdouble * winx, GLdouble * winy, GLdoubl    
2731 {                                                
2732     GLdouble in[4], out[4];                      
2733                                                  
2734     in[0] = objx;                                
2735     in[1] = objy;                                
2736     in[2] = objz;                                
2737     in[3] = 1.0;                                 
2738     transform_point(out, model, in);             
2739     transform_point(in, proj, out);              
2740                                                  
2741     if (in[3] == 0.0)                            
2742         return GL_FALSE;                         
2743                                                  
2744     in[0] /= in[3];                              
2745     in[1] /= in[3];                              
2746     in[2] /= in[3];                              
2747                                                  
2748     *winx = viewport[0] + (1 + in[0]) * viewp    
2749     *winy = viewport[1] + (1 + in[1]) * viewp    
2750                                                  
2751     *winz = (1 + in[2]) / 2;                     
2752     return GL_TRUE;                              
2753 }                                                
2754 static void render_text(QOpenGLWidget& widget    
2755                  double world_x, double world    
2756                  double offset_x, double offs    
2757                  const QFont& font,              
2758                  const QColor& color,            
2759                  const char* text)               
2760 {                                                
2761     GLdouble model[4][4];                        
2762     glGetDoublev(GL_MODELVIEW_MATRIX, &model[    
2763     GLdouble proj[4][4];                         
2764     glGetDoublev(GL_PROJECTION_MATRIX, &proj[    
2765     GLint view[4];                               
2766     glGetIntegerv(GL_VIEWPORT, &view[0]);        
2767                                                  
2768     GLdouble textPosX = 0, textPosY = 0, text    
2769     project_point(world_x, world_y, world_z,     
2770                   &model[0][0], &proj[0][0],     
2771                   &textPosX, &textPosY, &text    
2772                                                  
2773     textPosX /= GLdouble(widget.devicePixelRa    
2774     textPosY /= GLdouble(widget.devicePixelRa    
2775                                                  
2776     textPosY = GLdouble(widget.height()) - te    
2777                                                  
2778     textPosX += offset_x;                        
2779     textPosY += offset_y;                        
2780                                                  
2781     GLboolean GL_BLEND_enabled = glIsEnabled(    
2782                                                  
2783     QPainter painter(&widget);                   
2784     painter.setPen(color);                       
2785     painter.setFont(font);                       
2786     painter.setRenderHints(QPainter::Antialia    
2787     painter.drawText(textPosX, textPosY, text    
2788     painter.end();                               
2789                                                  
2790     if(GL_BLEND_enabled==GL_TRUE) {              
2791       ::glEnable(GL_BLEND);                      
2792       ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINU    
2793     }                                            
2794 }                                                
2795 #endif                                           
2796                                                  
2797 void G4OpenGLQtViewer::DrawText(const G4Text&    
2798 {                                                
2799   auto* qGLW = dynamic_cast<G4QGLWidgetType*>    
2800   if (! qGLW) {                                  
2801     return;                                      
2802   }                                              
2803   if (isGl2psWriting()) {                        
2804                                                  
2805     G4OpenGLViewer::DrawText(g4text);            
2806                                                  
2807   } else {                                       
2808                                                  
2809     if (!fGLWidget) return;                      
2810                                                  
2811     if (!G4Threading::IsMasterThread()) retur    
2812                                                  
2813     G4VSceneHandler::MarkerSizeType sizeType;    
2814     G4double size = fSceneHandler.GetMarkerSi    
2815                                                  
2816     QFont font = QFont();                        
2817     font.setPointSizeF(size);                    
2818                                                  
2819     const G4Colour& c = fSceneHandler.GetText    
2820                                                  
2821     G4Point3D position = g4text.GetPosition()    
2822                                                  
2823     const G4String& textString = g4text.GetTe    
2824     const char* textCString = textString.c_st    
2825                                                  
2826     // Calculate move for centre and right ad    
2827     QFontMetrics f(font);                        
2828     G4double span = f.boundingRect(textCStrin    
2829                                                  
2830     G4double xmove = 0.;                         
2831     G4double ymove = 0.;                         
2832                                                  
2833     switch (g4text.GetLayout()) {                
2834     case G4Text::left: break;                    
2835     case G4Text::centre: xmove -= span / 2.;     
2836     case G4Text::right: xmove -= span;           
2837     }                                            
2838                                                  
2839     //Add offsets                                
2840     xmove += g4text.GetXOffset();                
2841     ymove += g4text.GetYOffset();                
2842                                                  
2843 #if QT_VERSION < 0x060000                        
2844     glColor4d(c.GetRed(),c.GetGreen(),c.GetBl    
2845     glRasterPos3d(position.x(),position.y(),p    
2846     // xmove, ymove in pixels - or are they?     
2847 #ifdef __APPLE__                                 
2848     const G4double fudgeFactor = 2.;             
2849 #else                                            
2850     const G4double fudgeFactor = 1.;             
2851 #endif                                           
2852     xmove *= fudgeFactor;                        
2853     ymove *= fudgeFactor;                        
2854     qGLW->renderText                             
2855       ((position.x()+(2*xmove)/getWinWidth())    
2856        (position.y()+(2*ymove)/getWinHeight()    
2857        position.z(),                             
2858        textCString,                              
2859        font);                                    
2860 #else                                            
2861     QColor color((int)(c.GetRed()*255),          
2862                  (int)(c.GetGreen()*255),        
2863                  (int)(c.GetBlue()*255),         
2864                  (int)(c.GetAlpha()*255));       
2865     render_text(*qGLW,                           
2866                 position.x(),position.y(),pos    
2867                 xmove,ymove,                     
2868                 font,color,textCString);         
2869 #endif                                           
2870   }                                              
2871 }                                                
2872                                                  
2873                                                  
2874 void G4OpenGLQtViewer::ResetView () {            
2875   G4OpenGLViewer::ResetView();                   
2876   fDeltaDepth = 0.01;                            
2877   fDeltaZoom = 0.05;                             
2878 }                                                
2879                                                  
2880                                                  
2881                                                  
2882                                                  
2883 void G4OpenGLQtViewer::addPVSceneTreeElement(    
2884                                                  
2885   const QString& modelShortName = getModelSho    
2886                                                  
2887   if (modelShortName == "") {                    
2888     return ;                                     
2889   }                                              
2890   // try to init it                              
2891   if (fSceneTreeComponentTreeWidget == NULL)     
2892     createSceneTreeComponent();                  
2893   }                                              
2894                                                  
2895   // if no UI                                    
2896   if (fSceneTreeComponentTreeWidget == NULL)     
2897     return;                                      
2898   }                                              
2899                                                  
2900   fSceneTreeComponentTreeWidget->blockSignals    
2901                                                  
2902   // Create the "volume" node if not             
2903   //  if (fSceneTreeComponentTreeWidget->topL    
2904   if (!fPVRootNodeCreate) {                      
2905     const G4Colour& color = fSceneHandler.Get    
2906                                                  
2907     fModelShortNameItem = createTreeWidgetIte    
2908                                                  
2909                                                  
2910                                                  
2911                                                  
2912                                                  
2913                                                  
2914                                                  
2915     fPVRootNodeCreate = true;                    
2916   }                                              
2917                                                  
2918   bool added = parseAndInsertInSceneTree(fMod    
2919   if (!added) {                                  
2920   }                                              
2921                                                  
2922   fSceneTreeComponentTreeWidget->blockSignals    
2923                                                  
2924 }                                                
2925                                                  
2926                                                  
2927 /**                                              
2928    if treeNode is NULL, then add this treeNod    
2929    @return the inserted item                     
2930 */                                               
2931 QTreeWidgetItem* G4OpenGLQtViewer::createTree    
2932  const PVPath& fullPath                          
2933  ,const QString& name                            
2934  ,int copyNb                                     
2935  ,int POIndex                                    
2936  ,const QString& logicalName                     
2937  ,Qt::CheckState state                           
2938  ,QTreeWidgetItem * parentTreeNode               
2939  ,const G4Colour& color                          
2940 ) {                                              
2941                                                  
2942   // Set depth                                   
2943   if (fullPath.size() > fSceneTreeDepth) {       
2944     fSceneTreeDepth = (unsigned int)fullPath.    
2945     // Change slider value                       
2946     if (fSceneTreeDepthSlider) {                 
2947       fSceneTreeDepthSlider->setTickInterval(    
2948     }                                            
2949   }                                              
2950   QTreeWidgetItem * newItem = NULL;              
2951   if (parentTreeNode == NULL) {                  
2952     newItem = new QTreeWidgetItem();             
2953     fSceneTreeComponentTreeWidget->addTopLeve    
2954   } else {                                       
2955     newItem = new QTreeWidgetItem(parentTreeN    
2956     fSceneTreeComponentTreeWidget->addTopLeve    
2957   }                                              
2958                                                  
2959                                                  
2960   newItem->setText(0,name);                      
2961   newItem->setData(1,Qt::UserRole,copyNb);       
2962   newItem->setText(2,QString::number(POIndex)    
2963   newItem->setData(0, Qt::UserRole, POIndex);    
2964   newItem->setText(3,logicalName);               
2965   newItem->setFlags(newItem->flags()|Qt::Item    
2966   newItem->setCheckState(0,state);               
2967   newItem->setExpanded(true);                    
2968   updatePositivePoIndexSceneTreeWidgetQuickMa    
2969                                                  
2970   changeQColorForTreeWidgetItem(newItem,QColo    
2971                                                  
2972                                                  
2973                                                  
2974                                                  
2975   // If invisible                                
2976   if ((state == Qt::Unchecked) && (POIndex ==    
2977     newItem->setForeground (0, QBrush( Qt::gr    
2978                                                  
2979     // Set a tootip                              
2980     newItem->setToolTip (0,QString(              
2981                                    "This node    
2982                          "drawn, perhaps beca    
2983                          "cannot be made visi    
2984                          "To see it, change t    
2985                          "/vis/geometry/set/v    
2986                          "and rebuild the vie    
2987                          "Click here will onl    
2988   } else {                                       
2989     // Set a tootip                              
2990     newItem->setToolTip (0,QString("double-cl    
2991   }                                              
2992                                                  
2993   // special case: if alpha=0, it is a totall    
2994   // then, do not redraw it                      
2995   if (color.GetAlpha() == 0) {                   
2996     state = Qt::Unchecked;                       
2997     newItem->setCheckState(0,state);             
2998     updatePositivePoIndexSceneTreeWidgetQuick    
2999   }                                              
3000                                                  
3001   fTreeItemModels.insert(std::pair <int, PVPa    
3002                                                  
3003   // Check last status of this item and chang    
3004   // open/close/hidden/visible/selected          
3005   changeOpenCloseVisibleHiddenSelectedColorSc    
3006   return newItem;                                
3007 }                                                
3008                                                  
3009                                                  
3010 //                                               
3011 //   Recursive function.                         
3012 //   Try to insert the given item :              
3013 //   - If not present and last item of the pa    
3014 //   - If not present and NOT last item of th    
3015 //   - If already present and name/PO/Transfo    
3016 //     object : Change the PO number and tran    
3017 //   - If already present and PO different, t    
3018 //     set it visible                            
3019 //   - else : Create a new element               
3020 //   @return true if inserted, false if alrea    
3021 //                                               
3022 bool G4OpenGLQtViewer::parseAndInsertInSceneT    
3023  QTreeWidgetItem * parentItem                    
3024  ,G4PhysicalVolumeModel* pPVModel                
3025  ,unsigned int fullPathIndex                     
3026  ,const QString& parentRoot                      
3027  ,unsigned int currentIndexInTreeSceneHandler    
3028  ,int currentPVPOIndex                           
3029 ) {                                              
3030                                                  
3031   if (parentItem == NULL) {                      
3032     return false;                                
3033   }                                              
3034                                                  
3035   const PVPath& fullPath = pPVModel->GetFullP    
3036                                                  
3037   std::ostringstream oss;                        
3038   oss << fullPath.at(fullPathIndex).GetCopyNo    
3039   std::string currentPVName = G4String(fullPa    
3040                                                  
3041   int currentPVCopyNb = fullPath.at(fullPathI    
3042                                                  
3043   const G4Colour& color = fSceneHandler.GetCo    
3044                                                  
3045   // look in all children in order to get if     
3046   // child corresponding:                        
3047   // - if so, go into this child                 
3048   // - if not : create it as invisible           
3049                                                  
3050   // Realy quick check if the POindex is alre    
3051   QTreeWidgetItem* subItem = NULL;               
3052   QList<QTreeWidgetItem *> parentItemList;       
3053                                                  
3054                                                  
3055   // first of all, very quick check if it was    
3056                                                  
3057   // Check only if it is a transparent object    
3058   // If it is the last item and it is not tra    
3059   // simply add it.                              
3060   if ((currentIndexInTreeSceneHandler == (ful    
3061   } else {                                       
3062     QString lookForString = QString(currentPV    
3063     for (int i = 0;i < parentItem->childCount    
3064       if (parentItem->child(i)->text(0) == lo    
3065         parentItemList.push_back(parentItem->    
3066       }                                          
3067     }                                            
3068   }                                              
3069                                                  
3070   for (int i = 0; i < parentItemList.size();     
3071     const std::string& parentItemName = paren    
3072     int parentItemCopyNb = parentItemList.at(    
3073     int parentItemPOIndex = parentItemList.at    
3074                                                  
3075     // if already inside                         
3076     // -> return true                            
3077     // special case, do not have to deal with    
3078                                                  
3079                                                  
3080     /* Physical Volume AND copy number equal     
3081     if (((parentRoot == fTouchableVolumes) &&    
3082          && (currentPVName == parentItemName)    
3083         /* NOT a Physical Volume AND  copy nu    
3084         ((parentRoot != fTouchableVolumes) &&    
3085          /*AND  name equal AND  PO index equa    
3086          && (currentPVName == parentItemName)    
3087                                                  
3088       // then check for the Transform3D          
3089       bool sameTransform = true;                 
3090       if (parentItemPOIndex >= 0) {              
3091         const PVPath& fullPathTmp = fTreeItem    
3092         if (fullPathTmp.size() > 0) {            
3093           if (fullPathTmp.at(fullPathTmp.size    
3094             sameTransform = true;                
3095           } else {                               
3096             sameTransform = false;               
3097           }                                      
3098         }                                        
3099       }                                          
3100                                                  
3101       // Same transformation, then try to cha    
3102       if (sameTransform == true) {               
3103         // already exist in the tree, is it a    
3104         // If so, then have to change the PO     
3105         // and then change the state ONLY if     
3106         // If not, then go deaper                
3107                                                  
3108         // last element                          
3109         if (currentIndexInTreeSceneHandler ==    
3110                                                  
3111           parentItemList.at(i)->setText(2,QSt    
3112           parentItemList.at(i)->setData(0, Qt    
3113                                                  
3114           fTreeItemModels.insert(std::pair <i    
3115                                                  
3116           // Then remove tooltip and special     
3117           QFont f = QFont();                     
3118           parentItemList.at(i)->setFont (0,f)    
3119                                                  
3120           // set foreground                      
3121           parentItemList.at(i)->setForeground    
3122                                                  
3123           // Set a tootip                        
3124           parentItemList.at(i)->setToolTip (0    
3125                                                  
3126           changeQColorForTreeWidgetItem(paren    
3127                                                  
3128                                                  
3129                                                  
3130                                                  
3131           // set check only if there is somet    
3132           if (color.GetAlpha() > 0) {            
3133             parentItemList.at(i)->setCheckSta    
3134             updatePositivePoIndexSceneTreeWid    
3135           }                                      
3136           return false;                          
3137         } else {                                 
3138           subItem = parentItemList.at(i);        
3139         }                                        
3140                                                  
3141         // Exists but not the end of path, th    
3142       } else if (currentIndexInTreeSceneHandl    
3143         subItem = parentItemList.at(i);          
3144       }                                          
3145     }                                            
3146                                                  
3147   } // end for                                   
3148                                                  
3149   // if it the last, then add it and set it c    
3150   if (currentIndexInTreeSceneHandler == (full    
3151     /* subItem =*/ createTreeWidgetItem(fullP    
3152                                    QString(cu    
3153                                    currentPVC    
3154                                    currentPVP    
3155                                    QString(fu    
3156                                    Qt::Checke    
3157                                    parentItem    
3158                                    color);       
3159                                                  
3160     if (currentPVPOIndex > fMaxPOindexInserte    
3161       fMaxPOindexInserted = currentPVPOIndex;    
3162     }                                            
3163                                                  
3164   } else {                                       
3165                                                  
3166     // if no child found, then this child is     
3167     if (subItem == NULL) {                       
3168                                                  
3169       if (currentIndexInTreeSceneHandler < (f    
3170         subItem = createTreeWidgetItem(fullPa    
3171                                        QStrin    
3172                                        curren    
3173                                        -1,       
3174                                        QStrin    
3175                                        Qt::Un    
3176                                        parent    
3177                                        color)    
3178       }                                          
3179     }                                            
3180                                                  
3181     return parseAndInsertInSceneTree(subItem,    
3182   }                                              
3183   return true;                                   
3184 }                                                
3185                                                  
3186                                                  
3187 void G4OpenGLQtViewer::changeOpenCloseVisible    
3188  QTreeWidgetItem* subItem                        
3189 )                                                
3190 {                                                
3191   // Check if object with the same POIndex is    
3192   QTreeWidgetItem* oldItem = NULL;               
3193                                                  
3194   QTreeWidgetItem* foundItem = getOldTreeWidg    
3195                                                  
3196   if (foundItem != NULL) {                       
3197     if (isSameSceneTreeElement(foundItem,subI    
3198       oldItem = foundItem;                       
3199     }                                            
3200   }                                              
3201   if (foundItem == NULL) {  // PO should have    
3202                                                  
3203     // POindex > 0                               
3204     std::map <int, QTreeWidgetItem*>::const_i    
3205     i = fOldPositivePoIndexSceneTreeWidgetQui    
3206     while (i != fOldPositivePoIndexSceneTreeW    
3207       if (isSameSceneTreeElement(i->second,su    
3208         oldItem = i->second;                     
3209         i = fOldPositivePoIndexSceneTreeWidge    
3210       } else {                                   
3211         ++i;                                     
3212       }                                          
3213     }                                            
3214     // POindex == 0 ?                            
3215     if (oldItem == NULL) {                       
3216       std::size_t a = 0;                         
3217       while (a < fOldNullPoIndexSceneTreeWidg    
3218         if (isSameSceneTreeElement(fOldNullPo    
3219           oldItem = fOldNullPoIndexSceneTreeW    
3220           a = fOldNullPoIndexSceneTreeWidgetQ    
3221         } else {                                 
3222           ++a;                                   
3223         }                                        
3224       }                                          
3225     }                                            
3226   }                                              
3227                                                  
3228   // if found : retore old state                 
3229   if (oldItem != NULL) {                         
3230     subItem->setFlags(oldItem->flags());   //    
3231     subItem->setCheckState(0,oldItem->checkSt    
3232     subItem->setSelected(oldItem->isSelected(    
3233     subItem->setExpanded(oldItem->isExpanded     
3234                                                  
3235     // change color                              
3236     // when we call this function, the color     
3237                                                  
3238     std::map <int, QTreeWidgetItem* >::iterat    
3239                                                  
3240     // getOldPO                                  
3241     int oldPOIndex = oldItem->data(0,Qt::User    
3242     it = fOldPositivePoIndexSceneTreeWidgetQu    
3243     QColor color;                                
3244                                                  
3245     // get old Vis Attr Color                    
3246     std::map <int, QColor >::iterator itVis;     
3247     itVis = fOldVisAttrColorMap.find(oldPOInd    
3248                                                  
3249     QColor oldVisAttrColor;                      
3250     const QColor& newVisAttrColor = subItem->    
3251                                                  
3252     bool visAttrChange = false;                  
3253     // if old vis attr color found               
3254     if (itVis != fOldVisAttrColorMap.end()) {    
3255       oldVisAttrColor = itVis->second;           
3256       if (oldVisAttrColor != newVisAttrColor)    
3257         visAttrChange = true;                    
3258       }                                          
3259     } else {                                     
3260       visAttrChange = true;                      
3261     }                                            
3262                                                  
3263     if (visAttrChange) {                         
3264       fOldVisAttrColorMap.insert(std::pair <i    
3265                                                  
3266     } else { // if no changes, get old PO val    
3267       // if old PO found                         
3268       if (it != fOldPositivePoIndexSceneTreeW    
3269         color = (it->second)->data(2,Qt::User    
3270       } else {                                   
3271         color = oldItem->data(2,Qt::UserRole)    
3272       }                                          
3273       changeQColorForTreeWidgetItem(subItem,c    
3274     }                                            
3275   }                                              
3276                                                  
3277   return;                                        
3278 }                                                
3279                                                  
3280                                                  
3281                                                  
3282 // Check if both items are identical.            
3283 // For that, check name, copy number, transfo    
3284 // special case for "non Touchables", do not     
3285 bool G4OpenGLQtViewer::isSameSceneTreeElement    
3286  QTreeWidgetItem* parentOldItem                  
3287  ,QTreeWidgetItem* parentNewItem                 
3288 ) {                                              
3289                                                  
3290   int newPO = -1;                                
3291   int oldPO = -1;                                
3292                                                  
3293   int newCpNumber = -1;                          
3294   int oldCpNumber = -1;                          
3295                                                  
3296   bool firstWhile = true;                        
3297                                                  
3298   while ((parentOldItem != NULL) && (parentNe    
3299                                                  
3300     // check transform, optimize getting data    
3301     if (!firstWhile) {                           
3302       oldPO = parentOldItem->data(0,Qt::UserR    
3303       newPO = parentNewItem->data(0,Qt::UserR    
3304     }                                            
3305     firstWhile = false;                          
3306                                                  
3307     if ((oldPO >= 0) &&                          
3308         (newPO >= 0)) {                          
3309       const PVPath& oldFullPath = fOldTreeIte    
3310       const PVPath& newFullPath = fTreeItemMo    
3311       if ((oldFullPath.size() > 0) &&            
3312           (newFullPath.size() > 0)) {            
3313         if (oldFullPath.size() != newFullPath    
3314           return false;                          
3315         }                                        
3316         if (oldFullPath.at(oldFullPath.size()    
3317           newCpNumber = newFullPath.at(newFul    
3318           oldCpNumber = oldFullPath.at(oldFul    
3319           // ok                                  
3320         } else {                                 
3321           return false;                          
3322         }                                        
3323       }                                          
3324     }                                            
3325                                                  
3326     // Check copy Number                         
3327     if (oldCpNumber == -1) {                     
3328       oldCpNumber = parentOldItem->data(1,Qt:    
3329     }                                            
3330     if (newCpNumber == -1) {                     
3331       newCpNumber = parentNewItem->data(1,Qt:    
3332     }                                            
3333     if ((oldCpNumber != newCpNumber) ||          
3334         // Check name                            
3335         (parentOldItem->text(0) != parentNewI    
3336       // try to optimize                         
3337       return false;                              
3338     } else if ((parentOldItem->text(0) != par    
3339                (parentOldItem->text(3) != par    
3340       return false;                              
3341     } else {                                     
3342       parentOldItem = parentOldItem->parent()    
3343       parentNewItem = parentNewItem->parent()    
3344     }                                            
3345   } // end while                                 
3346                                                  
3347   return true;                                   
3348 }                                                
3349                                                  
3350                                                  
3351 void G4OpenGLQtViewer::addNonPVSceneTreeEleme    
3352  const G4String& model                           
3353  ,int currentPOIndex                             
3354  ,const std::string& modelDescription            
3355  ,const G4Visible& visible                       
3356 ) {                                              
3357                                                  
3358   QString modelShortName = getModelShortName(    
3359   G4Colour color;                                
3360                                                  
3361   // Special case for text                       
3362   try {                                          
3363     const G4Text& g4Text = dynamic_cast<const    
3364     color = fSceneHandler.GetTextColour(g4Tex    
3365   }                                              
3366   catch (const std::bad_cast&) {                 
3367     color = fSceneHandler.GetColour();           
3368   }                                              
3369                                                  
3370   // Special case for marker                     
3371   try {                                          
3372     const G4VMarker& g4Marker = dynamic_cast<    
3373     if (g4Marker.GetInfo() != "") {              
3374       modelShortName = g4Marker.GetInfo();       
3375     }                                            
3376   }                                              
3377   catch (const std::bad_cast&) {}                
3378                                                  
3379   if (modelShortName == "") {                    
3380     return ;                                     
3381   }                                              
3382   // try to init it                              
3383   if (fSceneTreeComponentTreeWidget == NULL)     
3384     createSceneTreeComponent();                  
3385   }                                              
3386                                                  
3387   // if no UI                                    
3388   if (fSceneTreeComponentTreeWidget == NULL)     
3389     return;                                      
3390   }                                              
3391                                                  
3392   fSceneTreeComponentTreeWidget->blockSignals    
3393                                                  
3394   // Create the "Model" node if not              
3395                                                  
3396   QList<QTreeWidgetItem *> resItem;              
3397   resItem =  fSceneTreeComponentTreeWidget->f    
3398   QTreeWidgetItem * currentItem = NULL;          
3399   const PVPath tmpFullPath;                      
3400                                                  
3401   if (resItem.empty()) {                         
3402     currentItem = createTreeWidgetItem(tmpFul    
3403                                        modelS    
3404                                        0, //     
3405                                        -1, //    
3406                                        "",       
3407                                        Qt::Ch    
3408                                        NULL,     
3409                                        color)    
3410   } else {                                       
3411     currentItem = resItem.first();               
3412   }                                              
3413                                                  
3414   // Is this volume already in the tree AND P    
3415   const QList<QTreeWidgetItem *>&                
3416   resItems =  fSceneTreeComponentTreeWidget->    
3417                                                  
3418   bool alreadyPresent = false;                   
3419   for (int i = 0; i < resItems.size(); ++i) {    
3420     if (currentPOIndex == resItems.at(i)->dat    
3421       alreadyPresent = true;                     
3422     }                                            
3423   }                                              
3424   if (!alreadyPresent) {                         
3425     createTreeWidgetItem(tmpFullPath,            
3426                          modelShortName,         
3427                          0, // currentPVCopyN    
3428                          currentPOIndex,         
3429                          "",                     
3430                          Qt::Checked,            
3431                          currentItem,            
3432                          color);                 
3433   }                                              
3434   fSceneTreeComponentTreeWidget->blockSignals    
3435                                                  
3436 }                                                
3437                                                  
3438                                                  
3439 /**                                              
3440    Get the short name for a given label          
3441 */                                               
3442 QString G4OpenGLQtViewer::getModelShortName(c    
3443                                                  
3444   QString modelShortName = model.data();         
3445   if (modelShortName.mid(0,modelShortName.ind    
3446     modelShortName = fTouchableVolumes;          
3447   } else {                                       
3448     if (modelShortName.mid(0,2) == "G4") {       
3449       modelShortName = modelShortName.mid(2);    
3450     }                                            
3451     if (modelShortName.indexOf("Model") != -1    
3452       modelShortName = modelShortName.mid(0,m    
3453     }                                            
3454   }                                              
3455   return modelShortName;                         
3456 }                                                
3457                                                  
3458                                                  
3459                                                  
3460 bool G4OpenGLQtViewer::isTouchableVisible(int    
3461                                                  
3462   // If no scene tree (Immediate viewer)         
3463   if (fSceneTreeComponentTreeWidget == NULL)     
3464     return false;                                
3465   }                                              
3466                                                  
3467   // should be the next one                      
3468   // Prevent to get out the std::map             
3469   if (fLastSceneTreeWidgetAskForIterator != f    
3470     fLastSceneTreeWidgetAskForIterator++;        
3471   }                                              
3472   QTreeWidgetItem* item = getTreeWidgetItem(P    
3473                                                  
3474   if (item != NULL) {                            
3475     if ( item->checkState(0) == Qt::Checked)     
3476       return true;                               
3477     }                                            
3478   }                                              
3479   return false;                                  
3480 }                                                
3481                                                  
3482                                                  
3483 bool G4OpenGLQtViewer::parseAndCheckVisibilit    
3484   bool isFound = false;                          
3485   for (int i = 0; i < treeNode->childCount()     
3486                                                  
3487     if (treeNode->child(i)->data(0,Qt::UserRo    
3488       if (treeNode->child(i)->checkState(0) =    
3489         return true;                             
3490       }                                          
3491     }                                            
3492     isFound = parseAndCheckVisibility(treeNod    
3493     if (isFound) {                               
3494       return true;                               
3495     }                                            
3496   } // end for                                   
3497   return false;                                  
3498 }                                                
3499                                                  
3500                                                  
3501 std::string G4OpenGLQtViewer::parseSceneTreeA    
3502   std::string commandLine = "";                  
3503   for (int b=0;b<fSceneTreeComponentTreeWidge    
3504     commandLine += parseSceneTreeElementAndSa    
3505   }                                              
3506   if (commandLine != "") {                       
3507     commandLine = std::string("# Disable auto    
3508     "# trajectories are established:\n" +        
3509     "/vis/viewer/set/autoRefresh false\n" +      
3510     "/vis/verbose errors" +                      
3511     commandLine +                                
3512     "# Re-establish auto refreshing and verbo    
3513     "/vis/viewer/set/autoRefresh true\n" +       
3514     "/vis/verbose confirmations\n";              
3515   }                                              
3516   return commandLine;                            
3517 }                                                
3518                                                  
3519                                                  
3520 std::string G4OpenGLQtViewer::parseSceneTreeE    
3521   // parse current item                          
3522   std::string str( level, ' ' );                 
3523   std::string commandLine = "\n#"+ str + "PV     
3524                                                  
3525   if (item->text(3) != "") {                     
3526     commandLine += " LV Name: "+item->text(3)    
3527     // save check state                          
3528     commandLine += "/vis/geometry/set/visibil    
3529     if (item->checkState(0) == Qt::Checked) {    
3530       commandLine += "1";                        
3531     }                                            
3532     if (item->checkState(0) == Qt::Unchecked)    
3533       commandLine += "0";                        
3534     }                                            
3535     commandLine +="\n";                          
3536                                                  
3537     // save color                                
3538     const QColor& c = item->data(2,Qt::UserRo    
3539     std::stringstream red;                       
3540     red << ((double)c.red())/255;                
3541     std::stringstream green;                     
3542     green << (double)c.green()/255;              
3543     std::stringstream blue;                      
3544     blue << ((double)c.blue())/255;              
3545     std::stringstream alpha;                     
3546     alpha << ((double)c.alpha())/255;            
3547                                                  
3548     commandLine += "/vis/geometry/set/colour     
3549                                                  
3550   } else {                                       
3551     commandLine += "\n";                         
3552   }                                              
3553                                                  
3554   // parse childs                                
3555   for (int b=0;b< item->childCount();b++) {      
3556     commandLine += parseSceneTreeElementAndSa    
3557   }                                              
3558                                                  
3559   return commandLine;                            
3560 }                                                
3561                                                  
3562                                                  
3563 void G4OpenGLQtViewer::sceneTreeComponentItem    
3564                                                  
3565   if (fCheckSceneTreeComponentSignalLock == f    
3566     fCheckSceneTreeComponentSignalLock = true    
3567     G4bool checked = false;                      
3568     if (item->checkState(0) == Qt::Checked) {    
3569       checked = true;                            
3570     }                                            
3571     setCheckComponent(item,checked);             
3572     updateQWidget();                             
3573                                                  
3574     fCheckSceneTreeComponentSignalLock = fals    
3575   }                                              
3576 }                                                
3577                                                  
3578                                                  
3579 void G4OpenGLQtViewer::sceneTreeComponentSele    
3580 }                                                
3581                                                  
3582 void G4OpenGLQtViewer::changeDepthInSceneTree    
3583                                                  
3584   // If no scene tree (Immediate viewer)         
3585   if (fSceneTreeComponentTreeWidget == NULL)     
3586     return;                                      
3587   }                                              
3588                                                  
3589   // max depth :   fSceneTreeDepth               
3590   // val is between 0 and 1                      
3591   // 0  .1  .2  .3  .4  .5  .6  .7  .8  .9  1    
3592   // 1      1.4          2                       
3593   // 1         2         3         4             
3594                                                  
3595   // Get the depth :                             
3596   double depth = 1 + ((double)val)/1000 * ((d    
3597                                                  
3598   // lock update on scene tree items             
3599   fCheckSceneTreeComponentSignalLock = true;     
3600                                                  
3601   // Disable redraw each time !                  
3602   G4bool currentAutoRefresh = fVP.IsAutoRefre    
3603   fVP.SetAutoRefresh(false);                     
3604                                                  
3605   for (int b=0;b<fSceneTreeComponentTreeWidge    
3606     changeDepthOnSceneTreeItem(depth,1.,fScen    
3607   }                                              
3608                                                  
3609   // Enable redraw !                             
3610   fVP.SetAutoRefresh(currentAutoRefresh);        
3611   updateQWidget();                               
3612                                                  
3613   // unlock update on scene tree items           
3614   fCheckSceneTreeComponentSignalLock = false;    
3615                                                  
3616 }                                                
3617                                                  
3618                                                  
3619 void G4OpenGLQtViewer::changeColorAndTranspar    
3620                                                  
3621   if (item == NULL) {                            
3622     return;                                      
3623   }                                              
3624   const QColor& old = QColor(item->data(2,Qt:    
3625                                                  
3626   const QColor& color = QColorDialog::getColo    
3627                                         fScen    
3628                                         " Get    
3629                                         QColo    
3630                                                  
3631   if (color.isValid()) {                         
3632                                                  
3633     changeColorAndTransparency(item->data(0,Q    
3634                                G4Colour (((G4    
3635                                          ((G4    
3636                                          ((G4    
3637                                          ((G4    
3638                                                  
3639     // set scene tree parameters                 
3640     changeQColorForTreeWidgetItem(item,color)    
3641   }                                              
3642 }                                                
3643                                                  
3644                                                  
3645 void G4OpenGLQtViewer::changeColorAndTranspar    
3646                                                  
3647   // change vis attributes to set new colour     
3648   G4int iPO = index;                             
3649   if (iPO >= 0 && fTreeItemModels.find(iPO) !    
3650     const PVPath& fullPath = fTreeItemModels[    
3651     // If a physical volume                      
3652     if (fullPath.size()) {                       
3653       SetTouchable(fullPath);                    
3654       TouchableSetColour(fullPath, color);       
3655       fMouseOnSceneTree = true;                  
3656     }                                            
3657   }                                              
3658 }                                                
3659                                                  
3660                                                  
3661 G4Colour G4OpenGLQtViewer::getColorForPoIndex    
3662   // FIXME 09/2014 : Could be optimize by sea    
3663   QTreeWidgetItem* item = getTreeWidgetItem(p    
3664                                                  
3665   if (item != NULL) {                            
3666                                                  
3667     const QColor& color = item->data(2,Qt::Us    
3668     G4Colour g4c(((G4double)color.red())/255,    
3669                  ((G4double)color.green())/25    
3670                  ((G4double)color.blue())/255    
3671                  ((G4double)color.alpha())/25    
3672                                                  
3673     return g4c;                                  
3674   }                                              
3675   return G4Colour();                             
3676 }                                                
3677                                                  
3678                                                  
3679 const std::vector<G4ModelingParameters::VisAt    
3680 G4OpenGLQtViewer::GetPrivateVisAttributesModi    
3681 {                                                
3682   static std::vector<G4ModelingParameters::Vi    
3683   privateVisAttributesModifiers;                 
3684                                                  
3685   privateVisAttributesModifiers.clear();         
3686                                                  
3687 // I don't think we need this.  (JA Sep 2016)    
3688 //  // For each modified touchable...            
3689 //  std::map<int,PVPath>::const_iterator i;      
3690 //  for (i = fTreeItemModels.begin();            
3691 //       i != fTreeItemModels.end();             
3692 //       ++i) {                                  
3693 //                                               
3694 //    // How do I know if it's been modified     
3695 //                                               
3696 //    int iPO = i->first;                        
3697 //    const PVPath& fullPath = i->second;        
3698 //                                               
3699 //    // If a physical volume                    
3700 //    if (fullPath.size()) {                     
3701 //                                               
3702 //      //    const G4bool& visibilityChanged    
3703 //      //    const G4bool& visibility = ???     
3704 //      //    const G4bool& colourChanged = ?    
3705 //      //    const QColor& colour = ???         
3706 //      //    G4Colour g4colour(((G4double)co    
3707 //      //                      ((G4double)co    
3708 //      //                      ((G4double)co    
3709 //      //                      ((G4double)co    
3710 //      // Next 4 lines are for testing, to b    
3711 //      G4bool visibilityChanged = true;         
3712 //      G4bool visibility = true;                
3713 //      G4bool colourChanged = true;             
3714 //      G4Colour g4colour(G4Colour::Red());      
3715 //                                               
3716 //      // Instantiate a working copy of a G4    
3717 //      G4VisAttributes workingVisAtts;          
3718 //      // ...and use it to create vis attrib    
3719 //      if (visibilityChanged) {                 
3720 //        workingVisAtts.SetVisibility(visibi    
3721 //        privateVisAttributesModifiers.push_    
3722 //        (G4ModelingParameters::VisAttribute    
3723 //         (workingVisAtts,                      
3724 //          G4ModelingParameters::VASVisibili    
3725 //          fullPath));                          
3726 //      }                                        
3727 //      if (colourChanged) {                     
3728 //        workingVisAtts.SetColour(g4colour);    
3729 //        privateVisAttributesModifiers.push_    
3730 //        (G4ModelingParameters::VisAttribute    
3731 //         (workingVisAtts,                      
3732 //          G4ModelingParameters::VASColour,     
3733 //          fullPath));                          
3734 //      }                                        
3735 //    }                                          
3736 //  }                                            
3737                                                  
3738   return &privateVisAttributesModifiers;         
3739 }                                                
3740                                                  
3741                                                  
3742 void G4OpenGLQtViewer::changeSearchSelection(    
3743 {                                                
3744   const QString& searchText = fFilterOutput->    
3745   if (fSceneTreeComponentTreeWidget == NULL)     
3746     return;                                      
3747   }                                              
3748                                                  
3749   // unselect all                                
3750   for (int a=0; a<fSceneTreeComponentTreeWidg    
3751     fSceneTreeComponentTreeWidget->topLevelIt    
3752     fSceneTreeComponentTreeWidget->topLevelIt    
3753     clearSceneTreeSelection(fSceneTreeCompone    
3754   }                                              
3755                                                  
3756   QList<QTreeWidgetItem *> itemList = fSceneT    
3757                                                  
3758   for (int i = 0; i < itemList.size(); ++i) {    
3759     QTreeWidgetItem* expandParentItem = itemL    
3760     while (expandParentItem->parent() != NULL    
3761       expandParentItem->parent()->setExpanded    
3762       expandParentItem = expandParentItem->pa    
3763     }                                            
3764     itemList.at(i)->setSelected(true);           
3765   }                                              
3766                                                  
3767 }                                                
3768                                                  
3769                                                  
3770 void G4OpenGLQtViewer::clearSceneTreeSelectio    
3771   for (int a=0; a<item->childCount(); a++) {     
3772     item->child(a)->setSelected(false);          
3773     item->child(a)->setExpanded(false);          
3774     clearSceneTreeSelection(item->child(a));     
3775   }                                              
3776                                                  
3777 }                                                
3778                                                  
3779                                                  
3780 bool G4OpenGLQtViewer::isPVVolume(QTreeWidget    
3781   QTreeWidgetItem* sParent = item;               
3782   while (sParent->parent() != NULL) {            
3783     sParent = sParent->parent();                 
3784   }                                              
3785   if (sParent->text(0) != fTouchableVolumes)     
3786     return false;                                
3787   }                                              
3788   // item is the "Touchable" node                
3789   if (item->text(0) == fTouchableVolumes) {      
3790     return false;                                
3791   }                                              
3792   return true;                                   
3793 }                                                
3794                                                  
3795                                                  
3796 void G4OpenGLQtViewer::changeDepthOnSceneTree    
3797  double lookForDepth                             
3798  ,double currentDepth                            
3799  ,QTreeWidgetItem* item                          
3800 ) {                                              
3801   double transparencyLevel = 0.;                 
3802                                                  
3803   // look for a 2.2 depth and we are at level    
3804   // -> Set all theses items to Opaque           
3805   // ONLY if it is a PV volume !                 
3806   if (isPVVolume(item)) {                        
3807     if ((lookForDepth-currentDepth) < 0) {       
3808       item->setCheckState(0,Qt::Checked);        
3809       updatePositivePoIndexSceneTreeWidgetQui    
3810       transparencyLevel = 1;                     
3811     } else if ((lookForDepth-currentDepth) >     
3812       item->setCheckState(0,Qt::Unchecked);      
3813       updatePositivePoIndexSceneTreeWidgetQui    
3814       transparencyLevel = 0;                     
3815     } else {                                     
3816       item->setCheckState(0,Qt::Checked);        
3817       updatePositivePoIndexSceneTreeWidgetQui    
3818       transparencyLevel = 1-(lookForDepth-cur    
3819     }                                            
3820   }                                              
3821                                                  
3822   if (item->data(0,Qt::UserRole).toInt() >= 0    
3823     const G4Colour& color = getColorForPoInde    
3824                                                  
3825     // We are less depper (ex:tree depth:2) t    
3826     // -> Have to hide this level ONLY if it     
3827                                                  
3828     // Not on a top level item case              
3829     // Do not set if it was already set          
3830                                                  
3831     // Should add them all the time in case o    
3832     // before. Should be checked in changeDep    
3833     // Do not change transparency if not visi    
3834     // problems..)                               
3835     if (((color.GetAlpha()-transparencyLevel)    
3836         ((color.GetAlpha()-transparencyLevel)    
3837       if ((item->text(3) != "")) {               
3838         // FIXME : Should not test this here     
3839         // volume that will came after and wi    
3840         // Good thing to do is to check and s    
3841         // and then check if last (transparen    
3842                                                  
3843         changeQColorForTreeWidgetItem(item,QC    
3844                                                  
3845                                                  
3846                                                  
3847       }                                          
3848     }                                            
3849   }                                              
3850                                                  
3851   for (int b=0;b< item->childCount();b++) {      
3852     changeDepthOnSceneTreeItem(lookForDepth,c    
3853   }                                              
3854 }                                                
3855                                                  
3856                                                  
3857 void G4OpenGLQtViewer::clearTreeWidget(){        
3858   // be careful about calling this twice         
3859                                                  
3860   if (fSceneTreeComponentTreeWidget) {           
3861                                                  
3862     if (fSceneTreeComponentTreeWidget->topLev    
3863                                                  
3864       fPVRootNodeCreate = false;                 
3865                                                  
3866       // reset all old                           
3867       fOldPositivePoIndexSceneTreeWidgetQuick    
3868       fOldNullPoIndexSceneTreeWidgetQuickVect    
3869       fOldTreeItemModels.clear();                
3870                                                  
3871       // Clone everything                        
3872       for (int b =0; b <fSceneTreeComponentTr    
3873         // All tree widgets are in :             
3874         // then we could get the old POindex     
3875         // .visible/Hidden                       
3876         // .Check/Uncheck                        
3877         // .selected                             
3878         // .colour status from std::map          
3879                                                  
3880         // clone top level items                 
3881         int poIndex = fSceneTreeComponentTree    
3882         if (poIndex != -1) {                     
3883           fOldPositivePoIndexSceneTreeWidgetQ    
3884         } else {                                 
3885           fOldNullPoIndexSceneTreeWidgetQuick    
3886         }                                        
3887                                                  
3888         // clone leaves                          
3889         cloneSceneTree(fSceneTreeComponentTre    
3890       }                                          
3891       // delete all elements                     
3892                                                  
3893       fOldTreeItemModels.insert(fTreeItemMode    
3894                                                  
3895       // all is copy, then clear scene tree      
3896       int tmp2 = fSceneTreeComponentTreeWidge    
3897       while (tmp2 > 0) {                         
3898         delete fSceneTreeComponentTreeWidget-    
3899         tmp2 = fSceneTreeComponentTreeWidget-    
3900       }                                          
3901       fPositivePoIndexSceneTreeWidgetQuickMap    
3902                                                  
3903       // put correct value in paramaters         
3904       fOldLastSceneTreeWidgetAskForIterator =    
3905       fOldLastSceneTreeWidgetAskForIteratorEn    
3906       fSceneTreeDepth = 1;                       
3907       fModelShortNameItem = NULL;                
3908       fMaxPOindexInserted = -1;                  
3909                                                  
3910     }                                            
3911   }                                              
3912 }                                                
3913                                                  
3914                                                  
3915 /**                                              
3916    Clone :                                       
3917    - Open/close                                  
3918    - Visible/hidden                              
3919    - Selected                                    
3920 */                                               
3921 QTreeWidgetItem * G4OpenGLQtViewer::cloneWidg    
3922                                                  
3923   QTreeWidgetItem* cloneItem = new QTreeWidge    
3924                                                  
3925   // Clone what is create createTreeWidgetIte    
3926                                                  
3927   cloneItem->setText(0,item->text(0));           
3928   cloneItem->setData(1,Qt::UserRole,item->dat    
3929   cloneItem->setText(2,item->text(2));           
3930   cloneItem->setData(0, Qt::UserRole,item->da    
3931   cloneItem->setText(3,item->text(3));           
3932   cloneItem->setFlags(item->flags());            
3933   cloneItem->setToolTip(0,item->toolTip(0));     
3934   cloneItem->setCheckState(0,item->checkState    
3935   cloneItem->setSelected(item->isSelected());    
3936   cloneItem->setExpanded(item->isExpanded ())    
3937                                                  
3938   cloneItem->setData(2,Qt::UserRole,item->dat    
3939                                                  
3940   return cloneItem;                              
3941 }                                                
3942                                                  
3943                                                  
3944 /**                                              
3945    Clone the current tree in order to get a s    
3946 */                                               
3947 void G4OpenGLQtViewer::cloneSceneTree(           
3948  QTreeWidgetItem* rootItem                       
3949 ) {                                              
3950                                                  
3951   for (int b=0;b< rootItem->childCount();b++)    
3952                                                  
3953     QTreeWidgetItem *child = rootItem->child(    
3954                                                  
3955     // clone top level items                     
3956     int poIndex = child->data(0,Qt::UserRole)    
3957     if (poIndex != -1) {                         
3958       fOldPositivePoIndexSceneTreeWidgetQuick    
3959     } else {                                     
3960       fOldNullPoIndexSceneTreeWidgetQuickVect    
3961     }                                            
3962     cloneSceneTree(child);                       
3963   }                                              
3964 }                                                
3965                                                  
3966                                                  
3967 /**                                              
3968    Update the quick scene tree visibility map    
3969 */                                               
3970  void G4OpenGLQtViewer::updatePositivePoIndex    
3971                                                  
3972    // Check state                                
3973    std::map <int, QTreeWidgetItem*>::iterator    
3974    i = fPositivePoIndexSceneTreeWidgetQuickMa    
3975                                                  
3976    if (i == fPositivePoIndexSceneTreeWidgetQu    
3977      fPositivePoIndexSceneTreeWidgetQuickMap.    
3978      fLastSceneTreeWidgetAskForIterator = fPo    
3979      fLastSceneTreeWidgetAskForIteratorEnd =     
3980    } else {                                      
3981      i->second = item;                           
3982    }                                             
3983  }                                               
3984                                                  
3985                                                  
3986                                                  
3987 void G4OpenGLQtViewer::changeQColorForTreeWid    
3988                                                  
3989   int POIndex = item->data(0,Qt::UserRole).to    
3990   updatePositivePoIndexSceneTreeWidgetQuickMa    
3991                                                  
3992   QPixmap pixmap = QPixmap(QSize(16, 16));       
3993   if (item->data(0,Qt::UserRole).toInt() != -    
3994     pixmap.fill (qc);                            
3995   } else {                                       
3996     pixmap.fill (QColor(255,255,255,255));       
3997   }                                              
3998   QPainter painter(&pixmap);                     
3999   painter.setPen(Qt::black);                     
4000   painter.drawRect(0,0,15,15); // Draw contou    
4001                                                  
4002   item->setIcon(0,pixmap);                       
4003   item->setData(2,Qt::UserRole,qc);              
4004 }                                                
4005                                                  
4006                                                  
4007                                                  
4008 /**                                              
4009    @return the corresponding item if existing    
4010    Look into fPositivePoIndexSceneTreeWidgetQ    
4011  */                                              
4012 QTreeWidgetItem* G4OpenGLQtViewer::getTreeWid    
4013                                                  
4014   // -1 is not a visible item                    
4015   if (POindex == -1) {                           
4016     return NULL;                                 
4017   }                                              
4018                                                  
4019   if (fPositivePoIndexSceneTreeWidgetQuickMap    
4020     return NULL;                                 
4021   }                                              
4022                                                  
4023   if (fLastSceneTreeWidgetAskForIterator != f    
4024     if (POindex == fLastSceneTreeWidgetAskFor    
4025       if (fLastSceneTreeWidgetAskForIterator-    
4026         return fLastSceneTreeWidgetAskForIter    
4027       }                                          
4028     }                                            
4029   }                                              
4030                                                  
4031   // if not, use the "find" algorithm            
4032   fLastSceneTreeWidgetAskForIterator = fPosit    
4033   fLastSceneTreeWidgetAskForIteratorEnd = fPo    
4034                                                  
4035   if (fLastSceneTreeWidgetAskForIterator != f    
4036     return fLastSceneTreeWidgetAskForIterator    
4037   }                                              
4038   return NULL;                                   
4039 }                                                
4040                                                  
4041 /**                                              
4042    @return the corresponding item if existing    
4043    Look into fOldPositivePoIndexSceneTreeWidg    
4044  */                                              
4045 QTreeWidgetItem* G4OpenGLQtViewer::getOldTree    
4046                                                  
4047                                                  
4048   // -1 is not a visible item                    
4049   if (POindex == -1) {                           
4050     return NULL;                                 
4051   }                                              
4052                                                  
4053   if (fOldPositivePoIndexSceneTreeWidgetQuick    
4054     return NULL;                                 
4055   }                                              
4056                                                  
4057   // Should be call only once by item additio    
4058   // Prevent to get out the std::map             
4059   if (fOldLastSceneTreeWidgetAskForIterator !    
4060     fOldLastSceneTreeWidgetAskForIterator++;     
4061   }                                              
4062                                                  
4063   if (fOldLastSceneTreeWidgetAskForIterator !    
4064     if (POindex == fOldLastSceneTreeWidgetAsk    
4065       if (fOldLastSceneTreeWidgetAskForIterat    
4066         return fOldLastSceneTreeWidgetAskForI    
4067       }                                          
4068     }                                            
4069   }                                              
4070                                                  
4071   // if not, use the "find" algorithm            
4072   fOldLastSceneTreeWidgetAskForIterator = fOl    
4073   fOldLastSceneTreeWidgetAskForIteratorEnd =     
4074                                                  
4075   if (fOldLastSceneTreeWidgetAskForIterator !    
4076     return fOldLastSceneTreeWidgetAskForItera    
4077   }                                              
4078   return NULL;                                   
4079 }                                                
4080                                                  
4081                                                  
4082                                                  
4083 /**                                              
4084    Should replace actual tree by the one in t    
4085    and update tree                               
4086 */                                               
4087 void G4OpenGLQtViewer::displaySceneTreeCompon    
4088   // no UI                                       
4089   if (fUISceneTreeWidget == NULL) {              
4090     return;                                      
4091   }                                              
4092   if (fSceneTreeComponentTreeWidget == NULL)     
4093     return;                                      
4094   }                                              
4095                                                  
4096   // sort tree items                             
4097   fSceneTreeComponentTreeWidget->sortItems (0    
4098                                                  
4099   return;                                        
4100 }                                                
4101                                                  
4102                                                  
4103 /**                                              
4104    Update the toolbar Icons/Mouse context men    
4105    - Change ortho/perspective                    
4106    - Change surface style                        
4107    - Change cursor style                         
4108  */                                              
4109 void G4OpenGLQtViewer::updateToolbarAndMouseC    
4110    if (fBatchMode) {                             
4111      return;                                     
4112    }                                             
4113                                                  
4114   G4ViewParameters::DrawingStyle                 
4115   d_style = fVP.GetDrawingStyle();               
4116                                                  
4117   // Surface style                               
4118   if (d_style == G4ViewParameters::wireframe)    
4119     if (fUiQt) fUiQt->SetIconWireframeSelecte    
4120     if (fContextMenu) {                          
4121       fDrawingWireframe->setChecked(true);       
4122       fDrawingLineRemoval->setChecked(false);    
4123       fDrawingSurfaceRemoval->setChecked(fals    
4124       fDrawingLineSurfaceRemoval->setChecked(    
4125     }                                            
4126   } else if (d_style == G4ViewParameters::hlr    
4127     if (fUiQt) fUiQt->SetIconHLRSelected();      
4128     if (fContextMenu) {                          
4129       fDrawingLineRemoval->setChecked(true);     
4130       fDrawingWireframe->setChecked(false);      
4131       fDrawingSurfaceRemoval->setChecked(fals    
4132       fDrawingLineSurfaceRemoval->setChecked(    
4133     }                                            
4134   } else if (d_style == G4ViewParameters::hsr    
4135     if (fUiQt) fUiQt->SetIconSolidSelected();    
4136     if (fContextMenu) {                          
4137       fDrawingSurfaceRemoval->setChecked(true    
4138       fDrawingWireframe->setChecked(false);      
4139       fDrawingLineRemoval->setChecked(false);    
4140       fDrawingLineSurfaceRemoval->setChecked(    
4141     }                                            
4142   } else if (d_style == G4ViewParameters::hlh    
4143     if (fUiQt) fUiQt->SetIconHLHSRSelected();    
4144     if (fContextMenu) {                          
4145       fDrawingLineSurfaceRemoval->setChecked(    
4146       fDrawingWireframe->setChecked(false);      
4147       fDrawingLineRemoval->setChecked(false);    
4148       fDrawingSurfaceRemoval->setChecked(fals    
4149       fDrawingLineSurfaceRemoval->setChecked(    
4150     }                                            
4151   }                                              
4152                                                  
4153                                                  
4154   // projection style                            
4155   G4double d_proj = fVP.GetFieldHalfAngle ()     
4156   if (d_proj == 0.) { // ortho                   
4157     if (fUiQt) fUiQt->SetIconOrthoSelected();    
4158     if (fContextMenu) {                          
4159       fProjectionOrtho->setChecked(true);        
4160       fProjectionPerspective->setChecked(fals    
4161     }                                            
4162   } else {                                       
4163     if (fUiQt) fUiQt->SetIconPerspectiveSelec    
4164       if (fContextMenu) {                        
4165         fProjectionPerspective->setChecked(tr    
4166         fProjectionOrtho->setChecked(false);     
4167       }                                          
4168   }                                              
4169                                                  
4170                                                  
4171   // mouse style : They are controlled by UI     
4172   if (fUiQt && fContextMenu) {                   
4173     if (fUiQt->IsIconPickSelected()) {           
4174       fMousePickAction->setChecked(true);        
4175       fMouseZoomOutAction->setChecked(false);    
4176       fMouseZoomInAction->setChecked(false);     
4177       fMouseRotateAction->setChecked(false);     
4178       fMouseMoveAction->setChecked(false);       
4179     } else if (fUiQt->IsIconZoomOutSelected()    
4180       fMouseZoomOutAction->setChecked(true);     
4181       fMousePickAction->setChecked(false);       
4182       fMouseZoomInAction->setChecked(false);     
4183       fMouseRotateAction->setChecked(false);     
4184       fMouseMoveAction->setChecked(false);       
4185     } else if (fUiQt->IsIconZoomInSelected())    
4186       fMouseZoomInAction->setChecked(true);      
4187       fMousePickAction->setChecked(false);       
4188       fMouseZoomOutAction->setChecked(false);    
4189       fMouseRotateAction->setChecked(false);     
4190       fMouseMoveAction->setChecked(false);       
4191     } else if (fUiQt->IsIconRotateSelected())    
4192       fMouseRotateAction->setChecked(true);      
4193       fMousePickAction->setChecked(false);       
4194       fMouseZoomOutAction->setChecked(false);    
4195       fMouseZoomInAction->setChecked(false);     
4196       fMouseMoveAction->setChecked(false);       
4197     } else if (fUiQt->IsIconMoveSelected()) {    
4198       fMouseMoveAction->setChecked(true);        
4199       fMousePickAction->setChecked(false);       
4200       fMouseZoomOutAction->setChecked(false);    
4201       fMouseZoomInAction->setChecked(false);     
4202       fMouseRotateAction->setChecked(false);     
4203     }                                            
4204   }                                              
4205 }                                                
4206                                                  
4207                                                  
4208 /**                                              
4209  Update the scene tree widget                    
4210  */                                              
4211 void G4OpenGLQtViewer::updateSceneTreeWidget(    
4212   // Ensure case where closing a UI tab close    
4213   if (!fSceneTreeWidget) {                       
4214     createSceneTreeWidget();                     
4215   }                                              
4216 }                                                
4217                                                  
4218                                                  
4219   /**                                            
4220  Update the viewer properties component widge    
4221  Clear it only if the number of command is le    
4222  */                                              
4223 void G4OpenGLQtViewer::updateViewerProperties    
4224                                                  
4225   if (!isCurrentWidget()) {                      
4226     return;                                      
4227   }                                              
4228                                                  
4229   // Ensure case where closing a UI tab close    
4230   if (!fViewerPropertiesTableWidget) {           
4231     createViewerPropertiesWidget();              
4232   }                                              
4233   int treeWidgetInfosIgnoredCommands = 0;        
4234   G4UImanager* UI = G4UImanager::GetUIpointer    
4235   G4UIcommandTree * commandTreeTop = UI->GetT    
4236   G4UIcommandTree* path = commandTreeTop->Fin    
4237                                                  
4238   if (!path) {                                   
4239     return;                                      
4240   }                                              
4241                                                  
4242   // clear old table                             
4243   if ((path->GetCommandEntry()-fTreeWidgetInf    
4244     fViewerPropertiesTableWidget->clear();       
4245   }                                              
4246                                                  
4247   fViewerPropertiesTableWidget->blockSignals(    
4248   // TODO : Could be optimized by comparing c    
4249                                                  
4250   fViewerPropertiesTableWidget->setColumnCoun    
4251   fViewerPropertiesTableWidget->setRowCount (    
4252   fViewerPropertiesTableWidget->setHorizontal    
4253                                                  
4254   fViewerPropertiesTableWidget->verticalHeade    
4255   fViewerPropertiesTableWidget->setAlternatin    
4256                                                  
4257   // For the moment, we do only command that     
4258                                                  
4259   for (int a=0;a<path->GetCommandEntry();a++)    
4260     G4UIcommand* commandTmp = path->GetComman    
4261                                                  
4262     // get current parameters                    
4263     QString params = "";                         
4264                                                  
4265     if(commandTmp->GetCommandName() == "autoR    
4266       if (fVP.IsAutoRefresh()) {                 
4267         params = "True";                         
4268       } else {                                   
4269         params = "False";                        
4270       }                                          
4271     } else if(commandTmp->GetCommandName() ==    
4272       if (fVP.IsAuxEdgeVisible()) {              
4273         params = "True";                         
4274       } else {                                   
4275         params = "False";                        
4276       }                                          
4277     } else if(commandTmp->GetCommandName() ==    
4278       params = QString().number(fVP.GetBackgr    
4279       QString().number(fVP.GetBackgroundColou    
4280       QString().number(fVP.GetBackgroundColou    
4281       QString().number(fVP.GetBackgroundColou    
4282                                                  
4283     } else if(commandTmp->GetCommandName() ==    
4284       params = QString().number(fVP. IsCullin    
4285     } else if(commandTmp->GetCommandName() ==    
4286       if (fVP.GetCutawayMode() == G4ViewParam    
4287         params = "union";                        
4288       } else {                                   
4289         params = "intersection";                 
4290       }                                          
4291                                                  
4292     } else if(commandTmp->GetCommandName() ==    
4293       params = QString().number(fVP.GetDefaul    
4294       QString().number(fVP.GetDefaultVisAttri    
4295       QString().number(fVP.GetDefaultVisAttri    
4296       QString().number(fVP.GetDefaultVisAttri    
4297                                                  
4298     } else if(commandTmp->GetCommandName() ==    
4299       params = QString().number(fVP.GetDefaul    
4300       QString().number(fVP.GetDefaultTextVisA    
4301       QString().number(fVP.GetDefaultTextVisA    
4302       QString().number(fVP.GetDefaultTextVisA    
4303                                                  
4304     } else if(commandTmp->GetCommandName() ==    
4305       G4ViewParameters::DrawingStyle existing    
4306       params = "False";                          
4307       if (existingStyle == G4ViewParameters::    
4308         params = "True";                         
4309       }                                          
4310                                                  
4311     } else if(commandTmp->GetCommandName() ==    
4312       params = QString().number(fVP.GetExplod    
4313                                                  
4314     } else if(commandTmp->GetCommandName() ==    
4315       params = QString().number(fVP.GetGlobal    
4316                                                  
4317     } else if(commandTmp->GetCommandName() ==    
4318       params = QString().number(fVP.GetGlobal    
4319                                                  
4320     } else if(commandTmp->GetCommandName() ==    
4321       G4ViewParameters::DrawingStyle style =     
4322       if ((style == G4ViewParameters::hlr) ||    
4323           (style == G4ViewParameters::hlhsr))    
4324         params = "True";                         
4325       } else {                                   
4326         params = "False";                        
4327       }                                          
4328                                                  
4329     } else if(commandTmp->GetCommandName() ==    
4330       if (fVP.IsMarkerNotHidden()) {             
4331         params = "False";                        
4332       } else {                                   
4333         params = "True";                         
4334       }                                          
4335                                                  
4336     } else if(commandTmp->GetCommandName() ==    
4337       if (fVP.GetLightsMoveWithCamera()) {       
4338         params = "camera";                       
4339       } else {                                   
4340         params = "object";                       
4341       }                                          
4342     } else if(commandTmp->GetCommandName() ==    
4343       G4Vector3D direction = fVP.GetLightpoin    
4344       // degree                                  
4345       params = QString().number(direction.the    
4346       if (commandTmp->GetParameterEntries() =    
4347         if (commandTmp->GetParameter(2)->GetD    
4348           params = QString().number(direction    
4349         }                                        
4350       }                                          
4351     } else if(commandTmp->GetCommandName() ==    
4352      params = QString().number(fVP.GetLightpo    
4353       QString().number(fVP.GetLightpointDirec    
4354       QString().number(fVP.GetLightpointDirec    
4355                                                  
4356     } else if(commandTmp->GetCommandName() ==    
4357       params = QString().number(fVP.GetNoOfSi    
4358                                                  
4359     } else if(commandTmp->GetCommandName() ==    
4360       if (fVP.IsPicking()) {                     
4361         params = "True";                         
4362       } else {                                   
4363         params = "False";                        
4364       }                                          
4365                                                  
4366     } else if(commandTmp->GetCommandName() ==    
4367       if (fVP.GetFieldHalfAngle() == 0.) {       
4368         params = "orthogonal";                   
4369       } else {                                   
4370         params = QString("perspective ") + QS    
4371       }                                          
4372                                                  
4373     } else if(commandTmp->GetCommandName() ==    
4374       if (fVP.GetRotationStyle() == G4ViewPar    
4375         params = "constrainUpDirection";         
4376       } else {                                   
4377         params = "freeRotation";                 
4378       }                                          
4379                                                  
4380     } else if(commandTmp->GetCommandName() ==    
4381       if (fVP.IsSection()) {                     
4382         params =  QString("on ") +               
4383         G4String(G4BestUnit(fVP.GetSectionPla    
4384         QString().number(fVP.GetSectionPlane(    
4385         + " " + QString().number(fVP.GetSecti    
4386         + " " + QString().number(fVP.GetSecti    
4387       } else {                                   
4388         params = "off";                          
4389       }                                          
4390                                                  
4391     } else if(commandTmp->GetCommandName() ==    
4392       if (fVP.GetDrawingStyle() == G4ViewPara    
4393          params = "wireframe";                   
4394       } else {                                   
4395         params = "surface";                      
4396       }                                          
4397                                                  
4398                                                  
4399     } else if(commandTmp->GetCommandName() ==    
4400       G4Point3D point = fVP.GetCurrentTargetP    
4401       if (fSceneHandler.GetScene()) {            
4402         G4String b = G4BestUnit(fSceneHandler    
4403         params = b.data();                       
4404       }                                          
4405     } else if(commandTmp->GetCommandName() ==    
4406       G4Vector3D up = fVP.GetUpVector();         
4407       // degree                                  
4408       params = QString().number(up.theta()/CL    
4409       if (commandTmp->GetParameterEntries() =    
4410         if (commandTmp->GetParameter(2)->GetD    
4411           params = QString().number(up.theta(    
4412         }                                        
4413       }                                          
4414     } else if(commandTmp->GetCommandName() ==    
4415       G4Vector3D up = fVP.GetUpVector();         
4416       params = QString().number(up.x())+ "  "    
4417                                                  
4418     } else if(commandTmp->GetCommandName() ==    
4419       G4Vector3D direction = fVP.GetViewpoint    
4420       // degree                                  
4421       params = QString().number(direction.the    
4422       if (commandTmp->GetParameterEntries() =    
4423         if (commandTmp->GetParameter(2)->GetD    
4424           params = QString().number(direction    
4425         }                                        
4426       }                                          
4427     } else if(commandTmp->GetCommandName() ==    
4428       G4Vector3D direction = fVP.GetViewpoint    
4429       params = QString().number(direction.x()    
4430     } else {                                     
4431       // No help                                 
4432     }                                            
4433                                                  
4434     /* DO NOT DISPLAY COMMANDS WITHOUT ANY PA    
4435     if (params == "") {                          
4436       // TODO : display default parameters //    
4437                                                  
4438       for( G4int i_thParameter=0; i_thParamet    
4439         commandParam = commandTmp->GetParamet    
4440                                                  
4441         if (QString(QChar(commandParam->GetPa    
4442           if (commandParam->GetDefaultValue()    
4443             params += "True";                    
4444           } else {                               
4445             params += "False";                   
4446           }                                      
4447         } else {                                 
4448           params += QString((char*)(commandPa    
4449         }                                        
4450         if (i_thParameter<commandTmp->GetPara    
4451           params += " ";                         
4452         }                                        
4453       }                                          
4454     }                                            
4455     */                                           
4456                                                  
4457     if (params != "") {                          
4458                                                  
4459       QTableWidgetItem *nameItem;                
4460       QTableWidgetItem *paramItem;               
4461                                                  
4462       // already present ?                       
4463       QList<QTableWidgetItem *> list = fViewe    
4464       if (list.size() == 1) {                    
4465         nameItem = list.first();                 
4466         paramItem = fViewerPropertiesTableWid    
4467                                                  
4468       } else {                                   
4469         nameItem = new QTableWidgetItem();       
4470         paramItem = new QTableWidgetItem();      
4471         fViewerPropertiesTableWidget->setItem    
4472         fViewerPropertiesTableWidget->setItem    
4473                                                  
4474         // Set Guidance                          
4475         QString guidance;                        
4476         G4int n_guidanceEntry = (G4int)comman    
4477         for( G4int i_thGuidance=0; i_thGuidan    
4478           guidance += QString((char*)(command    
4479         }                                        
4480                                                  
4481         nameItem->setToolTip(guidance);          
4482         paramItem->setToolTip(GetCommandParam    
4483                                                  
4484         fViewerPropertiesTableWidget->setRowH    
4485       }                                          
4486                                                  
4487       // set current name and parameters         
4488       nameItem->setText(commandTmp->GetComman    
4489       paramItem->setText(params);                
4490                                                  
4491       nameItem->setFlags(Qt::NoItemFlags);       
4492       nameItem->setForeground(QBrush());         
4493                                                  
4494     } else {                                     
4495       treeWidgetInfosIgnoredCommands++;          
4496     }                                            
4497   }                                              
4498   // remove empty content row                    
4499   for (int i=0; i<treeWidgetInfosIgnoredComma    
4500     fViewerPropertiesTableWidget->removeRow (    
4501   }                                              
4502                                                  
4503   // The resize should done only at creation     
4504   if (!fViewerPropertiesTableWidgetIsInit) {     
4505     fViewerPropertiesTableWidgetIsInit = true    
4506                                                  
4507     fViewerPropertiesTableWidget->resizeColum    
4508                                                  
4509     int x = fViewerPropertiesTableWidget->hor    
4510     int y = fViewerPropertiesTableWidget->ver    
4511                                                  
4512     //  fViewerPropertiesTableWidget->vertica    
4513     //  fViewerPropertiesTableWidget->horizon    
4514                                                  
4515     // resize to fit content                     
4516     QDialog* dial = static_cast<QDialog*> (fU    
4517     if (dial) {                                  
4518       dial->resize(x+56,y+46); // more or les    
4519     }                                            
4520   }                                              
4521   fViewerPropertiesTableWidget->blockSignals(    
4522                                                  
4523   fTreeWidgetInfosIgnoredCommands = treeWidge    
4524 }                                                
4525                                                  
4526                                                  
4527 /**                                              
4528  Update the pick infos component widget          
4529  */                                              
4530 void G4OpenGLQtViewer::updatePickInfosWidget(    
4531   fLastPickPoint = QPoint(aX,aY);                
4532                                                  
4533   if (!isCurrentWidget()) {                      
4534     return;                                      
4535   }                                              
4536   // Ensure case where closing a UI tab close    
4537   if (!fPickInfosWidget) {                       
4538     createPickInfosWidget();                     
4539   }                                              
4540                                                  
4541 #if QT_VERSION < 0x060000                        
4542 #else                                            
4543  {auto* qGLW = dynamic_cast<G4QGLWidgetType*>    
4544   if (qGLW) qGLW->makeCurrent();}                
4545   ResizeGLView();                                
4546 #endif                                           
4547   const std::vector < G4OpenGLViewerPickMap*     
4548                                                  
4549   // remove all previous widgets                 
4550   if (fPickInfosWidget) {                        
4551     QLayoutItem * wItem;                         
4552     if (fPickInfosWidget->layout()->count())     
4553       while ((wItem = fPickInfosWidget->layou    
4554         delete wItem->widget();                  
4555         delete wItem;                            
4556       }                                          
4557     }                                            
4558   } else {                                       
4559     // Ensure case where closing a UI tab clo    
4560     if (!fPickInfosWidget) {                     
4561       createPickInfosWidget();                   
4562     }                                            
4563   }                                              
4564                                                  
4565   // parse all pick results                      
4566   G4int nPickedObjectsWithAttributes = 0;        
4567   for (unsigned int a=0; a< pickMapVector.siz    
4568     const auto& pickMap = pickMapVector[a];      
4569     // Add a box inside the pick viewer box      
4570     std::ostringstream label;                    
4571     std::ostringstream content;                  
4572     std::string txt = pickMap->getAttributes(    
4573     if (pickMapVector[a]->getAttributes().siz    
4574       ++nPickedObjectsWithAttributes;            
4575                                                  
4576       std::size_t pos1 = txt.find(':');          
4577       std::string storeKey = txt.substr(0,pos    
4578                                                  
4579       if (storeKey == "G4PhysicalVolumeModel"    
4580                                                  
4581         label << "Volume:";                      
4582         std::size_t pos2 = txt.find(':',pos1+    
4583         std::size_t pos3 = txt.find('\n',pos2    
4584         label << txt.substr(pos2+1,pos3-pos2-    
4585                                                  
4586       } else if (storeKey == "G4TrajectoriesM    
4587                                                  
4588         label << "Trajectory:";                  
4589         std::size_t pos2 = txt.find(':',pos1+    
4590         std::size_t pos3 = txt.find('\n',pos2    
4591         label << " Run:" << txt.substr(pos2+1    
4592         std::size_t pos4 = txt.find(':',pos3+    
4593         std::size_t pos5 = txt.find('\n',pos4    
4594         label << ", Event:" << txt.substr(pos    
4595                                                  
4596       } else {                                   
4597                                                  
4598         label << "Hit number:" << a << ", Pic    
4599                                                  
4600       }                                          
4601                                                  
4602       // Accumulate all content with the same    
4603       content << pickMap->print().data();        
4604       G4int thisPickName = pickMap->getPickNa    
4605       while (++a < pickMapVector.size()) {       
4606         const auto& a_pickMap = pickMapVector    
4607         if (a_pickMap->getPickName() == thisP    
4608           content << a_pickMap->print().data(    
4609         } else {                                 
4610           a--;                                   
4611           break;                                 
4612         }                                        
4613       }                                          
4614                                                  
4615       QPushButton* pickCoutButton = new QPush    
4616       pickCoutButton->setStyleSheet ("text-al    
4617       pickCoutButton->setIcon(*fTreeIconClose    
4618       fPickInfosWidget->layout()->addWidget(p    
4619                                                  
4620       QStringList newStr;                        
4621                                                  
4622       // Add to stringList                       
4623       newStr = QStringList(QString(content.st    
4624                                                  
4625       QTextEdit* ed = new QTextEdit();           
4626       ed->setReadOnly(true);                     
4627       fPickInfosWidget->layout()->addWidget(e    
4628       ed->setVisible((false));                   
4629       ed->append(newStr.join(""));               
4630                                                  
4631       std::cout << pickCoutButton->text().toS    
4632       int tmp = fPickInfosWidget->layout()->c    
4633       connect(pickCoutButton, &QPushButton::c    
4634     }                                            
4635   }                                              
4636                                                  
4637   // add a label to push everything up!          
4638   QLabel * pushUp = new QLabel("");              
4639   QSizePolicy vPolicy = QSizePolicy(QSizePoli    
4640   vPolicy.setVerticalStretch(10);                
4641   pushUp->setSizePolicy(vPolicy);                
4642   fPickInfosWidget->layout()->addWidget(pushU    
4643                                                  
4644   // highlight the first one :                   
4645                                                  
4646   // first un-highlight the last selected        
4647   changeColorAndTransparency(fLastHighlightNa    
4648                                                  
4649   if (pickMapVector.size() > 0 ) {               
4650     // get the new one                           
4651     fLastHighlightName = pickMapVector[0]->ge    
4652     fLastHighlightColor = getColorForPoIndex(    
4653     // set the new one                           
4654     changeColorAndTransparency(fLastHighlight    
4655                                                  
4656     updateQWidget();                             
4657   }                                              
4658   QDialog* dial = static_cast<QDialog*> (fUIP    
4659   if (dial) {                                    
4660     // change name                               
4661     std::ostringstream oss;                      
4662     if (nPickedObjectsWithAttributes == 0) {     
4663       oss << "No object";                        
4664     } else if (nPickedObjectsWithAttributes =    
4665       oss << "1 object";                         
4666     } else {                                     
4667       oss << nPickedObjectsWithAttributes <<     
4668     }                                            
4669     oss << " selected - " << GetName();          
4670     dial->setWindowTitle(oss.str().c_str());     
4671   }                                              
4672   // set picking cout visible                    
4673   fPickInfosScrollArea->setVisible(true);        
4674 }                                                
4675                                                  
4676                                                  
4677 void G4OpenGLQtViewer::toggleSceneTreeCompone    
4678                                                  
4679   QWidget* w;                                    
4680   // close other items, it could take too muc    
4681                                                  
4682   for (int a=0; a<fPickInfosWidget->layout()-    
4683     w = fPickInfosWidget->layout()->itemAt(a)    
4684     QTextEdit* ed = dynamic_cast<QTextEdit*>(    
4685     QPushButton* button;                         
4686     if (ed) {                                    
4687       if (a == pickItem) {                       
4688         w->setVisible(!w->isVisible());          
4689       } else {                                   
4690         w->setVisible(false);                    
4691       }                                          
4692       if (a >= 1) {                              
4693         button = dynamic_cast<QPushButton*>(f    
4694         if (button) {                            
4695           if (button->isVisible()) {             
4696             button->setIcon(*fTreeIconOpen);     
4697           } else {                               
4698             button->setIcon(*fTreeIconClosed)    
4699           }                                      
4700         }                                        
4701       }                                          
4702     }                                            
4703   }                                              
4704 }                                                
4705                                                  
4706                                                  
4707 void G4OpenGLQtViewer::currentTabActivated(in    
4708   if (fUiQt->GetViewerTabWidget()->tabText(cu    
4709     createViewerPropertiesWidget();              
4710 //    createPickInfosWidget();  // Causes a /    
4711 //    createSceneTreeWidget();  // ...this ol    
4712   }                                              
4713 }                                                
4714                                                  
4715                                                  
4716 void G4OpenGLQtViewer::tableWidgetViewerSetIt    
4717   G4UImanager* UI = G4UImanager::GetUIpointer    
4718   if(UI != NULL)  {                              
4719     QTableWidgetItem* previous = fViewerPrope    
4720     if (previous) {                              
4721       fViewerPropertiesTableWidget->blockSign    
4722       UI->ApplyCommand((std::string("/vis/vie    
4723                         + previous->text().to    
4724                         + " "                    
4725                         + item->text().toStdS    
4726       fViewerPropertiesTableWidget->blockSign    
4727     }                                            
4728   }                                              
4729 }                                                
4730                                                  
4731 bool G4OpenGLQtViewer::isCurrentWidget(){        
4732   G4Qt* interactorManager = G4Qt::getInstance    
4733   if (!interactorManager->IsExternalApp()) {     
4734                                                  
4735     // Prevent from repainting a hidden tab (    
4736     if ( GetName() != fUiQt->GetViewerTabWidg    
4737       return false;                              
4738     }                                            
4739   }                                              
4740   return true;                                   
4741 }                                                
4742                                                  
4743 /**   Build the parameter list parameters in     
4744  Reimplement partialy the G4UIparameter.cc       
4745  @param aCommand : command to list parameters    
4746  @see G4UIparameter::List()                      
4747  @see G4UIcommand::List()                        
4748  @return the command list parameters, or "" i    
4749  */                                              
4750 QString G4OpenGLQtViewer::GetCommandParameter    
4751                                   const G4UIc    
4752                                   )              
4753 {                                                
4754   G4int n_parameterEntry = (G4int)aCommand->G    
4755   QString txt;                                   
4756                                                  
4757   if( n_parameterEntry > 0 ) {                   
4758     G4UIparameter *param;                        
4759                                                  
4760     // Re-implementation of G4UIparameter.cc     
4761                                                  
4762     for( G4int i_thParameter=0; i_thParameter    
4763       param = aCommand->GetParameter(i_thPara    
4764       txt += "\nParameter : " + QString((char    
4765       if( ! param->GetParameterGuidance().emp    
4766         txt += QString((char*)(param->GetPara    
4767       txt += " Parameter type  : " + QString(    
4768       if(param->IsOmittable()){                  
4769         txt += " Omittable       : True\n";      
4770       } else {                                   
4771         txt += " Omittable       : False\n";     
4772       }                                          
4773       if( param->GetCurrentAsDefault() ) {       
4774         txt += " Default value   : taken from    
4775       } else if( ! param->GetDefaultValue().e    
4776         txt += " Default value   : " + QStrin    
4777       }                                          
4778       if( ! param->GetParameterRange().empty(    
4779         txt += " Parameter range : " + QStrin    
4780       }                                          
4781       if( ! param->GetParameterCandidates().e    
4782         txt += " Candidates      : " + QStrin    
4783       }                                          
4784     }                                            
4785   }                                              
4786   return txt;                                    
4787 }                                                
4788                                                  
4789 #ifdef G4MULTITHREADED                           
4790                                                  
4791 namespace {                                      
4792   G4Mutex visSubThreadMutex = G4MUTEX_INITIAL    
4793   G4Condition waitForVisSubThreadInitialized     
4794   G4bool visSubThreadEstablished = false;        
4795   G4bool qObjectsSwitched = false;               
4796   G4QGLWidgetType* qGLWidget = nullptr;          
4797 }                                                
4798                                                  
4799 void G4OpenGLQtViewer::DoneWithMasterThread()    
4800 {                                                
4801   // Called by Main Thread !                     
4802                                                  
4803   // Initialise and check qGLWidget - no need    
4804   qGLWidget = dynamic_cast<G4QGLWidgetType*>(    
4805   if (qGLWidget == nullptr) return;              
4806                                                  
4807   // Done with master thread                     
4808   qGLWidget->doneCurrent();                      
4809                                                  
4810   // Set current QThread for the way back        
4811   fQGLContextMainThread = QThread::currentThr    
4812 }                                                
4813                                                  
4814 void G4OpenGLQtViewer::MovingToVisSubThread()    
4815 {                                                
4816   // Still on master thread but vis thread ha    
4817                                                  
4818   if (qGLWidget == nullptr) return;              
4819                                                  
4820   // Wait until SwitchToVisSubThread has foun    
4821   {                                              
4822   G4AutoLock lock(&visSubThreadMutex);           
4823   G4CONDITIONWAITLAMBDA(&waitForVisSubThreadI    
4824   }                                              
4825                                                  
4826   // Move stuff to sub-thread                    
4827   if(qGLWidget->context()) qGLWidget->context    
4828                                                  
4829   // Inform sub-thread                           
4830   G4AutoLock lock(&visSubThreadMutex);           
4831   qObjectsSwitched = true;                       
4832   lock.unlock();                                 
4833   G4CONDITIONBROADCAST(&waitForVisSubThreadIn    
4834 }                                                
4835                                                  
4836 void G4OpenGLQtViewer::SwitchToVisSubThread()    
4837 {                                                
4838   // Called by VisSub Thread !                   
4839                                                  
4840   if (qGLWidget == nullptr) return;              
4841                                                  
4842   // Set the current QThread to its static va    
4843   fQGLContextVisSubThread = QThread::currentT    
4844                                                  
4845   // Let MovingToVisSubThread know we have th    
4846   {                                              
4847   G4AutoLock lock(&visSubThreadMutex);           
4848   visSubThreadEstablished = true;                
4849   G4CONDITIONBROADCAST(&waitForVisSubThreadIn    
4850   }                                              
4851                                                  
4852   // Wait until MovingToVisSubThread has move    
4853   {                                              
4854   G4AutoLock lock(&visSubThreadMutex);           
4855   G4CONDITIONWAITLAMBDA(&waitForVisSubThreadI    
4856   }                                              
4857                                                  
4858   // make context current                        
4859   qGLWidget->makeCurrent();                      
4860 }                                                
4861                                                  
4862 void G4OpenGLQtViewer::DoneWithVisSubThread()    
4863 {                                                
4864   // Called by vis sub thread                    
4865                                                  
4866   if (qGLWidget == nullptr) return;              
4867                                                  
4868   // finish with this vis sub thread context     
4869   qGLWidget->doneCurrent();                      
4870                                                  
4871   // and move stuff back to the main thread      
4872   if(qGLWidget->context()) qGLWidget->context    
4873 }                                                
4874                                                  
4875 void G4OpenGLQtViewer::SwitchToMasterThread()    
4876 {                                                
4877   // Called by master Thread !                   
4878                                                  
4879   if (qGLWidget == nullptr) return;              
4880                                                  
4881   qGLWidget->makeCurrent();                      
4882                                                  
4883   visSubThreadEstablished = false;               
4884   qObjectsSwitched = false;                      
4885 }                                                
4886                                                  
4887 #endif                                           
4888                                                  
4889                                                  
4890 /*                                               
4891                                                  
4892 void MultiLayer::exportToSVG(const QString& f    
4893 {                                                
4894 QPicture picture;                                
4895 QPainter p(&picture);                            
4896 for (int i=0;i<(int)graphsList->count();i++)     
4897 {                                                
4898 Graph *gr=(Graph *)graphsList->at(i);            
4899 Plot *myPlot= (Plot *)gr->plotWidget();          
4900                                                  
4901 QPoint pos=gr->pos();                            
4902                                                  
4903 int width=int(myPlot->frameGeometry().width()    
4904 int height=int(myPlot->frameGeometry().height    
4905                                                  
4906 myPlot->print(&p, QRect(pos,QSize(width,heigh    
4907 }                                                
4908                                                  
4909 p.end();                                         
4910 picture.save(fname, "svg");                      
4911 }                                                
4912 */                                               
4913