PaIRS-UniNa 0.2.0__cp310-cp310-win_amd64.whl → 0.2.8__cp310-cp310-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. PaIRS_UniNa/Calibration_Tab.py +39 -23
  2. PaIRS_UniNa/Changes.txt +127 -8
  3. PaIRS_UniNa/Custom_Top.py +12 -9
  4. PaIRS_UniNa/Explorer.py +534 -165
  5. PaIRS_UniNa/FolderLoop.py +562 -0
  6. PaIRS_UniNa/Input_Tab.py +261 -100
  7. PaIRS_UniNa/Input_Tab_CalVi.py +24 -25
  8. PaIRS_UniNa/Input_Tab_tools.py +967 -405
  9. PaIRS_UniNa/Output_Tab.py +324 -130
  10. PaIRS_UniNa/PaIRS_PIV.py +58 -1
  11. PaIRS_UniNa/PaIRS_pypacks.py +1415 -1039
  12. PaIRS_UniNa/Process_Tab.py +15 -19
  13. PaIRS_UniNa/Process_Tab_Disp.py +12 -5
  14. PaIRS_UniNa/Saving_tools.py +27 -13
  15. PaIRS_UniNa/TabTools.py +176 -59
  16. PaIRS_UniNa/Vis_Tab.py +664 -256
  17. PaIRS_UniNa/Vis_Tab_CalVi.py +114 -45
  18. PaIRS_UniNa/Whatsnew.py +58 -9
  19. PaIRS_UniNa/_PaIRS_PIV.pyd +0 -0
  20. PaIRS_UniNa/__init__.py +4 -3
  21. PaIRS_UniNa/addwidgets_ps.py +150 -63
  22. PaIRS_UniNa/calib.py +6 -3
  23. PaIRS_UniNa/calibView.py +19 -6
  24. PaIRS_UniNa/gPaIRS.py +1397 -543
  25. PaIRS_UniNa/icons/align_all.png +0 -0
  26. PaIRS_UniNa/icons/announcement.png +0 -0
  27. PaIRS_UniNa/icons/bugfix.png +0 -0
  28. PaIRS_UniNa/icons/change_folder.png +0 -0
  29. PaIRS_UniNa/icons/change_folder_off.png +0 -0
  30. PaIRS_UniNa/icons/close_all.png +0 -0
  31. PaIRS_UniNa/icons/copy_process_off.png +0 -0
  32. PaIRS_UniNa/icons/flaticon_PaIRS_beta.png +0 -0
  33. PaIRS_UniNa/icons/flaticon_PaIRS_download_warning.png +0 -0
  34. PaIRS_UniNa/icons/folder_loop_cleanup.png +0 -0
  35. PaIRS_UniNa/icons/folder_loop_cleanup_off.png +0 -0
  36. PaIRS_UniNa/icons/linked.png +0 -0
  37. PaIRS_UniNa/icons/logo_opaco.png +0 -0
  38. PaIRS_UniNa/icons/open_image.png +0 -0
  39. PaIRS_UniNa/icons/open_new_window.png +0 -0
  40. PaIRS_UniNa/icons/open_result.png +0 -0
  41. PaIRS_UniNa/icons/process_loop.png +0 -0
  42. PaIRS_UniNa/icons/pylog.png +0 -0
  43. PaIRS_UniNa/icons/python_warning.png +0 -0
  44. PaIRS_UniNa/icons/queue.png +0 -0
  45. PaIRS_UniNa/icons/restore_undo.png +0 -0
  46. PaIRS_UniNa/icons/save_and_stop.png +0 -0
  47. PaIRS_UniNa/icons/scale_all.png +0 -0
  48. PaIRS_UniNa/icons/scale_down.png +0 -0
  49. PaIRS_UniNa/icons/scale_up.png +0 -0
  50. PaIRS_UniNa/icons/scan_path_loop.png +0 -0
  51. PaIRS_UniNa/icons/scan_path_loop_off.png +0 -0
  52. PaIRS_UniNa/icons/show_all.png +0 -0
  53. PaIRS_UniNa/icons/star.png +0 -0
  54. PaIRS_UniNa/icons/step_inheritance.png +0 -0
  55. PaIRS_UniNa/icons/subMIN_on.png +0 -0
  56. PaIRS_UniNa/icons/unedited.png +0 -0
  57. PaIRS_UniNa/icons/uninitialized.png +0 -0
  58. PaIRS_UniNa/icons/window.png +0 -0
  59. PaIRS_UniNa/listLib.py +3 -2
  60. PaIRS_UniNa/parForMulti.py +7 -5
  61. PaIRS_UniNa/parForWorkers.py +174 -140
  62. PaIRS_UniNa/pivParFor.py +9 -11
  63. PaIRS_UniNa/preProcParFor.py +4 -4
  64. PaIRS_UniNa/procTools.py +120 -44
  65. PaIRS_UniNa/rqrdpckgs.txt +9 -0
  66. PaIRS_UniNa/stereoPivParFor.py +16 -22
  67. PaIRS_UniNa/tabSplitter.py +17 -7
  68. PaIRS_UniNa/ui_Input_Tab.py +56 -57
  69. PaIRS_UniNa/ui_Input_Tab_CalVi.py +71 -64
  70. PaIRS_UniNa/ui_Log_Tab.py +8 -6
  71. PaIRS_UniNa/ui_Output_Tab.py +180 -4
  72. PaIRS_UniNa/ui_Process_Tab.py +19 -19
  73. PaIRS_UniNa/ui_Process_Tab_Disp.py +181 -10
  74. PaIRS_UniNa/ui_Vis_Tab.py +332 -196
  75. PaIRS_UniNa/ui_Whatsnew.py +13 -13
  76. PaIRS_UniNa/ui_gPairs.py +140 -71
  77. PaIRS_UniNa/ui_infoPaIRS.py +156 -31
  78. PaIRS_UniNa/whatsnew.txt +6 -4
  79. {PaIRS_UniNa-0.2.0.dist-info → pairs_unina-0.2.8.dist-info}/METADATA +62 -26
  80. {PaIRS_UniNa-0.2.0.dist-info → pairs_unina-0.2.8.dist-info}/RECORD +82 -54
  81. {PaIRS_UniNa-0.2.0.dist-info → pairs_unina-0.2.8.dist-info}/WHEEL +1 -1
  82. PaIRS_UniNa/icons/order.png +0 -0
  83. PaIRS_UniNa/icons/order_reverse.png +0 -0
  84. PaIRS_UniNa/icons/run_piv.png +0 -0
  85. PaIRS_UniNa/stereo.py +0 -685
  86. PaIRS_UniNa/ui_infoCalVi.py +0 -428
  87. PaIRS_UniNa-0.2.0.dist-info/LICENSE +0 -19
  88. {PaIRS_UniNa-0.2.0.dist-info → pairs_unina-0.2.8.dist-info}/top_level.txt +0 -0
PaIRS_UniNa/gPaIRS.py CHANGED
@@ -28,9 +28,10 @@ from .Saving_tools import*
28
28
 
29
29
  import concurrent.futures
30
30
 
31
- from .__init__ import __version__,__subversion__,__year__,__mail__,__website__
31
+ from .__init__ import __version__,__subversion__,__year__,__date__,__mail__,__website__
32
32
 
33
33
  version=__version__
34
+ subversion=__subversion__
34
35
  year=__year__
35
36
  mail=__mail__
36
37
  website=__website__
@@ -47,7 +48,14 @@ class FloatingObject(QMainWindow):
47
48
 
48
49
  def __init__(self,parent,tab):
49
50
  super().__init__()
50
- self.gui:gPaIRS=parent
51
+ if parent is None:
52
+ self.gui=self.window()
53
+ else:
54
+ if hasattr(parent,'gui'):
55
+ self.gui:gPaIRS=parent.gui
56
+ else:
57
+ self.gui:gPaIRS=parent.window()
58
+
51
59
  self.name=''
52
60
  self.button=None
53
61
  self.tab=tab
@@ -114,14 +122,23 @@ class infoPaIRS(QMainWindow):
114
122
  self.ui=ui
115
123
  setupWid(self)
116
124
 
117
- infotext=self.ui.info.text().replace('#.#.#',version)
125
+ subv=f"(.{subversion})" if int(subversion) else ""
126
+ infotext=self.ui.info.text().replace('#.#.#',version+subv)
118
127
  infotext=infotext.replace('yyyy',year)
128
+ infotext=infotext.replace('dddd/dd/dd',__date__)
119
129
  mailString=f'<a href="mailto:{mail}"><span style=" text-decoration: underline; color:#0000ff; font-size:11pt">{mail}</a>'
120
130
  infotext=infotext.replace('mmmm',mailString)
121
131
  websiteString=f'<a href="{website}"><span style=" text-decoration: underline; color:#0000ff; font-size:11pt">{website}</a>'
122
132
  infotext=infotext.replace('wwww',websiteString)
123
133
  self.ui.info.setText(infotext)
124
-
134
+ if Flag_ISEXE:
135
+ #self.ui.tabWidget.removeTab(3)
136
+ self.ui.tabWidget.setTabText(3,'Packages')
137
+ self.ui.req.setText(self.distPackages())
138
+ else:
139
+ self.ui.tabWidget.setTabText(3,'Requirements')
140
+ self.ui.req.setText(self.requirements())
141
+
125
142
  self.fontPixelSize=gui.GPApar.fontPixelSize
126
143
  self.setFontSizeText()
127
144
 
@@ -133,8 +150,8 @@ class infoPaIRS(QMainWindow):
133
150
  if w.hasFocus():
134
151
  #pri.Info.yellow(w)
135
152
  type(w).keyPressEvent(w,e)
136
- if not e.key() in self.gui.blockedKeys:
137
- self.gui.keyPressEvent(e)
153
+ #if not e.key() in self.gui.blockedKeys:
154
+ # self.gui.keyPressEvent(e)
138
155
  return KeyPressFun
139
156
  w.keyPressEvent=createKeyPressFun(w)
140
157
 
@@ -147,14 +164,128 @@ class infoPaIRS(QMainWindow):
147
164
  setFontSizeText(self.ui.tom_cv,[fPixSize+1])
148
165
  setFontSizeText(self.ui.list_ref,[fPixSize+1])
149
166
 
150
- #********************************************* GPaIRS
167
+ def distPackages(self):
168
+ # Read the contents of the file and split by lines
169
+ with open(rqrdpckgs_filename, 'r') as file:
170
+ lines = file.readlines()
171
+
172
+ # Introductory sentence
173
+ intro_text = """
174
+ <p style="font-size: 12pt; font-weight: normal; text-align: justify;">
175
+ Python packages included in the current executable:
176
+ </p>
177
+ <p>
178
+
179
+ </p>
180
+ """
181
+
182
+ # Start the HTML table with improved styling
183
+ html_table = intro_text + """
184
+ <table border="1" style="width: 100%; align-items: center;">
185
+ <thead>
186
+ <tr>
187
+ <th style="padding: 10px; font-size: 11pt; font-weight: bold;">Package</th>
188
+ <th style="padding: 10px; font-size: 11pt; font-weight: bold;">Version</th>
189
+ </tr>
190
+ </thead>
191
+ <tbody>
192
+ """
193
+
194
+ # Iterate over each line in the file
195
+ for line in lines:
196
+ # Split each line into package name, min vers11pt max version, and other info
197
+ package_info = line.strip().split()
198
+
199
+ # Ensure the line has the expected format
200
+ if len(package_info) >= 3:
201
+ package_name = package_info[0]
202
+ if package_name[0]=='#': continue
203
+ max_version = package_info[2]
204
+
205
+ # Append a row to the HTML table
206
+ html_table += f"""
207
+ <tr>
208
+ <td style="padding: 10px; font-size: 11pt">{package_name}</td>
209
+ <td style="padding: 10px; font-size: 11pt">{max_version}</td>
210
+ </tr>
211
+ """
212
+
213
+ # Close the table tags
214
+ html_table += """
215
+ </tbody>
216
+ </table>
217
+ """
218
+ return html_table
151
219
 
220
+ def requirements(self):
221
+ # Read the contents of the file and split by lines
222
+ with open(rqrdpckgs_filename, 'r') as file:
223
+ lines = file.readlines()
224
+
225
+ # Introductory sentence
226
+ intro_text = """
227
+ <p style="font-size: 12pt; font-weight: normal; text-align: justify;">
228
+ Required Python packages with their minimum and maximum supported versions:
229
+ </p>
230
+ <p>
231
+
232
+ </p>
233
+ """
234
+
235
+ # Start the HTML table with improved styling
236
+ html_table = intro_text + """
237
+ <table border="1" style="width: 100%; align-items: center;">
238
+ <thead>
239
+ <tr>
240
+ <th style="padding: 10px; font-size: 11pt; font-weight: bold;">Package</th>
241
+ <th style="padding: 10px; font-size: 11pt; font-weight: bold;">Minimum version</th>
242
+ <th style="padding: 10px; font-size: 11pt; font-weight: bold;">Maximum version</th>
243
+ <th style="padding: 10px; font-size: 11pt; font-weight: bold;">Installed version</th>
244
+ </tr>
245
+ </thead>
246
+ <tbody>
247
+ """
248
+
249
+ # Iterate over each line in the file
250
+ for line in lines:
251
+ # Split each line into package name, min vers11pt max version, and other info
252
+ package_info = line.strip().split()
253
+
254
+ # Ensure the line has the expected format
255
+ if len(package_info) >= 3:
256
+ package_name = package_info[0]
257
+ if package_name[0]=='#': continue
258
+ min_version = package_info[1]
259
+ max_version = package_info[2]
260
+ curr_version = package_info[3]
261
+
262
+ # Append a row to the HTML table
263
+ html_table += f"""
264
+ <tr>
265
+ <td style="padding: 10px; font-size: 11pt">{package_name}</td>
266
+ <td style="padding: 10px; font-size: 11pt">{min_version}</td>
267
+ <td style="padding: 10px; font-size: 11pt">{max_version}</td>
268
+ <td style="padding: 10px; font-size: 11pt">{curr_version}</td>
269
+ </tr>
270
+ """
271
+
272
+ # Close the table tags
273
+ html_table += """
274
+ </tbody>
275
+ </table>
276
+ """
277
+ return html_table
278
+
279
+ #********************************************* GPaIRS
152
280
  class gPaIRS(QMainWindow):
153
281
 
154
282
  def eventFilter(self, obj, event:QKeyEvent):
155
283
  # Check if the event is a KeyPress event
156
284
  if event.type() == QEvent.KeyPress:
157
285
  if event.modifiers() & Qt.KeyboardModifier.ControlModifier:
286
+ if event.modifiers() & Qt.KeyboardModifier.ShiftModifier and event.key() == Qt.Key.Key_F:
287
+ self.setDefaultSizes()
288
+ return True
158
289
  FlagSetFont=False
159
290
  if event.key() == Qt.Key.Key_0:
160
291
  FlagSetFont=self.GPApar.fontPixelSize!=fontPixelSize
@@ -184,11 +315,16 @@ class gPaIRS(QMainWindow):
184
315
  def resizeEvent(self,event):
185
316
  if self.FlagGeometryInit:
186
317
  self.FlagGeometryInit=False
187
- return
188
- self.setFontPixelSize()
318
+ #self.setFontPixelSize()
189
319
  super().resizeEvent(event)
190
320
  #self.updateGPAparGeom()
191
321
 
322
+ def showEvent(self, event):
323
+ super().showEvent(event)
324
+ if event.type() == QEvent.Show:
325
+ QTimer.singleShot(0, lambda: self.ui.tabAreaWidget.setSPLlayout())
326
+ pass
327
+
192
328
  def closeEvent(self,event):
193
329
  if self.completingTask!=self.correctClose:
194
330
  self.pauseQuestion('quitting',self.correctClose,FlagFirstQuestion=True)
@@ -201,7 +337,7 @@ class gPaIRS(QMainWindow):
201
337
  self.save_last_workspace()
202
338
  self.closeAll()
203
339
  if self.GPApar.FlagOutDated:
204
- warningLatestVersion(self,self.app,flagExit=1,flagWarning=self.GPApar.FlagOutDated==1)
340
+ warningLatestVersion(self,self.app,flagExit=1,flagWarning=self.GPApar.FlagOutDated in (-1,1,-1000))
205
341
  self.close()
206
342
  self.app.processEvents()
207
343
  self.app.SecondaryThreads=self.SecondaryThreads
@@ -223,9 +359,9 @@ class gPaIRS(QMainWindow):
223
359
  guiInit=Signal()
224
360
  setMapVar=Signal()
225
361
  pause_proc=Signal()
226
- printOutDated=Signal(bool)
362
+ printOutDated=Signal()
227
363
 
228
- def __init__(self,flagDebug=False,app=None):
364
+ def __init__(self,flagDebug=False,app=None, standardPalette=None):
229
365
  self.app:QApplication=app
230
366
  self.name='PaIRS'
231
367
  self.flagSimpleFor=False # normally false, True only if you are checking the c library or the parpool therefore I have added a long print at the end of this function
@@ -238,12 +374,18 @@ class gPaIRS(QMainWindow):
238
374
  #------------------------------------- Launching Parallel Pool
239
375
  self.previousPlotTime=time() #previous time for plotting
240
376
  self.FlagGeometryInit=True
377
+ self.FlagOpenedWorkspace=False
241
378
 
242
379
  self.FlagGuiInit=False
243
380
  self.signals=self.gPaIRS_signals()
244
- self.numUsedThreadsPIV=NUMTHREADS_PIV
381
+ #self.numUsedThreadsPIV=NUMTHREADS_MAX #now is called numMaxProcs
382
+
383
+ self.numMaxProcs=NUMTHREADS_MAX #number of cores that the user has selected should be larger than numUsedProcs*numPivOmpCores
384
+ self.numUsedProcs=NUMTHREADS_MAX #number of really used processor (Threads parfor)
385
+ self.numPivOmpCores=1 # number of PIV internal cores used by omp
386
+
245
387
  self.FlagParPoolInit=False
246
- self.launchParPool(NUMTHREADS_PIV_MAX)
388
+ self.launchParPool(NUMTHREADS_MAX)
247
389
 
248
390
  self.procdata:dataTreePar=None
249
391
  self.currind:list=None
@@ -251,6 +393,8 @@ class gPaIRS(QMainWindow):
251
393
  self.numCallBackTotOk=0 # Callbacks that are relative to a normal termination
252
394
  self.SecondaryThreads=[]
253
395
 
396
+ self.FlagPackIssue=False
397
+
254
398
  #------------------------------------- Graphical interface: widgets
255
399
  ui=Ui_gPairs()
256
400
  ui.setupUi(self)
@@ -269,15 +413,17 @@ class gPaIRS(QMainWindow):
269
413
  self.cfgname=lastcfgname
270
414
  self.FlagHappyLogo=False
271
415
  self.setupLogo()
416
+ self.startHappyLogoWatcher()
272
417
 
273
418
  self.GPApar_old=GPApar()
274
419
  self.GPApar=GPApar()
275
- self.GPApar.NumCores=self.numUsedThreadsPIV
420
+ self.GPApar.NumCores=self.numMaxProcs
276
421
  self.TABpar=self.GPApar
277
422
 
278
423
  pri.Time.blue(2,f'gPaIRS inizio generazione tabs')
279
424
  self.defineTabs()
280
425
  self.defineMenuActions()
426
+ self.ui.title_workspace.updateLabel=self.updateWorkspaceTitle
281
427
 
282
428
  setupWid(self) #---------------- IMPORTANT
283
429
  self.setFurtherFontPixelSizes(fontPixelSize)
@@ -303,9 +449,10 @@ class gPaIRS(QMainWindow):
303
449
  return KeyPressFun
304
450
  w.keyPressEvent=createKeyPressFun(w)
305
451
  """
306
- self.ui.spin_nworkers.setValue(self.numUsedThreadsPIV)
452
+ self.ui.spin_nworkers.setValue(self.numMaxProcs)
307
453
  self.ui.spin_nworkers.setMinimum(1)
308
- self.ui.spin_nworkers.setMaximum(NUMTHREADS_PIV_MAX)
454
+ self.ui.spin_nworkers.setMaximum(NUMTHREADS_MAX)
455
+ self.ui.spin_nworkers.valueChanged.connect(self.spin_nworkers_action)
309
456
 
310
457
  self.ui.button_pause.hide()
311
458
  self.ui.w_progress_Proc.hide()
@@ -317,8 +464,6 @@ class gPaIRS(QMainWindow):
317
464
  #window.close()
318
465
  self.maximumGeometry=self.app.primaryScreen().geometry()
319
466
 
320
- self.setDefaultSizes()
321
-
322
467
  self.minW=self.minimumWidth()
323
468
  self.maxW=self.maximumGeometry.width()
324
469
  self.ui.Explorer.setMinimumWidth(0)
@@ -328,10 +473,24 @@ class gPaIRS(QMainWindow):
328
473
  self.splash=None
329
474
 
330
475
  #------------------------------------- Graphical interface: miscellanea
476
+ self.flaticon_PaIRS_download=QIcon()
477
+ self.flaticon_PaIRS_download.addFile(icons_path+'flaticon_PaIRS_download.png')
478
+ self.flaticon_PaIRS_download_warning=QIcon()
479
+ self.flaticon_PaIRS_download_warning.addFile(icons_path+'flaticon_PaIRS_download_warning.png')
480
+ self.flaticon_PaIRS_beta=QIcon()
481
+ self.flaticon_PaIRS_beta.addFile(icons_path+'flaticon_PaIRS_beta.png')
482
+
331
483
  self.icon_play=QIcon()
332
484
  self.icon_play.addFile(u""+ icons_path +"play.png", QSize(), QIcon.Normal, QIcon.Off)
333
485
  self.icon_pause=QIcon()
334
486
  self.icon_pause.addFile(u""+ icons_path +"pause.png", QSize(), QIcon.Normal, QIcon.Off)
487
+ self.icon_save_and_stop=QIcon()
488
+ self.icon_save_and_stop.addFile(u""+ icons_path +"save_and_stop.png", QSize(), QIcon.Normal, QIcon.Off)
489
+
490
+ self.ui.tabAreaWidget.icon_link=QIcon()
491
+ self.ui.tabAreaWidget.icon_link.addFile(u""+ icons_path +"link.png", QSize(), QIcon.Normal, QIcon.Off)
492
+ self.ui.tabAreaWidget.icon_unlink=QIcon()
493
+ self.ui.tabAreaWidget.icon_unlink.addFile(u""+ icons_path +"unlink.png", QSize(), QIcon.Normal, QIcon.Off)
335
494
 
336
495
  self.updating_import_gif = QMovie(u""+ icons_path +"updating_import.gif")
337
496
  self.updating_import_gif.setScaledSize(self.ui.label_updating_import.size())
@@ -355,10 +514,11 @@ class gPaIRS(QMainWindow):
355
514
  self.gearMovie.setScaledSize(QSize(StepItemWidget.label_size,StepItemWidget.label_size))
356
515
  self.gearMovie.start()
357
516
 
358
- self.palettes=[lightPalette(),darkPalette(),None]
517
+ self.palettes=[lightPalette(),darkPalette(),standardPalette]
359
518
  self.paletteNames=['Light','Dark','System']
360
519
  #self.ui.logo.contextMenuEvent=self.paletteContextMenuEvent
361
520
  self.ui.button_colormode.mousePressEvent=self.paletteContextMenuEvent
521
+ self.ui.button_packissue.mousePressEvent=lambda e: checkRequiredPackages(self,FlagDisplay=True)
362
522
  self.ui.logo.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
363
523
  self.ui.logo.mousePressEvent=lambda e: self.about()
364
524
  #self.ui.logo.mousePressEvent=self.paletteContextMenuEvent
@@ -368,10 +528,16 @@ class gPaIRS(QMainWindow):
368
528
 
369
529
  self.aboutDialog=None
370
530
  self.logChanges:Log_Tab=None
371
- self.fontPixelSize=fontPixelSize
531
+ self.whatsNew=lambda: whatsNew(self)
532
+
372
533
  self.ui.button_PaIRS_download.setCursor(Qt.CursorShape.PointingHandCursor)
373
534
  self.ui.button_PaIRS_download.setVisible(False)
374
- self.signals.printOutDated.connect(lambda flagOutDated: self.ui.button_PaIRS_download.setVisible(flagOutDated))
535
+ self.signals.printOutDated.connect(self.setButtonDownload)
536
+
537
+ self.fontPixelSize=fontPixelSize
538
+ self.setDefaultSizes()
539
+
540
+ self.ui.title_workspace.bullet=GPApar().saveBullet()
375
541
 
376
542
  #------------------------------------- Declaration of parameters
377
543
  self.PaIRS_threadpool=QThreadPool()
@@ -410,14 +576,26 @@ class gPaIRS(QMainWindow):
410
576
  self.ui.workspace_icon.pressed.connect(lambda btn=self.ui.workspace_icon: btn.setStyleSheet("border: none; background: #dcdcdc;"))
411
577
  self.ui.workspace_icon.released.connect(lambda btn=self.ui.workspace_icon: btn.setStyleSheet("border: none; background: none;"))
412
578
  pixmap_workspace=QPixmap(icons_path+'workspace.png')
413
- self.ui.workspace_icon.clicked.connect(lambda: self.warningDialog(self.GPApar.InfoMessage(),pixmap=pixmap_workspace))
579
+ self.ui.workspace_icon.clicked.connect(lambda: self.warningDialog(self.GPApar.InfoMessage(),pixmap=pixmap_workspace,title='Workspace information'))
414
580
 
415
581
  self.currITEpar=self.TREpar
416
582
  self.ui.title_icon.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
417
583
  self.ui.title_icon.pressed.connect(lambda btn=self.ui.title_icon: btn.setStyleSheet("border: none; background: #dcdcdc;"))
418
584
  self.ui.title_icon.released.connect(lambda btn=self.ui.title_icon: btn.setStyleSheet("border: none; background: none;"))
419
585
  pixmap_workspace=QPixmap(icons_path+'workspace.png')
420
- self.ui.title_icon.clicked.connect(lambda: self.warningDialog(self.currITEpar.InfoMessage(),pixmap=TreeIcons.pixmaps[self.currITEpar.icon]))
586
+ self.ui.title_icon.clicked.connect(lambda: self.warningDialog(self.currITEpar.InfoMessage(),pixmap=TreeIcons.pixmaps[self.currITEpar.icon],title=f"{self.currITEpar.basename} information"))
587
+
588
+ class RCLbar:
589
+ buttons={0: self.ui.button_reset_step,
590
+ 1: self.ui.button_step_inherit,
591
+ 2: self.ui.button_copy_step,
592
+ 3: self.ui.button_link_step}
593
+ buttonData={0: {'name': 'Reset step'},
594
+ 1: {'name': 'Copy input/output data from...'},
595
+ 2: {'name': 'Copy step from...'},
596
+ 3: {'name': 'Link step to...'}}
597
+ self.RCLbar=RCLbar()
598
+ self.ui.Explorer.processActionBar.additionalButtonBars['items'].append(self.RCLbar)
421
599
 
422
600
  self.installEventFilter(self)
423
601
 
@@ -456,199 +634,9 @@ class gPaIRS(QMainWindow):
456
634
  self.open_workspace(filename=lastcfgname,FlagSetGeometry=True)
457
635
  self.GPApar_old.copyfrom(self.GPApar)
458
636
  else:
459
- self.adjustProjectSelection()
637
+ self.adjustProjectSelection()
638
+ self.setGPaIRSPalette()
460
639
  return
461
-
462
- def setFontPixelSize(self):
463
- if self.fontPixelSize==self.GPApar.fontPixelSize: return
464
- fPixSize=self.GPApar.fontPixelSize
465
- font=QFont()
466
- font.setFamily(fontName)
467
- font.setPixelSize(fPixSize)
468
- if self.app: self.app.setFont(font)
469
- setFontPixelSize(self,fPixSize)
470
- self.setFurtherFontPixelSizes(fPixSize)
471
- if self.aboutDialog:
472
- self.aboutDialog.fontPixelSize=self.GPApar.fontPixelSize
473
- self.aboutDialog.setFontSizeText()
474
- if self.logChanges: self.logChanges.setFontPixelSize(fPixSize)
475
- if self.menuDebug: self.menuDebug.setFont(self.ui.menuFile.font())
476
- self.fontPixelSize=fPixSize
477
-
478
- def setFurtherFontPixelSizes(self,fPixSize):
479
- self.setTabFontPixelSize(fPixSize)
480
-
481
- lab:QLabel=self.ui.title
482
- fPixSize_TabNames=min([fPixSize*2,30])
483
- font=lab.font()
484
- font.setFamily(fontName)
485
- font.setPixelSize(fPixSize_TabNames)
486
- lab.setFont(font)
487
- self.ui.title_workspace.setFont(font)
488
-
489
- lab:QLabel=self.ui.subtitle
490
- font=lab.font()
491
- font.setFamily(fontName)
492
- font.setPixelSize(fPixSize+4)
493
- lab.setFont(font)
494
- self.ui.subtitle_workspace.setFont(font)
495
-
496
- lab:QLabel=self.onlyReadLabel
497
- font=lab.font()
498
- font.setFamily(fontName)
499
- font.setPixelSize(fPixSize+4)
500
- lab.setFont(font)
501
-
502
- self.ui.projectPage.setFontPixelSize(fPixSize)
503
- self.ui.processPage.setFontPixelSize(fPixSize)
504
- self.ui.stepPage.setFontPixelSize(fPixSize)
505
-
506
- self.w_Log.setLogFont(fontPixelSize-dfontLog)
507
- self.w_Vis_CalVi.setLogFont(fontPixelSize-dfontLog)
508
-
509
- def setTabFontPixelSize(self,fPixSize):
510
- fPixSize_TabNames=min([fPixSize*2,30])
511
- for w in self.ui.tabAreaWidget.widgets:
512
- setFontPixelSize(w,fPixSize)
513
- w:gPaIRS_Tab
514
- for lab in w.findChildren(QLabel):
515
- lab:QLabel
516
- if 'name_tab' in lab.objectName():
517
- #lab:QLabel=w.ui.name_tab
518
- font=lab.font()
519
- font.setPixelSize(fPixSize_TabNames)
520
- lab.setFont(font)
521
-
522
- def falseShow(self):
523
- FlagHidden=not self.isVisible()
524
- total_rect = QGuiApplication.primaryScreen().geometry()
525
- for screen in QGuiApplication.screens():
526
- total_rect = total_rect.united(screen.geometry())
527
- self.move(total_rect.right() + 100, total_rect.bottom() + 100)
528
- self.updateGeometry()
529
- self.show()
530
- self.repaint()
531
- return FlagHidden
532
-
533
- def setDefaultSizes(self):
534
- margins=self.ui.centralLayout.contentsMargins()
535
- main_splitter_sizes=[self.ui.w_Managing_Tabs.baseSize().width(),self.ui.tabAreaWidget.widgetMinimumWidth*2+self.ui.tabAreaWidget.margin*2+self.ui.tabAreaWidget.handleWidth*2] #processTree, main_sep, tabAreaWidget
536
- w=margins.left()+self.ui.main_splitter.handleWidth()*2+sum(main_splitter_sizes)+margins.right()
537
- h=margins.top()+self.ui.w_header.minimumHeight()+self.ui.tabAreaWidget.tabAreaHeight+self.ui.tabAreaWidget.buttonSize[1]+self.ui.tabAreaWidget.buttonSpacing+self.ui.tabAreaWidget.margin*2+self.ui.w_Operating_Tabs.layout().spacing()+self.ui.statusbar.minimumHeight()+margins.bottom()
538
- self.resize(w,h)
539
- self.ui.main_splitter.setSizes(main_splitter_sizes)
540
- x=(self.maximumGeometry.width()-w)*0.5
541
- y=(self.maximumGeometry.height()-h)*0.5
542
- if self.falseShow(): self.hide()
543
- self.move(x,y)
544
- self.app.processEvents()
545
- self.updateGPAparGeometry()
546
-
547
- def adjustProcessSelection(self):
548
- FlagVisible=[False,False,False,False]
549
- if self.TREpar.project is None:
550
- FlagVisible[0]=True
551
- else:
552
- if self.TREpar.process is None:
553
- FlagVisible[1]=True
554
- else:
555
- if self.TREpar.step is None or self.TREpar.step==0:
556
- FlagVisible[2]=True
557
- else:
558
- FlagVisible[3]=True
559
- self.ui.projectPage.setVisible(FlagVisible[0])
560
- self.ui.processPage.setVisible(FlagVisible[1])
561
- self.ui.stepPage.setVisible(FlagVisible[2])
562
- self.ui.tabAreaWidget.setVisible(FlagVisible[3])
563
- #if FlagVisible[3]:
564
- # self.ui.tabAreaWidget.scrollArea.splitter.splitterResize()
565
-
566
- self.adjustWorkspaceHeader()
567
- self.adjustTitleHeader()
568
- self.adjustSwitches()
569
-
570
- def setGPaIRSTitle(self):
571
- cfgString=f': {self.GPApar.outName}' if self.GPApar.outName and self.GPApar.outName!=lastcfgname else ''
572
- if not self.GPApar.FlagSaved: cfgString+='*'
573
- if Flag_DEBUG:#TA per non incasinarmi
574
- windowTitle=f'PaIRS (v{version}.{__subversion__}) -- cfg v{uicfg_version} -- PIV {self.PIVvers} -- {platform.system()}'
575
- else:
576
- windowTitle=f'PaIRS (v{version})'
577
- windowTitle+=cfgString
578
- self.setWindowTitle(windowTitle)
579
-
580
- def adjustWorkspaceHeader(self):
581
- if self.GPApar.outName and self.GPApar.outName!=lastcfgname:
582
- title=self.GPApar.name+self.GPApar.saveBullet()
583
- subtitle=self.GPApar.date
584
- icon=self.GPApar.icon
585
- else:
586
- title=''
587
- subtitle=''
588
- icon=None
589
- self.ui.title_workspace.setText(title)
590
- self.ui.subtitle_workspace.setText(subtitle)
591
-
592
- InfoMessage=self.GPApar.InfoMessage()
593
- self.ui.title_workspace.setToolTip(InfoMessage)
594
- self.ui.title_workspace.setStatusTip(InfoMessage)
595
- self.ui.subtitle_workspace.setToolTip(InfoMessage)
596
- self.ui.subtitle_workspace.setStatusTip(InfoMessage)
597
-
598
- self.ui.workspace_icon.setVisible(icon is not None)
599
- self.setGPaIRSTitle()
600
- self.adjustMenuFile()
601
-
602
- def adjustTitleHeader(self):
603
- if self.TREpar.project is None:
604
- title='Welcome to PaIRS'
605
- subtitle='Particle Image Reconstruction Software'
606
- icon=None
607
- self.currITEpar=None
608
- else:
609
- title=self.TREpar.name+self.TREpar.saveBullet()
610
- if self.TREpar.step is None:
611
- subtitle=self.TREpar.date
612
- icon=self.TREpar.icon
613
- self.currITEpar=self.TREpar
614
- else:
615
- ITEs:ITEpar=self.ui.Explorer.ITEsfromTRE(self.TREpar)
616
- title+=': '+ITEs[0].name
617
- subtitle=self.TREpar.date
618
- icon=ITEs[self.TREpar.step].icon
619
- self.currITEpar=ITEs[self.TREpar.step]
620
- self.ui.title.setText(title)
621
- self.ui.subtitle.setText(subtitle)
622
-
623
- if self.currITEpar:
624
- InfoMessage=self.currITEpar.InfoMessage()
625
- else:
626
- InfoMessage=''
627
- self.ui.title.setToolTip(InfoMessage)
628
- self.ui.title.setStatusTip(InfoMessage)
629
- self.ui.subtitle.setToolTip(InfoMessage)
630
- self.ui.subtitle.setStatusTip(InfoMessage)
631
-
632
- self.ui.title_icon.setVisible(icon is not None)
633
- self.ui.title_icon.setIcon(TreeIcons.icons[icon])
634
-
635
- def adjustProjectSelection(self):
636
- self.adjustProcessSelection()
637
- self.ui.Explorer.adjustProjectSelection()
638
-
639
- def adjustSwitches(self):
640
- for k in range(len(self.projectTree.itemList[0])):
641
- FlagVisible=any([i[0].flagRun<=0 and i[0].Process!=ProcessTypes.cal for i in self.projectTree.itemList[1][k][0]])
642
- self.projectTree.itemList[0][k].FlagRunnable=FlagVisible
643
- topLevelItem=self.projectTree.topLevelItem(k)
644
- itemWidget=self.projectTree.itemWidget(topLevelItem,1)
645
- if itemWidget:
646
- switch:ModernSwitch=itemWidget.findChildren(ModernSwitch)[0]
647
- if switch:
648
- switch.setVisible(FlagVisible)
649
- #switch.setEnabled(self.FlagRun==0)
650
- #self.swithcEnabled(self.FlagRun==0)
651
- self.setButtonRunVisible()
652
640
 
653
641
  def disableDropping(self,FlagDisableed=True):
654
642
  self.projectTree.setDragEnabled(not FlagDisableed)
@@ -679,22 +667,12 @@ class gPaIRS(QMainWindow):
679
667
  self.ui.progress_Proc.setValue(0)
680
668
  self.ui.time_stamp.setText('Initializing...')
681
669
  else:
682
- FlagButtonRun=self.ui.progress_Proc.value()==0 and self.FlagRun==0
670
+ FlagButtonRun=self.ui.progress_Proc.value() in (0,self.ui.progress_Proc.maximum()) and self.FlagRun==0
683
671
  self.ui.button_Run.setVisible(FlagButtonRun)
684
672
  self.ui.button_pause.setVisible(not FlagButtonRun)
685
673
  self.ui.w_progress_Proc.setVisible(not FlagButtonRun)
674
+ self.ui.tabAreaWidget.display_controls()
686
675
 
687
- def adjustMenuFile(self):
688
- self.ui.actionSave.setEnabled(not self.GPApar.FlagSaved)
689
- self.ui.actionClose.setEnabled(self.GPApar.outName not in ('',lastcfgname))
690
- """
691
- bar=self.projectTree.actionBar
692
- for n in ['Save','Saveas','Close']:
693
- button:QPushButton=getattr(bar,'button_'+n.lower())
694
- action:QAction=getattr(self.ui,'action'+n)
695
- action.setEnabled(button.isEnabled())
696
- """
697
-
698
676
  def editingFinished(self,tree):
699
677
  self.ui.Explorer.arrangeCurrentProcess(tree)
700
678
  self.adjustProcessSelection()
@@ -741,6 +719,7 @@ class gPaIRS(QMainWindow):
741
719
 
742
720
  icons=[w.TABname.split('_')[0].lower()+'_logo' for w in self.tabWidgets]
743
721
  self.ui.tabAreaWidget.setupTabArea(self.tabWidgets,icons)
722
+ self.ui.tabAreaWidget.gui=self
744
723
  self.tabWidgets=self.tabWidgets+[self.ui.tabAreaWidget]
745
724
  self.tabNames=[tab.TABname for tab in self.tabWidgets]
746
725
 
@@ -760,6 +739,11 @@ class gPaIRS(QMainWindow):
760
739
  self.binTree=self.ui.Explorer.binTree
761
740
  self.TREpar=self.ui.Explorer.TREpar
762
741
 
742
+ self.ui.Explorer.gui=self
743
+ self.projectTree.gui=self
744
+ self.processTree.gui=self
745
+ self.binTree.gui=self
746
+
763
747
  for w in self.tabWidgets:
764
748
  w:gPaIRS_Tab
765
749
  w.TABpar_prev=[]
@@ -808,6 +792,13 @@ class gPaIRS(QMainWindow):
808
792
  self.w_Input.ui.button_forward.clicked.disconnect()
809
793
  self.w_Input.display_controls=lambda:None
810
794
 
795
+ self.ui.w_header.layout().removeWidget(self.ui.button_restore_undo)
796
+ self.ui.tabAreaWidget.buttonBar_layout.addWidget(self.ui.button_restore_undo)
797
+ self.ui.button_restore_undo.setFixedWidth(TabAreaWidget.buttonSize[1])
798
+ self.ui.button_restore_undo.setFixedHeight(TabAreaWidget.buttonSize[1])
799
+ self.ui.button_restore_undo.clicked.connect(self.fullCallback)
800
+ self.ui.tabAreaWidget.ui.button_restore_undo=self.ui.button_restore_undo
801
+
811
802
  self.ui.tabAreaWidget.FlagDisplayControls=True
812
803
  self.ui.tabAreaWidget.ui.button_back=self.w_Input.ui.button_back
813
804
  self.ui.tabAreaWidget.ui.button_back.clicked.connect(lambda: self.button_back_forward_action(-1))
@@ -820,21 +811,37 @@ class gPaIRS(QMainWindow):
820
811
  self.onlyReadLabel=QLabel('Read-Only')
821
812
  font=self.onlyReadLabel.font()
822
813
  font.setBold(True)
814
+ font.setItalic(True)
815
+ font.setPixelSize(fontPixelSize)
823
816
  self.onlyReadLabel.setFont(font)
824
817
  self.onlyReadLabel.setStyleSheet('color: rgb(51, 102, 255)') #('color: rgb(255,51,51);')
825
- self.ui.tabAreaWidget.buttonBar_layout.addWidget(self.onlyReadLabel)
818
+ #self.ui.tabAreaWidget.buttonBar_layout.addWidget(self.onlyReadLabel)
826
819
  self.ui.tabAreaWidget.onlyReadLabel=self.onlyReadLabel
827
820
  self.ui.tabAreaWidget.button_reset_step=self.ui.button_reset_step
821
+ self.ui.tabAreaWidget.button_step_inherit=self.ui.button_step_inherit
828
822
  self.ui.tabAreaWidget.button_copy_step=self.ui.button_copy_step
829
823
  self.ui.tabAreaWidget.button_link_step=self.ui.button_link_step
830
824
 
831
- for b in [self.ui.button_reset_step,self.ui.button_copy_step,self.ui.button_link_step]:
825
+ self.w_RCL = QWidget(self) #CLR: copy, link, reset
826
+ self.RCL_layout = QHBoxLayout()
827
+ self.RCL_layout.setContentsMargins(0, 0, 0, 0)
828
+ self.RCL_layout.setSpacing(actionButtonSpacing*2)
829
+ self.w_RCL.setLayout(self.RCL_layout)
830
+
831
+ self.RCL_layout.addSpacerItem(QSpacerItem(projectActionButtonSize[1], projectActionButtonSize[1], QSizePolicy.Expanding, QSizePolicy.Minimum))
832
+ self.RCL_layout.addWidget(self.onlyReadLabel)
833
+ self.RCL_layout.addSpacerItem(QSpacerItem(5, projectActionButtonSize[1], QSizePolicy.Minimum, QSizePolicy.Minimum))
834
+ for b in [self.ui.button_reset_step,self.ui.button_step_inherit,self.ui.button_copy_step,self.ui.button_link_step]:
832
835
  self.ui.w_header.layout().removeWidget(b)
833
- self.ui.tabAreaWidget.buttonBar_layout.addWidget(b)
834
- b.setFixedSize(TabAreaWidget.buttonSize[1],TabAreaWidget.buttonSize[1])
835
- b.setIconSize(QSize(TabAreaWidget.buttonSize[1]-8,TabAreaWidget.buttonSize[1]-8))
836
+ #self.ui.tabAreaWidget.buttonBar_layout.addWidget(b)
837
+ #b.setFixedSize(TabAreaWidget.buttonSize[1],TabAreaWidget.buttonSize[1])
838
+ #b.setIconSize(QSize(TabAreaWidget.buttonSize[1]-8,TabAreaWidget.buttonSize[1]-8))
839
+ self.RCL_layout.addWidget(b)
840
+ b.setFixedSize(projectActionButtonSize[1],projectActionButtonSize[1])
841
+ b.setIconSize(QSize(projectActionButtonSize[0],projectActionButtonSize[0]))
836
842
  if hasattr(self,b.objectName()+'_action'):
837
843
  b.clicked.connect(getattr(self,b.objectName()+'_action'))
844
+ self.ui.Explorer.processTree_layout.addWidget(self.w_RCL)
838
845
 
839
846
  self.w_Input.ui.button_back.setFixedSize(TabAreaWidget.buttonSize[1],TabAreaWidget.buttonSize[1])
840
847
  self.w_Input.ui.button_back.setIconSize(QSize(TabAreaWidget.buttonSize[1]-2,TabAreaWidget.buttonSize[1]-2))
@@ -846,8 +853,29 @@ class gPaIRS(QMainWindow):
846
853
  self.ui.tabAreaWidget.FlagPrevPropagation=FlagPrevPropagationTabSplitter
847
854
  self.ui.Explorer.inheritance=self.inheritance
848
855
 
856
+ self.brush_icon=QIcon(icons_path+"brush_cursor.png")
857
+ self.w_Vis.ui.icon.addfuncclick['copy_VIS']=lambda: self.copy_link_action(self.w_Vis.ui.name_tab,lambda isl,ima: self.copy_VIS(isl,ima),menuTitle='Copy graphical settings from...',icon=self.brush_icon)
858
+ self.w_Vis.ui.icon.setCustomCursor()
859
+
849
860
  self.defineTABbridges()
850
-
861
+
862
+ for c in self.findChildren(PaIRSTree):
863
+ c:PaIRSTree
864
+ c.gui=self
865
+
866
+ def fullCallback(self):
867
+ for w in self.tabWidgets:
868
+ w:gPaIRS_Tab
869
+ TABpar_ind=w.TABpar_at(w.TABpar.ind[:-1]+[-1])
870
+ if TABpar_ind:
871
+ if w.TABpar.isDifferentFrom(TABpar_ind,exceptions=w.TABpar.unchecked_fields+['ind']):
872
+ w.TABpar.ind[-1]=-1
873
+ w.fullCallback('Restored configuration')
874
+ break
875
+ ind=[i for i in w.TABpar.ind]
876
+ ind[-1]=-1
877
+ self.setTABpars_at(ind)
878
+
851
879
  def defineMenuActions(self):
852
880
  self.projectTree.button_open_action=self.open_project
853
881
  self.projectTree.button_save_action=self.save_project
@@ -872,6 +900,10 @@ class gPaIRS(QMainWindow):
872
900
  self.showChanges=lambda: changes(self,Log_Tab,fileChanges)
873
901
  self.ui.actionChanges.triggered.connect(self.showChanges)
874
902
  self.ui.actionGuide.triggered.connect(self.guide)
903
+ self.ui.actionDownload.setVisible(not Flag_ISEXE)
904
+ if not Flag_ISEXE:
905
+ self.ui.menuHelp.insertSeparator(self.ui.actionDownload)
906
+ self.ui.actionDownload.triggered.connect(self.downloadApp)
875
907
  self.ui.actionAbout.triggered.connect(self.about)
876
908
 
877
909
  self.ui.button_PaIRS_download.clicked.connect(lambda: button_download_PaIRS_action(self,self.app))
@@ -889,6 +921,8 @@ class gPaIRS(QMainWindow):
889
921
  self.w_Input.ui.button_back.setEnabled(not Flag)
890
922
  self.w_Input.ui.button_forward.setEnabled(not Flag)
891
923
 
924
+ self.ui.menubar.setEnabled(not Flag)
925
+
892
926
  #evita TABpar.FlagSettingPar=Flag così che sai dove FlagSettingPar è settato True o False
893
927
  ImageTreeWidget.disableTab(self.w_Input.ui.imTreeWidget,Flag)
894
928
 
@@ -902,12 +936,25 @@ class gPaIRS(QMainWindow):
902
936
  ind=w.TABpar.ind
903
937
  ind[-1]+=step
904
938
  w.TABpar.copyfrom(w.TABpar_at(ind))
905
- FlagAdjustPar=w.TABpar.ind[-1]==0
906
- FlagBridge=False
939
+ FlagAdjustPar=w.TABpar.FlagInit==False or w.TABpar.Process==ProcessTypes.cal #w.TABpar.ind[-1]==0
940
+ FlagBridge=w.TABpar.Process==ProcessTypes.cal #False
941
+ if FlagAdjustPar or FlagBridge:
942
+ for w in self.tabWidgets:
943
+ if not w.TABpar.FlagNone:
944
+ w:gPaIRS_Tab
945
+ if FlagAdjustPar:
946
+ FlagSettingPar=TABpar.FlagSettingPar
947
+ TABpar.FlagSettingPar=True
948
+ w.adjustTABpar()
949
+ TABpar.FlagSettingPar=FlagSettingPar
950
+ if FlagBridge: self.bridge(w.TABname)
951
+ FlagAdjustPar=False
952
+ FlagBridge=False
907
953
  for w in self.tabWidgets:
908
954
  w:gPaIRS_Tab
909
955
  if not w.TABpar.FlagNone:
910
956
  w.setTABpar(FlagAdjustPar,FlagBridge)
957
+ self.ui.Explorer.setITElayout()
911
958
  return
912
959
 
913
960
  def bfContextMenu(self,bf,event):
@@ -1006,103 +1053,57 @@ class gPaIRS(QMainWindow):
1006
1053
  self.adjustItemWidgets(ind)
1007
1054
 
1008
1055
  self.inheritance(ind)
1056
+ self.IOVinheritance(ind)
1009
1057
  self.adjustDependencies(ITE)
1010
1058
  #self.checkFutureProc()
1011
1059
  tab.add_TABpar_bridge=add_TABpar_bridge
1012
1060
 
1013
- def adjustDependencies(self,ITE:ITEpar):
1014
- for ind_slave in ITE.dependencies:
1015
- self.copy_pars(ind_slave,ITE.ind,FlagSet=False)
1016
- self.inheritance(ind_slave)
1017
- self.setLinks(ind_slave,ITE.ind)
1018
-
1019
- def adjustItemWidgets(self,ind=None):
1020
- if ind is None: ind=[self.TREpar.project, self.TREpar.tree, self.TREpar.process, self.TREpar.step, -1]
1021
- TRE:TREpar=self.projectTree.itemList[0][ind[0]]
1022
- topLevelItem=self.projectTree.topLevelItem(ind[0])
1023
- itemWidget=self.projectTree.itemWidget(topLevelItem,1)
1024
- if itemWidget:
1025
- title:QLabel=itemWidget.findChildren(QLabel,'title_project')[0]
1026
- title.setText(TRE.name+TRE.saveBullet())
1027
- subtitle:QLabel=itemWidget.findChildren(QLabel,'subtitle_project')[0]
1028
- subtitle.setText(TRE.date)
1029
- InfoMessage=TRE.InfoMessage()
1030
- title.setToolTip(InfoMessage)
1031
- title.setStatusTip(InfoMessage)
1032
- subtitle.setToolTip(InfoMessage)
1033
- subtitle.setStatusTip(InfoMessage)
1034
- if self.TREpar.project==ind[0] and self.TREpar.tree==ind[1] and self.TREpar.process is not None:
1035
- self.adjustTitleHeader()
1036
- self.projectTree.actionBar.button_save.setEnabled(not self.TREpar.FlagSaved)
1037
- topLevelItem=self.processTree.topLevelItem(ind[2])
1038
- itemWidget=self.processTree.itemWidget(topLevelItem,1)
1039
- if itemWidget:
1040
- title:QLabel=itemWidget.findChildren(QLabel,'title_process')[0]
1041
- subtitle:QLabel=itemWidget.findChildren(QLabel,'subtitle_process')[0]
1042
- subtitle.setText(TRE.date)
1043
- ITE:ITEpar=self.ui.Explorer.ITEfromTRE(TRE)
1044
- InfoMessage=ITE.InfoMessage()
1045
- title.setToolTip(InfoMessage)
1046
- title.setStatusTip(InfoMessage)
1047
- subtitle.setToolTip(InfoMessage)
1048
- subtitle.setStatusTip(InfoMessage)
1049
- self.adjustTitleHeader()
1050
- self.adjustWorkspaceHeader()
1051
-
1052
- def updateProjectItemWidget(self):
1053
- TRE:TREpar=self.projectTree.itemList[0][self.TREpar.project]
1054
- TRE.modifiedDate=currentTimeString()
1055
- TRE.date=f'Modified: {TRE.modifiedDate}'
1056
- TRE.FlagSaved=False
1057
- self.TREpar.copyfrom(TRE)
1058
-
1059
- self.GPApar.modifiedDate=TRE.modifiedDate
1060
- self.GPApar.date=TRE.date
1061
- self.GPApar.FlagSaved=False
1062
-
1063
- self.adjustItemWidgets()
1064
-
1065
- def updateWorkspace(self):
1066
- self.GPApar.modifiedDate=currentTimeString()
1067
- self.GPApar.date=f'Modified: {self.GPApar.modifiedDate}'
1068
- self.GPApar.FlagSaved=False
1069
-
1070
- self.adjustWorkspaceHeader()
1071
-
1072
1061
  def define_setTABpar_bridge(self,tab:gPaIRS_Tab):
1073
1062
  def setTABpar_bridge(FlagAdjustPar,FlagCallback=False):
1074
1063
  focusWidget=self.focusWidget()
1075
1064
  TABname=tab.TABname
1076
1065
  self.bridge(TABname)
1077
1066
  if FlagAdjustPar:
1067
+ FlagSettingPar=TABpar.FlagSettingPar
1068
+ TABpar.FlagSettingPar=True
1078
1069
  for w in self.tabWidgets:
1079
1070
  if w.TABpar.FlagNone: continue
1080
1071
  w:gPaIRS_Tab
1081
1072
  if w!=tab:
1082
1073
  w.adjustTABpar()
1083
1074
  self.bridge(w.TABname)
1075
+ TABpar.FlagSettingPar=FlagSettingPar
1084
1076
  FlagAdjustPar=False
1085
1077
  FlagBridge=False
1078
+ FlagDisplayControls=False
1086
1079
  for w in self.tabWidgets:
1087
1080
  w:gPaIRS_Tab
1088
1081
  if not w.TABpar.FlagNone and w!=self.w_Log:
1089
1082
  if w.TABpar_old.isDifferentFrom(w.TABpar,exceptions=['ind'],FlagStrictDiff=True):
1090
- w.setTABpar(FlagAdjustPar,FlagBridge,FlagCallback) #setting parameters without bridge
1083
+ w.setTABpar(FlagAdjustPar,FlagBridge,FlagCallback,FlagDisplayControls) #setting parameters without bridge
1091
1084
  else:
1092
1085
  if w==self.w_Vis_CalVi and w.TABpar.plane and w.TABpar.cam:
1093
1086
  self.w_Vis_CalVi.calibView.show()
1094
- w.TABpar_old.copyfromfields(w.TABpar,['ind'])
1087
+ w.TABpar_old.copyfrom(w.TABpar,exceptions=['ind'])
1095
1088
  if not FlagCallback:
1096
1089
  w.adjustTABparInd()
1097
- self.logBridge()
1098
- if self.w_Log.TABpar_old.isDifferentFrom(self.w_Log.TABpar):
1099
- self.w_Log.setTABpar(FlagAdjustPar,FlagBridge,FlagCallback)
1100
- else:
1101
- self.w_Log.TABpar_old.copyfromfields(self.w_Log.TABpar,['ind'])
1102
- if not FlagCallback: self.w_Log.adjustTABparInd()
1103
1090
  self.ui.Explorer.ITEpar.FlagInit=False
1104
1091
  self.ui.Explorer.setITElayout()
1105
- if not FlagCallback: self.inheritance(tab.TABpar.ind)
1092
+ if not self.w_Log.TABpar.FlagNone:
1093
+ if self.w_Log.LOGpar.flagRun!=-2:
1094
+ self.logBridge()
1095
+ if self.w_Log.TABpar_old.isDifferentFrom(self.w_Log.TABpar,FlagStrictDiff=True):
1096
+ self.w_Log.setTABpar(FlagAdjustPar,FlagBridge,FlagCallback)
1097
+ else:
1098
+ self.w_Log.TABpar_old.copyfrom(self.w_Log.TABpar,exceptions=['ind'])
1099
+ if not FlagCallback: self.w_Log.adjustTABparInd()
1100
+ else:
1101
+ self.w_Log.setTABpar(FlagAdjustPar=False,FlagBridge=False,FlagCallback=False)
1102
+ if not FlagCallback:
1103
+ self.inheritance(tab.TABpar.ind)
1104
+ ITE_ind:ITEpar=self.ui.Explorer.ITEfromInd(tab.TABpar.ind)
1105
+ self.adjustDependencies(ITE_ind)
1106
+ self.ui.tabAreaWidget.display_controls()
1106
1107
 
1107
1108
  if focusWidget:
1108
1109
  self.app.processEvents()
@@ -1110,7 +1111,9 @@ class gPaIRS(QMainWindow):
1110
1111
  tab.setTABpar_bridge=setTABpar_bridge
1111
1112
 
1112
1113
  def logBridge(self):
1114
+ OUT:OUTpar = self.w_Output.TABpar
1113
1115
  LOG:LOGpar = self.w_Log.TABpar
1116
+ VIS:VISpar = self.w_Vis.TABpar
1114
1117
  ITE:ITEpar = self.ui.Explorer.ITEpar #self.ui.Explorer.ITEfromTRE(self.TREpar)
1115
1118
 
1116
1119
  if ITE.flagRun==0:
@@ -1131,6 +1134,23 @@ class gPaIRS(QMainWindow):
1131
1134
  if errorText:
1132
1135
  errorText='\n\n'+ITE.procdata.headerSection('CRITICAL ISSUES',errorText,'X')
1133
1136
  LOG.text=PaIRS_Header+ITE.procdata.itemname+warnigText+errorText
1137
+ if VIS.FlagView:
1138
+ outPathRoot=myStandardRoot(OUT.path+OUT.subfold+OUT.root)
1139
+ logfile=ITE.procdata.procOutName()+'.log'
1140
+ if ITE.procdata.outPathRoot=='': logfile=outPathRoot+logfile
1141
+ border='o' #·●⦁᛫
1142
+ headerWidth=54
1143
+ result_text = '\n\n\n\n\n'+ITE.procdata.eyeHeaderSection('EXISTING PROCESS LOG',width=headerWidth,border=border) +f"\nLog file: '{os.path.basename(logfile)}'\n\n"
1144
+ if os.path.isfile(logfile):
1145
+ try:
1146
+ with open(logfile, 'r', encoding='utf-8') as f:
1147
+ log_content = f.read()
1148
+ result_text += "\n" + log_content
1149
+ except Exception as e:
1150
+ result_text += f"\nError reading log file '{os.path.basename(logfile)}:'\n{e}"
1151
+ else:
1152
+ result_text += f"\nLog file '{os.path.basename(logfile)}' not found!"
1153
+ LOG.text+=result_text+'\n\n'+ITE.procdata.headerSection('END of EXISTING PROCESS LOG',' ',border,headerWidth)
1134
1154
  else:
1135
1155
  LOG.text=ITE.procdata.Log
1136
1156
 
@@ -1178,7 +1198,7 @@ class gPaIRS(QMainWindow):
1178
1198
  for k in range(len(INP.imList[c][f])):
1179
1199
  if INP.imEx[c][f][k]:
1180
1200
  OUT.imageFile=INP.imList[c][f][k]
1181
- break
1201
+ break
1182
1202
 
1183
1203
  VIS.img=INP.selection[0]
1184
1204
  VIS.cam=INP.selection[1]
@@ -1203,7 +1223,7 @@ class gPaIRS(QMainWindow):
1203
1223
  imListMin=[]
1204
1224
  outPathRoot=myStandardRoot(OUT.path+OUT.subfold+OUT.root)
1205
1225
  for c in range(INP.ncam):
1206
- imListMin.append([outPathRoot+f'_cam{c+1}_a_min.png',outPathRoot+f'_cam{c+1}_a_min.png'])
1226
+ imListMin.append([outPathRoot+f'_cam{c+1}_a_min.png',outPathRoot+f'_cam{c+1}_b_min.png'])
1207
1227
 
1208
1228
  INP.FlagMIN = True
1209
1229
  INP.FlagTR = PRO_Min.FlagTR
@@ -1220,36 +1240,37 @@ class gPaIRS(QMainWindow):
1220
1240
  VIS.FlagTR=PRO_Min.FlagTR
1221
1241
  VIS.LaserType=PRO_Min.LaserType
1222
1242
  elif TABname=='Process_Disp':
1223
- if VIS.Pro.isDifferentFrom(PRO_Disp):
1224
- VIS.Pro.copyfrom(PRO_Disp)
1243
+ if VIS.Pro.isDifferentFrom(PRO_Disp,exceptions=['FlagBordo']):
1244
+ VIS.Pro.copyfrom(PRO_Disp,exceptions=['FlagBordo'])
1225
1245
  VIS.Nit=PRO_Disp.Nit if VIS.flagRun!=-2 else ITE.procdata.numFinalized
1226
1246
  elif TABname=='Process':
1227
1247
  if VIS.Pro.isDifferentFrom(PRO):
1228
1248
  VIS.Pro.copyfrom(PRO)
1229
1249
  elif TABname=='Vis':
1230
1250
  INP.selection=[VIS.img,VIS.cam,VIS.frame]
1251
+ self.w_Input.InputAdjustSelection(INP)
1231
1252
  pass
1232
1253
  elif ITE.Step in [StepTypes.cal]:
1233
1254
  INP_CalVi.FlagReadCalib=PRO_CalVi.CalibProcType>=2
1234
1255
  INP_CalVi.CalibProcType=PRO_CalVi.CalibProcType
1235
1256
  if TABname=='Calibration':
1236
1257
  #FlagPrev=CAL.ind[-1]==len(self.w_Calibration.TABpar_prev_at(CAL.ind))-1
1237
- self.ui.logo_CalVi.setVisible(CAL.FlagCalVi and CAL.flagRun==0) #and FlagPrev)
1238
- self.ui.button_Run_CalVi.setVisible(CAL.FlagCalVi and CAL.flagRun==0) #and FlagPrev)
1258
+ self.ui.logo_CalVi.setVisible(CAL.FlagCalVi and CAL.flagRun==0 and not CAL.link) #and FlagPrev)
1259
+ self.ui.button_Run_CalVi.setVisible(CAL.FlagCalVi and CAL.flagRun==0 and not CAL.link) #and FlagPrev)
1239
1260
  if CAL.isDifferentFrom(self.w_Calibration.CALpar_old,fields=['FlagCalVi','flagRun']) or not INP_CalVi.FlagInit:
1240
1261
  for w in [self.w_Input_CalVi,self.w_Process_CalVi,self.w_Vis_CalVi]:
1241
1262
  k=self.ui.tabAreaWidget.widgets.index(w)
1242
1263
  SPL.FlagVisible[k]=CAL.FlagCalVi
1243
1264
  w.buttonTab.setVisible(CAL.FlagCalVi)
1244
- self.ui.tabAreaWidget.splitterResize()
1265
+ self.ui.tabAreaWidget.splitterResize(FlagReleased=False)
1245
1266
  width=sum([s if f else 0 for s,f in zip(SPL.sizes,SPL.FlagVisible)])
1246
1267
  if width<self.ui.tabAreaWidget.width():
1247
1268
  SPL.sizes[-1]= self.ui.tabAreaWidget.width()-width
1248
1269
  else: SPL.sizes[-1]=0
1249
- ITE.ncam=CAL.ncam
1250
- ITE.progress=len(CAL.calList)
1270
+ #ITE.ncam=CAL.ncam
1271
+ #ITE.progress=len(CAL.calList)
1251
1272
  elif TABname=='Input_CalVi':
1252
- VIS_CalVi.plane=INP_CalVi.row+1
1273
+ VIS_CalVi.plane=int(INP_CalVi.row)*(1+PRO_CalVi.TargetType)+1
1253
1274
  VIS_CalVi.FlagResetLevels=INP_CalVi.isDifferentFrom(self.w_Input_CalVi.INPpar_old,fields=['path']) or len(self.w_Input_CalVi.INPpar_old.filenames)==0
1254
1275
  VIS_CalVi.FlagResetZoom=INP_CalVi.isDifferentFrom(self.w_Input_CalVi.INPpar_old,fields=['x','y','w','h','W','H']) or len(self.w_Input_CalVi.INPpar_old.filenames)==0
1255
1276
  pass
@@ -1264,12 +1285,10 @@ class gPaIRS(QMainWindow):
1264
1285
  for k,p in enumerate(INP_CalVi.plapar):
1265
1286
  if len(p)>1:
1266
1287
  INP_CalVi.plapar[k]=[p[-1]]
1267
- if PRO_CalVi.isDifferentFrom(self.w_Process_CalVi.PROpar_old,exceptions=['ind']) or INP_CalVi.isDifferentFrom(self.w_Input_CalVi.INPpar_old,exceptions=['ind']) or not self.w_Vis_CalVi.FlagInitData or not PRO_CalVi.FlagInit:
1268
- self.initDataAndSetImgFromGui(INP_CalVi,PRO_CalVi)
1269
1288
  pass
1270
1289
  elif TABname=='Vis_CalVi':
1271
1290
  if VIS_CalVi.plane-1!=INP_CalVi.row:
1272
- INP_CalVi.row=VIS_CalVi.plane-1
1291
+ INP_CalVi.row=int( (VIS_CalVi.plane-1)/(1+PRO_CalVi.TargetType) )
1273
1292
  INP_CalVi.rows=[INP_CalVi.row]
1274
1293
  #INP_CalVi.col=0
1275
1294
  #INP_CalVi.cols=[INP_CalVi.col]
@@ -1278,6 +1297,12 @@ class gPaIRS(QMainWindow):
1278
1297
  pass
1279
1298
  return
1280
1299
 
1300
+ def getInheritance(self, ind):
1301
+ indpar=[j for j in ind]
1302
+ for j in range(indpar[-2]):
1303
+ indpar[-2]=j
1304
+ self.inheritance(indpar)
1305
+
1281
1306
  def inheritance(self,indpar):
1282
1307
  ITE:ITEpar = self.ui.Explorer.ITEfromInd(indpar) #self.ui.Explorer.ITEfromTRE(self.TREpar)
1283
1308
  if ITE.FlagNone: return
@@ -1296,35 +1321,31 @@ class gPaIRS(QMainWindow):
1296
1321
  imListMin=[]
1297
1322
  outPathRoot=myStandardRoot(OUT.path+OUT.subfold+OUT.root)
1298
1323
  for c in range(INP.ncam):
1299
- imListMin.append([outPathRoot+f'_cam{c+1}_a_min.png',outPathRoot+f'_cam{c+1}_a_min.png'])
1324
+ imListMin.append([outPathRoot+f'_cam{c+1}_a_min.png',outPathRoot+f'_cam{c+1}_b_min.png'])
1325
+ imageFileMin=INP.path
1326
+ FlagImage=False
1327
+ for c in range(len(INP.imList)):
1328
+ for f in range(len(INP.imList[c])):
1329
+ if INP.imList[c][f]:
1330
+ imageFileMin+=INP.imList[c][f][0]
1331
+ FlagImage=True
1332
+ break
1333
+ if FlagImage: break
1300
1334
  else:
1301
1335
  FlagMIN=False
1302
1336
  FlagTR=False
1303
1337
  LaserType=0 #0 single, 1 double
1304
1338
  imListMin=[]
1339
+ imageFileMin=None
1305
1340
  if Process==ProcessTypes.piv:
1306
1341
  children=[+1] #piv step
1307
1342
  else:
1308
1343
  children=[+1,+2] #disparity, spiv steps
1309
- FlagInit=True
1310
1344
  for c in children:
1311
1345
  ind_child=copy.deepcopy(ind)
1312
1346
  ind_child[-2]+=c
1313
1347
  TABpar_prev=self.w_Input.TABpar_prev_at(ind_child)
1314
1348
 
1315
- FlagInit=FlagInit and len(TABpar_prev)==1 and TABpar_prev[0].flagRun==0 and ITE.active
1316
- if FlagInit:
1317
- ind_child[-1]=0
1318
- INP_child:INPpar=self.w_Input.TABpar_at(ind_child)
1319
- INP_child.copyfrom(INP,exceptions=['Process','Step']+INP_child.parFields)
1320
- #self.bridge('Input',ind_child)
1321
- OUT_child:OUTpar=self.w_Output.TABpar_at(ind_child)
1322
- OUT_child.copyfrom(OUT,exceptions=['Process','Step']+OUT_child.parFields)
1323
- #self.bridge('Output',ind_child)
1324
- VIS:VISpar = self.w_Vis.TABpar_at(ind)
1325
- VIS_child:VISpar=self.w_Vis.TABpar_at(ind_child)
1326
- VIS_child.copyfrom(VIS,exceptions=['Process','Step']+VIS_child.parFields)
1327
-
1328
1349
  for d in range(len(TABpar_prev)):
1329
1350
  ind_child[-1]=d
1330
1351
  INP_child:INPpar=self.w_Input.TABpar_at(ind_child)
@@ -1334,6 +1355,9 @@ class gPaIRS(QMainWindow):
1334
1355
  INP_child.imListMin = deep_duplicate(imListMin)
1335
1356
  #INP_child.FlagInit = False
1336
1357
 
1358
+ OUT_child:OUTpar=self.w_Output.TABpar_at(ind_child)
1359
+ OUT_child.imageFileMin = imageFileMin
1360
+
1337
1361
  VIS_child:VISpar=self.w_Vis.TABpar_at(ind_child)
1338
1362
  VIS_child.FlagMIN = ITE.procdata.flagRun>0
1339
1363
  VIS_child.FlagTR = FlagTR
@@ -1356,6 +1380,7 @@ class gPaIRS(QMainWindow):
1356
1380
  for c in children:
1357
1381
  ind_child=copy.deepcopy(ind)
1358
1382
  ind_child[-2]+=c
1383
+
1359
1384
  for d in range(len(self.w_Input.TABpar_prev_at(ind_child))):
1360
1385
  ind_child[-1]=d
1361
1386
 
@@ -1370,16 +1395,38 @@ class gPaIRS(QMainWindow):
1370
1395
  VIS_child.calList = copy.deepcopy(calList)
1371
1396
  VIS_child.calEx = copy.deepcopy(calEx)
1372
1397
  #VIS_child.FlagInit = False
1373
-
1398
+
1399
+ elif Process == ProcessTypes.spiv and Step == StepTypes.disp:
1400
+ if ITE.active:
1401
+ FlagDISP=True
1402
+ else:
1403
+ FlagDISP=False
1404
+ children=[+1] #disparity, spiv steps
1405
+ for c in children:
1406
+ ind_child=copy.deepcopy(ind)
1407
+ ind_child[-2]+=c
1408
+ TABpar_prev=self.w_Input.TABpar_prev_at(ind_child)
1409
+
1410
+ for d in range(len(TABpar_prev)):
1411
+ ind_child[-1]=d
1412
+ OUT_child:OUTpar=self.w_Output.TABpar_at(ind_child)
1413
+ OUT_child.FlagDISP = FlagDISP
1414
+ """
1374
1415
  elif Process == ProcessTypes.spiv and Step == StepTypes.disp:
1375
1416
  if ITE.active:
1376
1417
  FlagDISP=True
1377
1418
  INP:INPpar = self.w_Input.TABpar_at(ind)
1378
1419
  OUT:OUTpar = self.w_Output.TABpar_at(ind)
1420
+ zconst=OUT.zconst
1421
+ xterm=OUT.xterm
1422
+ yterm=OUT.yterm
1379
1423
  outPathRoot=myStandardRoot(OUT.path+OUT.subfold+OUT.root)
1380
1424
  dispFile=outPathRoot+'.clz'
1381
1425
  else:
1382
1426
  FlagDISP=False
1427
+ zconst=0.0
1428
+ xterm=0.0
1429
+ yterm=0.0
1383
1430
  dispFile=''
1384
1431
  children=[+1] #disparity, spiv steps
1385
1432
  FlagInit=True
@@ -1388,105 +1435,454 @@ class gPaIRS(QMainWindow):
1388
1435
  ind_child[-2]+=c
1389
1436
  TABpar_prev=self.w_Input.TABpar_prev_at(ind_child)
1390
1437
 
1391
- FlagInit=FlagInit and len(TABpar_prev)==1 and TABpar_prev[0].flagRun==0 and ITE.active
1438
+ for d in range(len(TABpar_prev)):
1439
+ ind_child[-1]=d
1440
+
1441
+ INP_child:INPpar=self.w_Input.TABpar_at(ind_child)
1442
+ INP_child.FlagDISP = FlagDISP
1443
+ INP_child.dispFile = dispFile
1444
+ #INP_child.FlagInit = False
1445
+
1446
+ OUT_child:OUTpar=self.w_Output.TABpar_at(ind_child)
1447
+ OUT_child.FlagDISP = FlagDISP
1448
+ OUT_child.zconst= zconst
1449
+ OUT_child.xterm = xterm
1450
+ OUT_child.yterm = yterm
1451
+
1452
+ VIS_child:VISpar=self.w_Vis.TABpar_at(ind_child)
1453
+ VIS_child.FlagDISP = FlagDISP
1454
+ VIS_child.dispFile = dispFile
1455
+ #VIS_child.FlagInit = False
1456
+
1457
+ pass
1458
+ """
1459
+
1460
+ ITEs=self.ui.Explorer.ITEsfromInd(indpar)
1461
+ #currInd=list(ITEs[0].children).index(ITE.Step)+1
1462
+ for c in range(len(ITEs)): #range(currInd+1,len(ITEs))
1463
+ ITE_ind:ITEpar=ITEs[c]
1464
+ self.checkProcesses(FlagInit=True,ind=ITE_ind.ind)
1465
+ #self.checkProcesses(FlagInit=False,ind=ITE_ind.ind)
1466
+ self.ui.Explorer.setITElayout(ITE_ind)
1467
+ return
1468
+
1469
+ def IOVinheritance(self,indpar):
1470
+ ITE:ITEpar = self.ui.Explorer.ITEfromInd(indpar) #self.ui.Explorer.ITEfromTRE(self.TREpar)
1471
+ if ITE.FlagNone: return
1472
+ ind=copy.deepcopy(ITE.ind)
1473
+ Step=ITE.Step
1474
+ #inverse inheritance
1475
+ if Step not in (StepTypes.cal,) and ITE.active:
1476
+ INP:INPpar = self.w_Input.TABpar_at(ind)
1477
+ OUT:OUTpar = self.w_Output.TABpar_at(ind)
1478
+ VIS:VISpar = self.w_Vis.TABpar_at(ind)
1479
+
1480
+ #children=[-2, -1] if Step==StepTypes.spiv else [-1] #disparity, spiv steps #*
1481
+ for c in range(len(processData[ITE.Process]['children'])): #in children: #*
1482
+ ind_child=copy.deepcopy(ind)
1483
+ #ind_child[-2]+=c #*
1484
+ ind_child[-2]=c
1485
+ TABpar_prev=self.w_Input.TABpar_prev_at(ind_child)
1486
+ if TABpar_prev[0] is None: continue
1487
+
1488
+ FlagInit=len(TABpar_prev)==1 and TABpar_prev[0].flagRun==0
1392
1489
  if FlagInit:
1393
1490
  ind_child[-1]=0
1394
1491
  INP_child:INPpar=self.w_Input.TABpar_at(ind_child)
1395
1492
  INP_child.copyfrom(INP,exceptions=['Process','Step']+INP_child.parFields)
1396
- #self.bridge('Input',ind_child)
1493
+
1397
1494
  OUT_child:OUTpar=self.w_Output.TABpar_at(ind_child)
1398
1495
  OUT_child.copyfrom(OUT,exceptions=['Process','Step']+OUT_child.parFields)
1399
- #self.bridge('Output',ind_child)
1400
- VIS:VISpar = self.w_Vis.TABpar_at(ind)
1496
+
1401
1497
  VIS_child:VISpar=self.w_Vis.TABpar_at(ind_child)
1402
1498
  VIS_child.copyfrom(VIS,exceptions=['Process','Step']+VIS_child.parFields)
1499
+
1500
+ self.checkProcesses(FlagInit=True,ind=ind_child)
1501
+ self.checkProcesses(FlagInit=False,ind=ind_child)
1502
+ ITE_ind:ITEpar = self.ui.Explorer.ITEfromInd(ind_child)
1503
+ self.ui.Explorer.setITElayout(ITE_ind)
1504
+ self.inheritance(ind_child)
1505
+
1506
+ def IOVcopy(self,ind_slave,ind_master):
1507
+ ITE:ITEpar = self.ui.Explorer.ITEfromInd(ind_master) #self.ui.Explorer.ITEfromTRE(self.TREpar)
1508
+ if ITE.FlagNone: return
1403
1509
 
1404
- for d in range(len(TABpar_prev)):
1405
- ind_child[-1]=d
1510
+ #Input/Output/Vis inheritance
1511
+ INP:INPpar = self.w_Input.TABpar_at(ind_master)
1512
+ OUT:OUTpar = self.w_Output.TABpar_at(ind_master)
1513
+ VIS:VISpar = self.w_Vis.TABpar_at(ind_master)
1406
1514
 
1407
- INP_child:INPpar=self.w_Input.TABpar_at(ind_child)
1408
- INP_child.FlagDISP = FlagDISP
1409
- INP_child.dispFile = dispFile
1410
- #INP_child.FlagInit = False
1515
+ self.w_Input.INPpar.copyfrom(INP,exceptions=['Process','Step']+INP.parFields)
1516
+ self.w_Output.OUTpar.copyfrom(OUT,exceptions=['Process','Step']+OUT.parFields)
1517
+ self.w_Vis.VISpar.copyfrom(VIS,exceptions=['Process','Step']+VIS.parFields)
1518
+
1519
+ FlagNewPar=self.w_Input.isNewPar() or self.w_Output.isNewPar()
1520
+ ind_slave=self.w_Input.add_TABpar('Copy input/output data from step',FlagNewPar)
1521
+ self.setTABpars_at(ind_slave,FlagAdjustPar=True,FlagBridge=True,widget=self.w_Input)
1522
+
1523
+ ITE_slave:ITEpar = self.ui.Explorer.ITEfromInd(ind_slave) #self.ui.Explorer.ITEfromTRE(self.TREpar)
1524
+ self.ui.Explorer.setITElayout(ITE_slave)
1525
+ return
1526
+
1527
+ #*************************************************** Update workspace and projects
1528
+ def updateWorkspace(self):
1529
+ self.GPApar.modifiedDate=currentTimeString()
1530
+ self.GPApar.date=f'Modified: {self.GPApar.modifiedDate}'
1531
+ self.GPApar.FlagSaved=False
1532
+
1533
+ self.adjustWorkspaceHeader()
1534
+
1535
+ def adjustWorkspaceHeader(self):
1536
+ if self.GPApar.outName and self.GPApar.outName!=lastcfgname:
1537
+ title=self.GPApar.name+self.GPApar.saveBullet()
1538
+ subtitle=self.GPApar.date
1539
+ icon=self.GPApar.icon
1540
+ FlagVisible=True
1541
+ else:
1542
+ title=''
1543
+ subtitle=''
1544
+ icon=None
1545
+ FlagVisible=False
1546
+ self.ui.title_workspace.setVisible(FlagVisible)
1547
+ self.ui.subtitle_workspace.setVisible(FlagVisible)
1548
+ self.ui.title_workspace.setText(title)
1549
+ self.ui.subtitle_workspace.setText(subtitle)
1550
+
1551
+ InfoMessage=self.GPApar.InfoMessage()
1552
+ self.ui.title_workspace.setToolTip(InfoMessage)
1553
+ self.ui.title_workspace.setStatusTip(InfoMessage)
1554
+ self.ui.subtitle_workspace.setToolTip(InfoMessage)
1555
+ self.ui.subtitle_workspace.setStatusTip(InfoMessage)
1556
+
1557
+ self.ui.workspace_icon.setVisible(icon is not None)
1558
+ self.adjustMenuFile()
1559
+
1560
+ self.setGPaIRSTitle()
1561
+
1562
+ def adjustMenuFile(self):
1563
+ self.ui.actionSave.setEnabled(not self.GPApar.FlagSaved)
1564
+ self.ui.actionClose.setEnabled(self.GPApar.outName not in ('',lastcfgname))
1565
+
1566
+ def updateProjectItemWidget(self):
1567
+ TRE:TREpar=self.projectTree.itemList[0][self.TREpar.project]
1568
+ TRE.modifiedDate=currentTimeString()
1569
+ TRE.date=f'Modified: {TRE.modifiedDate}'
1570
+ TRE.FlagSaved=False
1571
+ self.TREpar.copyfrom(TRE)
1572
+
1573
+ self.GPApar.modifiedDate=TRE.modifiedDate
1574
+ self.GPApar.date=TRE.date
1575
+ self.GPApar.FlagSaved=False
1576
+
1577
+ self.adjustItemWidgets()
1578
+
1579
+ def adjustItemWidgets(self,ind=None):
1580
+ if ind is None: ind=[self.TREpar.project, self.TREpar.tree, self.TREpar.process, self.TREpar.step, -1]
1581
+ TRE:TREpar=self.projectTree.itemList[0][ind[0]]
1582
+ topLevelItem=self.projectTree.topLevelItem(ind[0])
1583
+ itemWidget=self.projectTree.itemWidget(topLevelItem,1)
1584
+ if itemWidget:
1585
+ title:QLabel=itemWidget.findChildren(QLabel,'title_project')[0]
1586
+ title.setText(TRE.name+TRE.saveBullet())
1587
+ subtitle:QLabel=itemWidget.findChildren(QLabel,'subtitle_project')[0]
1588
+ subtitle.setText(TRE.date)
1589
+ InfoMessage=TRE.InfoMessage()
1590
+ title.setToolTip(InfoMessage)
1591
+ title.setStatusTip(InfoMessage)
1592
+ subtitle.setToolTip(InfoMessage)
1593
+ subtitle.setStatusTip(InfoMessage)
1594
+ if self.TREpar.project==ind[0] and self.TREpar.tree==ind[1] and self.TREpar.process is not None:
1595
+ self.adjustTitleHeader()
1596
+ self.projectTree.actionBar.button_save.setEnabled(not self.TREpar.FlagSaved)
1597
+ topLevelItem=self.processTree.topLevelItem(ind[2])
1598
+ itemWidget=self.processTree.itemWidget(topLevelItem,1)
1599
+ if itemWidget:
1600
+ title:QLabel=itemWidget.findChildren(QLabel,'title_process')[0]
1601
+ subtitle:QLabel=itemWidget.findChildren(QLabel,'subtitle_process')[0]
1602
+ subtitle.setText(TRE.date)
1603
+ ITE:ITEpar=self.ui.Explorer.ITEfromTRE(TRE)
1604
+ InfoMessage=ITE.InfoMessage()
1605
+ title.setToolTip(InfoMessage)
1606
+ title.setStatusTip(InfoMessage)
1607
+ subtitle.setToolTip(InfoMessage)
1608
+ subtitle.setStatusTip(InfoMessage)
1609
+ self.adjustTitleHeader()
1610
+ self.adjustWorkspaceHeader()
1611
+
1612
+ def adjustTitleHeader(self):
1613
+ if self.TREpar.project is None:
1614
+ title='Welcome to PaIRS'
1615
+ subtitle='Particle Image Reconstruction Software'
1616
+ icon=None
1617
+ self.currITEpar=None
1618
+ else:
1619
+ title=self.TREpar.name+self.TREpar.saveBullet()
1620
+ if self.TREpar.process is None or self.TREpar.step is None:
1621
+ subtitle=self.TREpar.date
1622
+ icon=self.TREpar.icon
1623
+ self.currITEpar=self.TREpar
1624
+ else:
1625
+ ITEs:ITEpar=self.ui.Explorer.ITEsfromTRE(self.TREpar)
1626
+ title+=': '+ITEs[0].name
1627
+ subtitle=self.TREpar.date
1628
+ icon=ITEs[self.TREpar.step].icon
1629
+ self.currITEpar=ITEs[self.TREpar.step]
1630
+ self.ui.title.setText(title)
1631
+ self.ui.subtitle.setText(subtitle)
1632
+
1633
+ if self.currITEpar:
1634
+ InfoMessage=self.currITEpar.InfoMessage()
1635
+ else:
1636
+ InfoMessage=''
1637
+ self.ui.title.setToolTip(InfoMessage)
1638
+ self.ui.title.setStatusTip(InfoMessage)
1639
+ self.ui.subtitle.setToolTip(InfoMessage)
1640
+ self.ui.subtitle.setStatusTip(InfoMessage)
1641
+
1642
+ self.ui.title_icon.setVisible(icon is not None)
1643
+ self.ui.title_icon.setIcon(TreeIcons.icons[icon])
1644
+
1645
+ def adjustProcessSelection(self):
1646
+ FlagVisible=[False,False,False,False]
1647
+ if self.TREpar.project is None:
1648
+ FlagVisible[0]=True
1649
+ self.ui.Explorer.hideStepButtons()
1650
+ else:
1651
+ if self.TREpar.process is None:
1652
+ FlagVisible[1]=True
1653
+ self.ui.Explorer.hideStepButtons()
1654
+ else:
1655
+ if self.TREpar.step is None or self.TREpar.step==0:
1656
+ FlagVisible[2]=True
1657
+ else:
1658
+ FlagVisible[3]=True
1659
+ self.ui.projectPage.setVisible(FlagVisible[0])
1660
+ self.ui.processPage.setVisible(FlagVisible[1])
1661
+ self.ui.stepPage.setVisible(FlagVisible[2])
1662
+ self.ui.tabAreaWidget.setVisible(FlagVisible[3])
1663
+ self.w_RCL.setVisible(FlagVisible[3])
1664
+ #if FlagVisible[3]:
1665
+ # self.ui.tabAreaWidget.scrollArea.splitter.splitterResize()
1666
+
1667
+ self.adjustWorkspaceHeader()
1668
+ self.adjustTitleHeader()
1669
+ self.adjustSwitches()
1670
+
1671
+ self.ui.Explorer.cancelUndo()
1672
+
1673
+ def adjustProjectSelection(self):
1674
+ self.adjustProcessSelection()
1675
+ self.ui.Explorer.adjustProjectSelection()
1676
+
1677
+ def adjustSwitches(self):
1678
+ for k in range(len(self.projectTree.itemList[0])):
1679
+ topLevelItem=self.projectTree.topLevelItem(k)
1680
+ itemWidget=self.projectTree.itemWidget(topLevelItem,1)
1681
+ if itemWidget:
1682
+ switch:ModernSwitch=itemWidget.findChildren(ModernSwitch)[0]
1683
+ if switch:
1684
+ FlagVisible=any([i[0].flagRun<=0 and i[0].Process!=ProcessTypes.cal for i in self.projectTree.itemList[1][k][0]])
1685
+ self.projectTree.itemList[0][k].FlagRunnable=FlagVisible
1686
+ if not self.FlagRun:
1687
+ FlagQueue=len(self.projectTree.itemList[1][k][0])==0 or not FlagVisible or any([i[0].flagRun<=0 and i[0].Process!=ProcessTypes.cal and i[0].FlagQueue for i in self.projectTree.itemList[1][k][0]])
1688
+ else:
1689
+ FlagQueue=switch._checked
1690
+
1691
+ switch.setVisible(FlagVisible)
1692
+ switch.setSwitch(FlagQueue)
1693
+ self.projectTree.itemList[0][k].FlagQueue=FlagQueue
1694
+ if self.TREpar.project==k:
1695
+ self.TREpar.FlagQueue=FlagQueue
1696
+ #switch.setEnabled(self.FlagRun==0)
1697
+ if len(self.processTree.itemList):
1698
+ for k,i in enumerate(self.processTree.itemList[0]):
1699
+ topLevelItem=self.processTree.topLevelItem(k)
1700
+ itemWidget=self.processTree.itemWidget(topLevelItem,1)
1701
+ if itemWidget:
1702
+ switch:ModernSwitch=itemWidget.findChildren(ModernSwitch)[0]
1703
+ if switch:
1704
+ ITE:ITEpar=i[0]
1705
+ switch.setVisible(ITE.flagRun<=0 and ITE.Process!=ProcessTypes.cal and any([j.active and len(j.link)==0 for j in i[1:]]))
1706
+ #self.swithcEnabled(self.FlagRun==0)
1707
+ self.setButtonRunVisible()
1411
1708
 
1412
- VIS_child:VISpar=self.w_Vis.TABpar_at(ind_child)
1413
- VIS_child.FlagDISP = FlagDISP
1414
- VIS_child.dispFile = dispFile
1415
- #VIS_child.FlagInit = False
1709
+ #*************************************************** Link and copy
1710
+ def adjustDependencies(self,ITE:ITEpar):
1711
+ for ind_slave in ITE.dependencies:
1712
+ self.copy_pars(ind_slave,ITE.ind)
1713
+ #self.inheritance(ind_slave) #useless, already performed in copy_pars
1714
+ self.setLinks(ind_slave,ITE.ind)
1416
1715
 
1417
- pass
1418
-
1419
- ITEs=self.ui.Explorer.ITEsfromInd(indpar)
1420
- currInd=list(ITEs[0].children).index(ITE.Step)+1
1421
- for c in range(currInd+1,len(ITEs)):
1422
- ITE_ind:ITEpar=ITEs[c]
1423
- self.ui.Explorer.setITElayout(ITE_ind)
1424
- return
1425
-
1426
1716
  def button_reset_step_action(self):
1427
- if self.questionDialog('Are you sure you want to reset the current process step? This operation is irreversible!'):
1717
+ if self.questionDialog('Are you sure you want to reset the current process step? This operation will affect all the subsequent steps in the process and it is irreversible!'):
1428
1718
  self.reset_step(self.ui.Explorer.ITEpar.ind)
1429
1719
  return
1430
1720
 
1431
1721
  def reset_step(self,ind):
1432
1722
  FlagSettingPar=TABpar.FlagSettingPar
1433
1723
  TABpar.FlagSettingPar=True
1434
- ITE_ind:ITEpar=self.ui.Explorer.ITEfromInd(ind)
1435
- ITE_ind.procdata=data=dataTreePar(ITE_ind.Process,ITE_ind.Step)
1436
- ITE_ind.procdata.ind=ITE_ind.ind
1437
- ITE_ind.progress=0
1438
- self.setFlagRun(data,0)
1439
- self.setTABpars_at(ITE_ind.ind,FlagAdjustPar=True,widget=self.w_Vis)
1724
+ ITEs_ind:ITEpar=self.ui.Explorer.ITEsfromInd(ind)
1725
+ ind_child=copy.deepcopy(ind)
1726
+ for j in range(ind[-2],0,-1):
1727
+ ind_child[-2]=j-1
1728
+ ITE_ind:ITEpar=ITEs_ind[j]
1729
+ if not ITE_ind.active and ITE_ind.flagRun<0:
1730
+ ITE_ind.procdata=data=dataTreePar(ITE_ind.Process,ITE_ind.Step)
1731
+ ITE_ind.procdata.ind=ITE_ind.ind
1732
+ ITE_ind.progress=0
1733
+ self.setFlagRun(data,0,flagPrev=True)
1734
+ else:
1735
+ break
1736
+ for j in range(len(ITEs_ind)-1,ind[-2],-1):
1737
+ ind_child[-2]=j-1
1738
+ ITE_ind:ITEpar=ITEs_ind[j]
1739
+ ITE_ind.procdata=data=dataTreePar(ITE_ind.Process,ITE_ind.Step)
1740
+ ITE_ind.procdata.ind=ITE_ind.ind
1741
+ ITE_ind.progress=0
1742
+ self.setFlagRun(data,0,flagPrev=True)
1743
+ self.adjustDependencies(ITE_ind)
1744
+ self.inheritance(ind_child)
1745
+ ind_child[-1]=-1
1746
+ LOG_ind:LOGpar=self.w_Log.TABpar_at(ind_child)
1747
+ if LOG_ind:
1748
+ LOG_ind.progress=0
1749
+ if self.w_Log.LOGpar.ind[:-1]==LOG_ind.ind[:-1]:
1750
+ self.w_Log.setLOGlayout()
1751
+ self.ui.progress_Proc.setValue(0)
1752
+ self.setTABpars_at(ITE_ind.ind,FlagAdjustPar=True,widget=self.w_Calibration if ITE_ind.Step==StepTypes.cal else self.w_Vis)
1440
1753
  if data.ind[:-2]==self.ui.tabAreaWidget.TABpar.ind[:-2]:
1441
1754
  self.ui.Explorer.arrangeCurrentProcess(self.processTree)
1442
- self.adjustDependencies(ITE_ind)
1755
+
1756
+ self.adjustSwitches()
1757
+
1443
1758
  TABpar.FlagSettingPar=FlagSettingPar
1444
1759
 
1445
- def copy_link_action(self,button:QPushButton,fun=lambda ind_slave, ind_master:None, FlagExcludeLinked=False):
1446
- menu = QMenu(self)
1760
+ def IOVheritableSteps(self):
1447
1761
  ITE=self.ui.Explorer.ITEpar
1448
1762
  stepList={}
1449
- for process in self.processTree.itemList[0]:
1450
- ITE0:ITEpar=process[0]
1451
- for step in process[1:]:
1763
+ if len(self.processTree.itemList) and ITE.ind[2]<len(self.processTree.itemList[0]):
1764
+ for step in self.processTree.itemList[0][ITE.ind[2]]:
1452
1765
  step:ITEpar
1453
- FlagNoOverLink=True if not FlagExcludeLinked else len(step.link)==0
1454
- if step.Step==ITE.Step and ITE.ind[:-2]!=ITE0.ind[:-2] and FlagNoOverLink:
1455
- stepList[f'{step.ind[-3]+1}: '+ITE0.name]={'ind': step.ind, 'icon': ITE0.icon}
1766
+ if step.active and ITE.ind[:-1]!=step.ind[:-1]:
1767
+ INP:INPpar = self.w_Input.TABpar_at(step.ind)
1768
+ OUT:OUTpar = self.w_Output.TABpar_at(step.ind)
1769
+ VIS:VISpar = self.w_Vis.TABpar_at(step.ind)
1770
+ if INP is not None and OUT is not None and VIS is not None:
1771
+ stepList[step.name]={'ind': step.ind, 'icon': step.icon}
1772
+ return stepList
1773
+
1774
+ def linkableSteps(self,FlagExcludeLinked=False):
1775
+ ITE=self.ui.Explorer.ITEpar
1776
+ stepList={}
1777
+ if len(self.processTree.itemList):
1778
+ for process in self.processTree.itemList[0]:
1779
+ ITE0:ITEpar=process[0]
1780
+ for step in process[1:]:
1781
+ step:ITEpar
1782
+ FlagNoOverLink=True if not FlagExcludeLinked else len(step.link)==0
1783
+ if step.active and step.Step==ITE.Step and ITE.ind[:-2]!=ITE0.ind[:-2] and FlagNoOverLink:
1784
+ stepList[f'{step.ind[-3]+1}: '+ITE0.name]={'ind': step.ind, 'icon': ITE0.icon}
1785
+ return stepList
1786
+
1787
+ def copy_link_action(self,button:QPushButton, fun=lambda ind_slave, ind_master:None, FlagExcludeLinked=False, menuTitle='Copy step from...',icon=None,message='No process step available!', stepListType=0):
1788
+ if stepListType==1:
1789
+ stepList=self.IOVheritableSteps()
1790
+ else:
1791
+ stepList=self.linkableSteps(FlagExcludeLinked=FlagExcludeLinked)
1792
+ ITE=self.ui.Explorer.ITEpar
1456
1793
  if len(stepList)==0:
1457
- QToolTip.showText(button.mapToGlobal(button.rect().topLeft()), 'No unlinked process step available!')
1794
+ showTip(self,message)
1458
1795
  return None
1796
+ menu = QMenu(self)
1797
+ title_action = QAction(menuTitle, self)
1798
+ if icon: title_action.setIcon(icon)
1799
+ title_action.setDisabled(True) # Disabilita l'azione per evitare l'interazione
1800
+ menu.addAction(title_action)
1801
+ menu.addSeparator()
1459
1802
  for key, item in stepList.items():
1460
1803
  #for colormap in VIS_ColorMaps[colorMapClass]:
1461
1804
  nameItem=' '+key
1462
1805
  action:QAction = menu.addAction(TreeIcons.icons[item['icon']], nameItem)
1463
- action.triggered.connect(lambda _, name=nameItem: fun(ITE.ind,item['ind']))
1464
- return menu.exec(button.mapToGlobal(button.rect().bottomLeft()))
1806
+ action.triggered.connect(lambda _, name=key: fun(ITE.ind,stepList[name]['ind']))
1807
+ return menu.exec(QCursor.pos()) #menu.exec(button.mapToGlobal(button.rect().bottomLeft()))
1465
1808
 
1466
- def button_copy_step_action(self):
1467
- self.copy_link_action(self.ui.button_link_step,lambda isl,ima: self.copy_pars(isl,ima,FlagNew=True))
1809
+ def button_step_inherit_action(self):
1810
+ self.copy_link_action(self.ui.button_step_inherit,lambda isl,ima: self.IOVcopy(isl,ima),menuTitle='Copy input/output data from...', message='No process step available!', stepListType=1)
1468
1811
 
1469
- def copy_pars(self,ind_slave,ind_master,FlagNew=False,FlagSet=True):
1812
+ def button_copy_step_action(self):
1813
+ self.copy_link_action(self.ui.button_copy_step,lambda isl,ima: self.copy_pars_proc(isl,ima,FlagNew=True))
1814
+
1815
+ def checkCamCompatibility(self,ind_slave,ind_master):
1816
+ ITE_slave:ITEpar=self.ui.Explorer.ITEfromInd(ind_slave)
1817
+ isCompatible=True
1818
+ if ITE_slave.Step==StepTypes.min:
1819
+ INP_slave:INPpar=self.w_Input.TABpar_at(ind_slave)
1820
+ ncam_slave=INP_slave.ncam
1821
+ INP_master:INPpar=self.w_Input.TABpar_at(ind_master)
1822
+ ncam_master=INP_master.ncam
1823
+ isCompatible=ncam_slave==ncam_master
1824
+ elif ITE_slave.Step==StepTypes.cal:
1825
+ CAL_slave:CALpar=self.w_Calibration.TABpar_at(ind_slave)
1826
+ ncam_slave=CAL_slave.ncam
1827
+ CAL_master:CALpar=self.w_Calibration.TABpar_at(ind_master)
1828
+ ncam_master=CAL_master.ncam
1829
+ isCompatible=ncam_slave==ncam_master
1830
+ if not isCompatible:
1831
+ warningMessage=f'The number of cameras in the current step (={ncam_slave}) is different from that in the selected step (={ncam_master}). Please, select a different step or modify the number of cameras in the selected step before proceeding!'
1832
+ self.warningDialog(warningMessage)
1833
+ return isCompatible
1834
+
1835
+ def copy_pars(self,ind_slave,ind_master,FlagNew=False):
1470
1836
  ind_new=[i for i in ind_slave]
1471
1837
  if FlagNew: ind_new[-1]+=1
1472
1838
  for w in self.tabWidgets:
1473
1839
  w:gPaIRS_Tab
1474
- if not w.TABpar.FlagNone:
1475
- if FlagNew: w.gen_TABpar(ind_new)
1840
+ TAB_slave_curr:TABpar=w.TABpar_at(ind_slave)
1841
+ if TAB_slave_curr:
1842
+ if FlagNew: w.gen_TABpar(ind_new,Process=TAB_slave_curr.Process,Step=TAB_slave_curr.Step)
1476
1843
  TAB_slave:TABpar=w.TABpar_at(ind_new)
1477
- TAB_slave.copyfrom(w.TABpar_at(ind_master),exceptions=['ind','link'])
1844
+ TAB_slave.copyfrom(w.TABpar_at(ind_master),exceptions=['ind','link','Process'])
1478
1845
  ITE_master:ITEpar=self.ui.Explorer.ITEfromInd(ind_master)
1479
1846
  ITE_slave:ITEpar=self.ui.Explorer.ITEfromInd(ind_new)
1480
1847
  ITE_slave.ind=[i for i in ind_new]
1481
- ITE_slave.copyfrom(ITE_master,exceptions=['procdata','ind','link','dependencies'])
1482
- ITE_slave.procdata.copyfrom(ITE_master.procdata,exceptions=['ind','link'])
1848
+ ITE_slave.copyfrom(ITE_master,exceptions=['procdata','ind','link','Process','dependencies'])
1849
+ ITE_slave.procdata.copyfrom(ITE_master.procdata,exceptions=['ind','link','Process'])
1850
+ self.getInheritance(ind_slave)
1851
+ self.ui.Explorer.undoInd=None
1852
+ self.inheritance(ind_slave)
1483
1853
  self.ui.Explorer.setITElayout(ITE_slave)
1484
- if FlagSet: self.setTABpars_at(ind_new)
1854
+ self.adjustSwitches() #useless?
1855
+ return ind_new
1856
+
1857
+ def copy_pars_proc(self,ind_slave,ind_master,FlagNew=False,FlagSet=True):
1858
+ if not self.checkCamCompatibility(ind_slave,ind_master): return
1859
+ ITEs_slave=self.ui.Explorer.ITEsfromInd(ind_slave)
1860
+ ITEs_master=self.ui.Explorer.ITEsfromInd(ind_master)
1861
+ for c in range(ind_slave[-2]+1):
1862
+ ind_slave=ITEs_slave[c+1].ind
1863
+ ind_master=ITEs_master[c+1].ind
1864
+ ind_new=self.copy_pars(ind_slave,ind_master,FlagNew=True)
1865
+
1866
+ if FlagSet:
1867
+ self.ui.Explorer.arrangeCurrentProcess(self.ui.Explorer.processTree)
1868
+ self.ui.Explorer.selectStep()
1869
+ self.adjustSwitches()
1870
+ return ind_new
1871
+
1872
+ def copy_VIS(self,ind_slave,ind_master):
1873
+ ind_new=[i for i in ind_slave]
1874
+ w=self.w_Vis
1875
+ w:gPaIRS_Tab
1876
+ TAB_slave_curr:VISpar=w.TABpar_at(ind_slave)
1877
+ if TAB_slave_curr:
1878
+ TAB_slave:VISpar=w.TABpar_at(ind_new)
1879
+ TAB_slave.copyfromfields(w.TABpar_at(ind_master),fields=TAB_slave.graphics_fields)
1880
+ self.w_Vis.setTABpar_at(ind_new,FlagAdjustPar=True,FlagBridge=True)
1485
1881
  return ind_new
1486
1882
 
1487
1883
  def button_link_step_action(self):
1488
1884
  if self.ui.button_link_step.isChecked():
1489
- result=self.copy_link_action(self.ui.button_link_step,self.link_pars,FlagExcludeLinked=True)
1885
+ result=self.copy_link_action(self.ui.button_link_step,self.link_pars,FlagExcludeLinked=True,menuTitle='Link step to...')
1490
1886
  FlagUnlink=result is None
1491
1887
  else:
1492
1888
  FlagUnlink=True
@@ -1495,10 +1891,25 @@ class gPaIRS(QMainWindow):
1495
1891
  self.unlink_pars(ITE.ind)
1496
1892
  self.ui.button_link_step.setChecked(False)
1497
1893
 
1498
- def link_pars(self,ind_slave,ind_master):
1499
- ind_new=self.copy_pars(ind_slave,ind_master,FlagNew=True,FlagSet=False)
1500
- self.setLinks(ind_new,ind_master)
1501
- self.setTABpars_at(ind_new)
1894
+ def link_pars(self,ind_slave,ind_master,FlagSet=True):
1895
+ if not self.checkCamCompatibility(ind_slave,ind_master): return
1896
+ ITEs_slave=self.ui.Explorer.ITEsfromInd(ind_slave)
1897
+ ITEs_master=self.ui.Explorer.ITEsfromInd(ind_master)
1898
+ for c in range(ind_slave[-2]+1):
1899
+ ind_slave=ITEs_slave[c+1].ind
1900
+ ind_master=ITEs_master[c+1].ind
1901
+ ind_new=self.copy_pars(ind_slave,ind_master,FlagNew=True)
1902
+ self.setLinks(ind_new,ind_master)
1903
+ #item=self.processTree.topLevelItem(ind_new[2])
1904
+ #child=item.child(ind_new[3])
1905
+ #child.setIcon(0,self.processTree.linkedIcon)
1906
+
1907
+ #self.setTABpars_at(ind_new)
1908
+ if FlagSet:
1909
+ self.ui.Explorer.arrangeCurrentProcess(self.ui.Explorer.processTree)
1910
+ self.ui.Explorer.selectStep()
1911
+ self.adjustSwitches()
1912
+ return ind_new
1502
1913
 
1503
1914
  def setLinks(self,ind_slave,ind_master,FlagUnlink=False,ind_slave_new=None,ind_master_new=None):
1504
1915
  if ind_slave_new is None: ind_slave_new=copy.deepcopy(ind_slave)
@@ -1530,7 +1941,11 @@ class gPaIRS(QMainWindow):
1530
1941
  ind_master=ITE_slave.link
1531
1942
  if ind_master:
1532
1943
  self.setLinks(ind_slave,ind_master,FlagUnlink=True)
1944
+ #item=self.processTree.topLevelItem(ind_slave[2])
1945
+ #child=item.child(ind_slave[3])
1946
+ #child.setIcon(0,QIcon())
1533
1947
  self.setTABpars_at(ind_slave)
1948
+ self.adjustSwitches()
1534
1949
 
1535
1950
  #*************************************************** PROCESS
1536
1951
  #********************************** Launching
@@ -1552,78 +1967,127 @@ class gPaIRS(QMainWindow):
1552
1967
 
1553
1968
  def setButtonPause(self,flagPlay):
1554
1969
  if flagPlay:
1970
+ self.ui.label_updating_pairs.setVisible(False)
1555
1971
  self.ui.button_pause.setIcon(self.icon_play)
1556
1972
  stringa='Restart'
1557
1973
  else:
1974
+ self.ui.label_updating_pairs.setVisible(True)
1558
1975
  self.ui.button_pause.setIcon(self.icon_pause)
1559
1976
  stringa='Pause'
1560
1977
  tip=f'{stringa} process queue'+' ('+self.ui.button_pause.shortcut().toString(QKeySequence.NativeText)+')'
1561
1978
  self.ui.button_pause.setToolTip(tip)
1562
1979
  self.ui.button_pause.setStatusTip(tip)
1980
+ self.setButtonRunVisible()
1981
+ self.processTree.setProcessActionButtonLayout()
1982
+ """
1563
1983
  FlagButtonRun=self.ui.progress_Proc.value()==0
1564
1984
  self.ui.button_Run.setVisible(FlagButtonRun)
1565
1985
  self.ui.button_pause.setVisible(not FlagButtonRun)
1566
1986
  self.ui.w_progress_Proc.setVisible(not FlagButtonRun)
1567
-
1987
+ """
1988
+
1568
1989
  def run(self):
1569
- self.ui.button_pause.show()
1570
- self.ui.w_progress_Proc.show()
1571
- self.ui.button_Run.hide()
1572
- self.ui.label_updating_pairs.setVisible(True)
1573
1990
  self.setSwitchEnabled(False)
1574
1991
  self.disableDropping(True)
1575
1992
  if self.initializeWorkers():
1576
1993
  self.indProc=-1
1577
1994
  self.updateIndProc()
1578
1995
  else:
1579
- self.button_run_pause_action()
1996
+ self.FlagRun=0
1997
+ self.setButtonPause(True)
1998
+ #self.button_run_pause_action()
1580
1999
  self.stopProcs()
1581
2000
 
1582
2001
  def updateIndProc(self):
2002
+ self.indWorker+=1
2003
+ data=self.dataQueue[self.indWorker]
2004
+ self.initialize_proc(data)
2005
+ ITE_ind:ITEpar=self.ui.Explorer.ITEfromInd(data.ind)
2006
+ self.ui.Explorer.setITElayout(ITE_ind)
2007
+
1583
2008
  self.indProc+=1
1584
2009
  data:dataTreePar
1585
2010
  self.ui.Explorer.updateSwitchMovies(self.currind,FlagStart=False)
1586
2011
  self.procdata=None
1587
2012
  self.procdata=data=self.dataQueue[self.indProc]
1588
2013
  self.currind=data.ind
2014
+ self.checkProcesses(FlagInit=True,ind=self.currind)
2015
+ ITE:ITEpar=self.ui.Explorer.ITEfromInd(data.ind)
2016
+ self.ui.Explorer.setITElayout(ITE)
2017
+ if ITE.OptionDone==0:
2018
+ self.stopProcs()
2019
+ self.nextProc()
2020
+ return
2021
+
1589
2022
  self.procdata.uncopied_fields+=self.procFields
1590
2023
  self.ui.Explorer.updateSwitchMovies(self.currind,FlagStart=True)
1591
2024
 
1592
2025
  self.resetProc(data)
1593
2026
  self.setProgressBar(data)
1594
2027
  data.resetLog()
2028
+ try:
2029
+ with open(data.stepOutName()+'.log', 'w') as file:
2030
+ file.write(data.Log)
2031
+ except:
2032
+ pri.Error.red(f'Error while trying to save the process log file: {data.stepOutName()}.log.\n{traceback.format_exc()}\n')
1595
2033
 
1596
2034
  self.FlagResetPlot=True
1597
2035
  self.setFlagRun(data,-2)
2036
+ self.ui.Explorer.setITElayout(ITE)
2037
+ ITEs_ind:ITEpar=self.ui.Explorer.ITEsfromInd(self.currind)
2038
+ ind_child=copy.deepcopy(self.currind)
2039
+ for j in range(1,self.currind[-2]+1):
2040
+ ind_child[-2]=j-1
2041
+ ITE_child:ITEpar=ITEs_ind[j]
2042
+ data_child=ITE_child.procdata
2043
+ if data_child.flagRun==0:
2044
+ self.setFlagRun(data_child,-1)
2045
+ self.checkProcesses(FlagInit=True,ind=ind_child)
2046
+ self.ui.Explorer.setITElayout(ITE_child)
2047
+ if data_child.ind==self.ui.tabAreaWidget.TABpar.ind:
2048
+ self.w_Log.LOGpar.text=data_child.Log
2049
+ self.setTABpars_at(data_child.ind,FlagAdjustPar=True)
1598
2050
 
1599
2051
  FlagCurrent=data.ind==self.ui.tabAreaWidget.TABpar.ind
1600
2052
  if FlagCurrent:
1601
2053
  self.w_Log.LOGpar.text=data.Log
1602
2054
  self.setTABpars_at(data.ind,FlagAdjustPar=True)
1603
2055
  self.w_Log.buttonAction()
1604
- else:
1605
- ITE:ITEpar=self.ui.Explorer.ITEfromInd(data.ind)
1606
- self.ui.Explorer.setITElayout(ITE)
1607
2056
  self.FlagProcInit=True
1608
2057
  self.signals.indProc.emit(self.indProc)
1609
2058
  if data.flagRun==0:#not launched
1610
2059
  data.resetTimeStat()
1611
2060
  data.onStartTimeStat()
1612
2061
 
1613
- def setFlagRun(self,data:dataTreePar,flagRun):
2062
+ def setFlagRun(self,data:dataTreePar,flagRun,flagPrev=False):
1614
2063
  data.flagRun=flagRun #come ultimo o comunque dopo resetProc
1615
2064
  for w in self.tabWidgets:
1616
2065
  w:gPaIRS_Tab
1617
- TABpar_ind:TABpar=w.TABpar_at(data.ind)
1618
- if TABpar_ind: TABpar_ind.flagRun=flagRun
2066
+ if flagPrev:
2067
+ TABpar_prev=w.TABpar_prev_at(data.ind)
2068
+ for TABpar_ind in TABpar_prev:
2069
+ if TABpar_ind: TABpar_ind.flagRun=flagRun
2070
+ else:
2071
+ TABpar_ind:TABpar=w.TABpar_at(data.ind)
2072
+ if TABpar_ind: TABpar_ind.flagRun=flagRun
1619
2073
  ITE_ind:ITEpar=self.ui.Explorer.ITEfromInd(data.ind)
1620
2074
  ITE_ind.flagRun=flagRun
1621
-
2075
+
2076
+ self.ui.Explorer.setProcessFlagRun(data.ind)
2077
+ return
2078
+
1622
2079
  def nextProc(self):
1623
2080
  self.UpdatingImage=True
1624
2081
 
1625
2082
  if self.indProc<self.nProc-1 and self.FlagRun==1:
1626
- self.updateIndProc()
2083
+ try:
2084
+ self.updateIndProc()
2085
+ except:
2086
+ errMessage=f"{traceback.format_exc()}"
2087
+ self.procdata.warnings[0]+='\n\n'+self.procdata.headerSection('CRITICAL ERROR',errMessage,'X')
2088
+ self.store_proc(self.procdata)
2089
+ self.stopProcs()
2090
+ self.nextProc()
1627
2091
  else:
1628
2092
  self.ui.button_pause.setEnabled(False)
1629
2093
 
@@ -1643,7 +2107,7 @@ class gPaIRS(QMainWindow):
1643
2107
  self.ui.progress_Proc.setMaximum(data.nsteps)
1644
2108
  self.ui.progress_Proc.setValue(data.numFinalized)
1645
2109
  self.w_Log.TABpar_at(data.ind).nimg=data.nsteps
1646
- ITE:ITEpar=self.ui.Explorer.ITEfromInd(data.ind)
2110
+ #ITE:ITEpar=self.ui.Explorer.ITEfromInd(data.ind)
1647
2111
  return
1648
2112
 
1649
2113
  def setLogProgressBar(self,data:dataTreePar):
@@ -1675,27 +2139,38 @@ class gPaIRS(QMainWindow):
1675
2139
  nTot+=int(process[0].FlagQueue and step.active)
1676
2140
  nError+=int(process[0].FlagQueue and step.active and step.flagRun<=0 and step.Step!=StepTypes.cal and step.OptionDone==0)
1677
2141
  nValid+=int((process[0].FlagQueue and step.active and step.flagRun>0) or step.Step==StepTypes.cal)
1678
- if process[0].FlagQueue and step.active and step.flagRun<=0 and step.Step!=StepTypes.cal and step.OptionDone!=0:
2142
+ if process[0].FlagQueue and step.active and step.flagRun<=0 and step.Step!=StepTypes.cal and step.OptionDone!=0 and len(step.link)==0:
1679
2143
  self.nProc+=1
1680
- self.indWorker+=1
1681
2144
  data=step.procdata
1682
2145
  data.ind=step.ind
1683
- self.initialize_proc(data)
1684
2146
  self.dataQueue.append(data)
1685
- elif step.Step==StepTypes.cal and step.OptionDone==1:
2147
+ elif step.Process!=ProcessTypes.cal and step.Step==StepTypes.cal and step.OptionDone==1:
1686
2148
  data=step.procdata
1687
2149
  data.ind=step.ind
1688
2150
  self.setFlagRun(data,2)
2151
+ CAL:CALpar=self.w_Calibration.TABpar_at(step.ind)
2152
+ CAL.FlagCalVi=False
1689
2153
  if self.nProc==0 and nValid==0:
1690
2154
  self.warningDialog('No valid process found in the present projects!\nPlease, check for critical issues related to each step of the defined processes.',pixmap=icons_path+'issue.png')
1691
2155
  elif self.nProc==0 and nError>0:
1692
2156
  self.warningDialog(f'{nError} process step{"s" if nError>1 else ""} present{"" if nError>1 else "s"} critical issues!\nNo further valid process found in the present projects.\nPlease, check before running again.',pixmap=icons_path+'issue.png')
1693
2157
  elif self.nProc>0 and nError>0:
1694
- self.warningDialog(f'{nError} process step{"s" if nError>1 else ""} present{"" if nError>1 else "s"} critical issues!\n{"They" if nError>1 else "It"} will not be executed.',pixmap=icons_path+'warning.png')
2158
+ if not self.questionDialog(f'{nError} process step{"s" if nError>1 else ""} present{"" if nError>1 else "s"} critical issues!\n{"They" if nError>1 else "It"} will not be executed. Do you want to proceed with processing?'):
2159
+ self.contProc=self.nProc-1 #necessario per far funzionare stopProc in run quando il risultato di questa funzione è False
2160
+ return False
1695
2161
  elif self.nProc==0:
1696
2162
  self.warningDialog(f'All the processes found in the present projects have been already executed!',pixmap=icons_path+'completed.png')
1697
2163
  FlagQueue=len(self.dataQueue)!=0
1698
- self.contProc=-1 if not FlagQueue else 0
2164
+ self.contProc=-1 if not FlagQueue else 0
2165
+ self.putStepsInQueue()
2166
+ """
2167
+ for data in self.dataQueue:
2168
+ data:dataTreePar
2169
+ self.indWorker+=1
2170
+ self.initialize_proc(data)
2171
+ ITE_ind:ITEpar=self.ui.Explorer.ITEfromInd(data.ind)
2172
+ self.ui.Explorer.setITElayout(ITE_ind)
2173
+ """
1699
2174
  return FlagQueue
1700
2175
 
1701
2176
  def initialize_proc(self,data:dataTreePar):
@@ -1710,17 +2185,24 @@ class gPaIRS(QMainWindow):
1710
2185
  try:
1711
2186
  os.mkdir(currpath)
1712
2187
  except Exception as inst:
1713
- pri.Error.red(f'It was not possible to make the output folder:\n{traceback.print_exc}\n\n{inst}')
2188
+ pri.Error.red(f'It was not possible to make the directory {currpath}:\n{traceback.format_exc()}\n\n{inst}')
1714
2189
  pfPool = None if self.flagSimpleFor else self.pfPool
1715
2190
  if data.Step==StepTypes.min:
1716
- procWorker=MIN_ParFor_Worker(data,self.indWorker,self.indProc,self.numUsedThreadsPIV,pfPool,self.parForMul)
1717
- elif data.Step ==StepTypes.piv:
1718
- procWorker=PIV_ParFor_Worker(data,self.indWorker,self.indProc,self.numUsedThreadsPIV,pfPool,self.parForMul)
2191
+ self.numUsedProcs=self.numMaxProcs
2192
+ data.numPivOmpCores=1
2193
+ data.numUsedProcs=self.numMaxProcs
2194
+ procWorker=MIN_ParFor_Worker(data,self.indWorker,self.indProc,self.numMaxProcs,pfPool,self.parForMul)
2195
+ elif data.Step ==StepTypes.piv or data.Step ==StepTypes.spiv:
2196
+ data.numPivOmpCores,data.numUsedProcs=optimalPivCores(self.numMaxProcs,data.nimg,penCore=0.95)
2197
+ #data.numUsedProcs=3 # data.numUsedProcs is used for output should be the number of parfor threads used
2198
+ #data.numPivOmpCores=7#self.numMaxProcs
2199
+ self.numUsedProcs=data.numUsedProcs
2200
+ procWorker=PIV_ParFor_Worker(data,self.indWorker,self.indProc,self.numMaxProcs,pfPool,self.parForMul)
1719
2201
  elif data.Step ==StepTypes.disp:
1720
- procWorker=StereoDisparity_ParFor_Worker(data,self.indWorker,self.indProc,self.numUsedThreadsPIV,pfPool,self.parForMul)
1721
- elif data.Step ==StepTypes.spiv:
1722
- procWorker=StereoPIV_ParFor_Worker(data,self.indWorker,self.indProc,self.numUsedThreadsPIV,pfPool,self.parForMul)
1723
-
2202
+ data.numPivOmpCores=NUMTHREADS_MAX
2203
+ data.numUsedProcs=1
2204
+ procWorker=StereoDisparity_ParFor_Worker(data,self.indWorker,self.indProc,self.numMaxProcs,pfPool,self.parForMul)
2205
+
1724
2206
 
1725
2207
  procWorker.signals.progress.connect(self.progress_proc)
1726
2208
  self.signals.progress.connect(procWorker.setNumCallBackTot)
@@ -1735,14 +2217,11 @@ class gPaIRS(QMainWindow):
1735
2217
  self.procWorkers.append(procWorker)
1736
2218
  self.PaIRS_threadpool.start(procWorker)
1737
2219
 
1738
-
1739
2220
  def set_proc(self,data:dataTreePar,ind=None,FlagLog=True):
1740
2221
  if ind is None: ind=data.ind
1741
- if data.flagRun==0:
1742
- indpar=[j for j in ind]
1743
- for j in range(indpar[-2]):
1744
- indpar[-2]=j
1745
- self.inheritance(indpar)
2222
+ k=self.dataQueue.index(data)
2223
+ if self.dataFlagRuns[k]==0:
2224
+ self.getInheritance(ind)
1746
2225
  data.namesPIV=NamesPIV(Process=data.Process,Step=data.Step)
1747
2226
  INP_ind=self.w_Input.TABpar_at(ind)
1748
2227
  OUT_ind=self.w_Output.TABpar_at(ind)
@@ -1750,6 +2229,7 @@ class gPaIRS(QMainWindow):
1750
2229
  PRO_Min_ind=self.w_Process_Min.TABpar_at(ind)
1751
2230
  PRO_Disp_ind=self.w_Process_Disp.TABpar_at(ind)
1752
2231
  data.setProc(INP_ind,OUT_ind,PRO_ind,PRO_Min_ind,PRO_Disp_ind)
2232
+ data.assignDataName()
1753
2233
 
1754
2234
  if FlagLog:
1755
2235
  ITE_ind:ITEpar=self.ui.Explorer.ITEfromInd(ind)
@@ -1772,7 +2252,7 @@ class gPaIRS(QMainWindow):
1772
2252
 
1773
2253
  if i<0: return #When restarting a process return immediately if the images have been already processed
1774
2254
  #******************** Updating Log
1775
- data.Log+=stampa
2255
+ data.Log+=stampa+'\n'
1776
2256
  self.w_Log.TABpar_at(data.ind).text=data.Log
1777
2257
 
1778
2258
  data.list_print[i]=stampa
@@ -1795,6 +2275,7 @@ class gPaIRS(QMainWindow):
1795
2275
  ITE_ind.progress=data.numFinalized
1796
2276
  LOG_ind.nimg=data.nsteps
1797
2277
  self.ui.Explorer.updateItemWidget(ITE_ind)
2278
+ self.adjustDependencies(ITE_ind)
1798
2279
 
1799
2280
  flagSelected=data.hasIndexOf(self.ui.Explorer.ITEpar)
1800
2281
  if flagSelected:
@@ -1814,7 +2295,6 @@ class gPaIRS(QMainWindow):
1814
2295
  if data.flagParForCompleted: return
1815
2296
  #******************** updating log
1816
2297
  if flagSelected:
1817
- LOG_ind.text=data.Log
1818
2298
  self.w_Log.LOGpar.text=data.Log
1819
2299
  self.w_Log.setLogText(FlagMoveToBottom=True)
1820
2300
 
@@ -1822,7 +2302,7 @@ class gPaIRS(QMainWindow):
1822
2302
  # prLock ha smesso di funzionare perchè?
1823
2303
  #prLock(f'progress_proc {i} data.numProcOrErrTot={data.numProcOrErrTot} self.numCallBackTotOk={self.numCallBackTotOk}')
1824
2304
 
1825
- if self.FlagRun==0 or (procId%self.numUsedThreadsPIV and data.Step!=StepTypes.disp): return #evitare aggiornamento tempo
2305
+ if self.FlagRun==0 or (procId%self.numUsedProcs and data.Step!=StepTypes.disp): return #evitare aggiornamento tempo
1826
2306
  #if self.FlagRun==0: return #evitare aggiornamento tempo
1827
2307
  #******************** Updating time counter and stats
1828
2308
  actualTime=time()
@@ -1845,6 +2325,7 @@ class gPaIRS(QMainWindow):
1845
2325
  if data is None:
1846
2326
  data=self.procdata
1847
2327
  try:
2328
+ FlagCurrent=data.hasIndexOf(self.ui.Explorer.ITEpar)
1848
2329
  VIS_ind:VISpar=self.w_Vis.TABpar_at(data.ind)
1849
2330
  if data.Step==StepTypes.min:
1850
2331
  if i>-1:
@@ -1854,6 +2335,10 @@ class gPaIRS(QMainWindow):
1854
2335
  VIS_ind.FlagMIN = True
1855
2336
  VIS_ind.image_file_Current=''
1856
2337
  self.w_Vis.image_Current_raw=None
2338
+ #if Var: #todo GP: per i==-1 Var deve essere l'immagine giusta
2339
+ # self.w_Vis.getImageInfo(Var,data.ind)
2340
+ # self.w_Vis.resetAllLevels(data.ind)
2341
+ # self.w_Vis.resetAllXYLims(data.ind)
1857
2342
 
1858
2343
  if self.FlagResetPlot:
1859
2344
  VIS_ind.img=0
@@ -1861,7 +2346,7 @@ class gPaIRS(QMainWindow):
1861
2346
  VIS_ind.variable=self.namesPIV.combo_dict[self.namesPIV.img]
1862
2347
  VIS_ind.variableKey=self.namesPIV.combo_dict_keys[VIS_ind.variable]
1863
2348
  VIS_ind.FlagResetLevels=VIS_ind.FlagResetSizes=True
1864
- self.FlagResetPlot=False
2349
+ self.FlagResetPlot=False
1865
2350
  pass
1866
2351
  elif data.Step in (StepTypes.piv,StepTypes.disp,StepTypes.spiv):
1867
2352
  if i>-1:
@@ -1875,14 +2360,17 @@ class gPaIRS(QMainWindow):
1875
2360
  result={}
1876
2361
  for f,v in zip(fields,Var):
1877
2362
  result[f]=v
1878
- if data.Step==StepTypes.piv:
1879
- result[data.namesPIV.Mod]=np.sqrt(result[data.namesPIV.u]**2+result[data.namesPIV.v]**2)
1880
- elif data.Step==StepTypes.spiv:
1881
- result[data.namesPIV.Mod]=np.sqrt(result[data.namesPIV.u]**2+result[data.namesPIV.v]**2+result[data.namesPIV.w]**2)
2363
+ result=self.w_Vis.calcMagnitude(result)
2364
+ FlagUnit=VIS_ind.Out.xres!=1.0 or VIS_ind.Out.pixAR!=1.0
2365
+ result=self.w_Vis.calcZVorticity(result,FlagUnit)
1882
2366
  self.w_Vis.result_Current=result
1883
2367
  else:
1884
2368
  VIS_ind.result_file_Current=''
1885
2369
  self.w_Vis.result_Current=None
2370
+ #if Var: #todo GP: per i==-1 Var deve essere result
2371
+ # self.w_Vis.getResultInfo(result,data.ind)
2372
+ # self.w_Vis.resetAllLevels(data.ind)
2373
+ # self.w_Vis.resetAllXYLims(data.ind)
1886
2374
 
1887
2375
  if self.FlagResetPlot:
1888
2376
  VIS_ind.img=0
@@ -1898,7 +2386,7 @@ class gPaIRS(QMainWindow):
1898
2386
  else:
1899
2387
  pri.Info.red(f'Current process type ({data.Step}) has no plot function available!')
1900
2388
  return
1901
- if data.hasIndexOf(self.ui.Explorer.ITEpar):
2389
+ if FlagCurrent:
1902
2390
  self.w_Vis.FlagReset=i==-1
1903
2391
  self.setTABpars_at(data.ind,FlagAdjustPar=True,widget=self.w_Vis)
1904
2392
  pri.Process.yellow(f'{"*"*50} Result plotted!')
@@ -1946,8 +2434,9 @@ class gPaIRS(QMainWindow):
1946
2434
  def store_proc(self,data_worker:dataTreePar):
1947
2435
  data=self.procdata #self.w_Tree.TABpar_prev[idata.indTree][idata.indItem][-1]
1948
2436
  for f in self.procFields:
1949
- i=self.procdata.uncopied_fields.index(f)
1950
- self.procdata.uncopied_fields.pop(i)
2437
+ if f in self.procdata.uncopied_fields:
2438
+ i=self.procdata.uncopied_fields.index(f)
2439
+ self.procdata.uncopied_fields.pop(i)
1951
2440
  #Aggiusto ciò che deve essere aggiornato
1952
2441
  #if not data.numFinalized: return
1953
2442
  pri.Time.yellow(f'{"-"*100} store PROC')
@@ -1968,30 +2457,38 @@ class gPaIRS(QMainWindow):
1968
2457
  OUT_ind.res=data.res
1969
2458
  if OUT_ind.unit==0:
1970
2459
  OUT_ind.xres=data.res
2460
+ if 'zconst' in data.OUT_dict and 'xterm' in data.OUT_dict and 'yterm' in data.OUT_dict:
2461
+ OUT_ind.zconst=data.OUT_dict['zconst']
2462
+ OUT_ind.xterm=data.OUT_dict['xterm']
2463
+ OUT_ind.yterm=data.OUT_dict['yterm']
1971
2464
  indpar[-2]+=1
1972
2465
  indpar[-1]=-1
1973
2466
  OUT_ind:OUTpar=self.w_Output.TABpar_at(indpar)
1974
2467
  OUT_ind.res=data.res
1975
2468
  if OUT_ind.unit==0:
1976
2469
  OUT_ind.xres=data.res
2470
+ if 'zconst' in data.OUT_dict and 'xterm' in data.OUT_dict and 'yterm' in data.OUT_dict:
2471
+ OUT_ind.zconst=data.OUT_dict['zconst']
2472
+ OUT_ind.xterm=data.OUT_dict['xterm']
2473
+ OUT_ind.yterm=data.OUT_dict['yterm']
1977
2474
  ITE_ind:ITEpar=self.ui.Explorer.ITEfromInd(indpar)
1978
2475
  ITE_ind.procdata.res=data.res
1979
2476
  ITE_ind.procdata.laserConst=[const for const in data_worker.laserConst]
2477
+ if 'zconst' in data.OUT_dict and 'xterm' in data.OUT_dict and 'yterm' in data.OUT_dict:
2478
+ ITE_ind.procdata.OUT_dict['zconst']=data.OUT_dict['zconst']
2479
+ ITE_ind.procdata.OUT_dict['xterm']=data.OUT_dict['xterm']
2480
+ ITE_ind.procdata.OUT_dict['yterm']=data.OUT_dict['yterm']
1980
2481
 
1981
2482
  #Aggiusto ciò che deve essere aggiornato
1982
- data.warnings[1]=''
1983
- data.setCompleteLog()
1984
2483
  if data.nsteps==data.numCallBackTotOk: #data.FlagFinished: #todo TA da GP: secondo te è corretto?
1985
2484
  flagRun=int(data.numFinalized==data.nsteps)+1
1986
2485
  else:
1987
2486
  flagRun=-1
1988
2487
  self.setFlagRun(data,flagRun)
2488
+ data.warnings[1]=''
2489
+ data.setCompleteLog()
2490
+ self.adjustSwitches()
1989
2491
 
1990
- with open(data.outPathRoot+'.log', 'a') as file:
1991
- file.write(data.Log)
1992
- if data.Step in (StepTypes.piv,StepTypes.spiv):
1993
- data.writeCfgProcPiv()
1994
-
1995
2492
  Process=[]
1996
2493
  for l in self.projectTree.itemList[1:]:
1997
2494
  Process.append([ l[data.ind[0]][data.ind[1]][data.ind[2]] ])
@@ -1999,10 +2496,22 @@ class gPaIRS(QMainWindow):
1999
2496
  try:
2000
2497
  saveList(Process,filename)
2001
2498
  except Exception as inst:
2002
- warningDialog(self,f'Error while saving the configuration file {filename}!\nPlease, retry.')
2499
+ #warningDialog(self,f'Error while saving the configuration file {filename}!')
2003
2500
  pri.Error.red(f'Error while saving the configuration file {filename}!\n{inst}')
2004
2501
 
2005
-
2502
+ try:
2503
+ with open(data.outPathRoot+'.log', 'a') as file:
2504
+ file.write(data.Log)
2505
+ except:
2506
+ pri.Error.red(f'Error while trying to save the process log file: {data.outPathRoot}.log.\n{traceback.format_exc()}\n')
2507
+ try:
2508
+ with open(data.stepOutName()+'.log', 'w') as file:
2509
+ file.write(data.Log)
2510
+ except:
2511
+ pri.Error.red(f'Error while trying to save the process log file: {data.stepOutName()}.log.\n{traceback.format_exc()}\n')
2512
+ if data.Step in (StepTypes.piv,StepTypes.spiv):
2513
+ data.writeCfgProcPiv()
2514
+
2006
2515
  LOG_ind:LOGpar=self.w_Log.TABpar_at(data.ind)
2007
2516
  LOG_ind.text=data.Log
2008
2517
  self.w_Log.setLogText(FlagMoveToBottom=True)
@@ -2011,7 +2520,11 @@ class gPaIRS(QMainWindow):
2011
2520
  #if not data.hasIndexOf(self.ui.Explorer.ITEpar):
2012
2521
  ITE:ITEpar=self.ui.Explorer.ITEfromInd(data.ind)
2013
2522
  self.ui.Explorer.setITElayout(ITE)
2523
+ self.inheritance(data.ind)
2524
+ self.adjustDependencies(ITE)
2014
2525
  self.ui.time_stamp.setText('')
2526
+
2527
+ self.adjustSwitches()
2015
2528
 
2016
2529
  pri.Time.yellow(f'{"-"*100} store PROC END')
2017
2530
 
@@ -2026,7 +2539,8 @@ class gPaIRS(QMainWindow):
2026
2539
  if self.procdata:
2027
2540
  pri.Time.red(f'stopProcs self.contProc={self.contProc}/{self.nProc} self.numCallBackTotOk={self.numCallBackTotOk} numFinalized={self.procdata.numFinalized} {self.FlagRun}')
2028
2541
 
2029
- if self.contProc==self.nProc:
2542
+ FlagEnd = self.contProc==self.indProc+1 if self.FlagRun==2 else self.contProc==self.nProc
2543
+ if FlagEnd:
2030
2544
  self.ui.Explorer.updateSwitchMovies(self.currind,FlagStart=False)
2031
2545
  self.setSwitchEnabled(True)
2032
2546
  self.disableDropping(False)
@@ -2036,21 +2550,41 @@ class gPaIRS(QMainWindow):
2036
2550
  self.setEnabled(True)
2037
2551
  self.procWorkers=[]
2038
2552
  self.FlagRun=0
2553
+ self.putStepsInQueue()
2039
2554
  self.ui.button_pause.setEnabled(True)
2040
2555
  self.ui.button_Run.setEnabled(True)
2041
2556
  self.setButtonPause(True)
2042
2557
 
2043
- self.ui.label_updating_pairs.setVisible(False)
2044
- if self.waitingDialog:
2045
- self.waitingDialog.done(0)
2046
- self.waitingDialog=None
2047
- if self.completingTask:
2048
- self.completingTask()
2049
- self.completingTask=None
2050
-
2051
- if self.FlagClosing[0]:
2052
- self.correctClose()
2053
-
2558
+ self.closeIfRequested()
2559
+
2560
+ def putStepsInQueue(self):
2561
+ if self.FlagRun:
2562
+ self.dataFlagRuns=[]
2563
+ for k,data in enumerate(self.dataQueue):
2564
+ if self.FlagRun:
2565
+ self.dataFlagRuns.append(data.flagRun)
2566
+ self.setFlagRun(data,-10)
2567
+ elif data.flagRun==-10:
2568
+ self.setFlagRun(data,self.dataFlagRuns[k])
2569
+ else:
2570
+ continue
2571
+ ITE_ind:ITEpar=self.ui.Explorer.ITEfromInd(data.ind)
2572
+ self.ui.Explorer.setITElayout(ITE_ind)
2573
+ self.ui.Explorer.arrangeCurrentProcess(self.processTree)
2574
+
2575
+ def closeIfRequested(self):
2576
+ self.ui.label_updating_pairs.setVisible(False)
2577
+ if self.waitingDialog:
2578
+ self.waitingDialog.done(0)
2579
+ self.waitingDialog=None
2580
+ if self.completingTask:
2581
+ self.completingTask()
2582
+ self.completingTask=None
2583
+ """
2584
+ if self.FlagClosing[0]:
2585
+ self.correctClose()
2586
+ """
2587
+
2054
2588
  #********************************************* CalVi
2055
2589
  def runCalVi(self):
2056
2590
  self.w_Vis_CalVi.VISpar.FlagRunning=not self.w_Vis_CalVi.VISpar.FlagRunning
@@ -2078,7 +2612,7 @@ class gPaIRS(QMainWindow):
2078
2612
  else:
2079
2613
  cams=[-1]
2080
2614
  data=self.w_Vis_CalVi.calibView.calib.cal.data
2081
- varName=f'{data.percorsoOut}{data.NomeFileOut}{camString}{outExt.cal}'
2615
+ varName=f'{data.percorsoOut}{data.NomeFileOut}{camString}{outExt.calvi}'
2082
2616
  questionMessage=f'The calibration result file:\n{varName}\nalready exists in the current output path. The above error could arise from the attempt of loading such a file.\n\nDo you want to remove the file from the disk?\n\n(Please, consider to choose a different output name root for your process)'
2083
2617
  if questionDialog(self,questionMessage):
2084
2618
  os.remove(varName)
@@ -2118,7 +2652,7 @@ class gPaIRS(QMainWindow):
2118
2652
 
2119
2653
  if self.w_Vis_CalVi.FlagResume>-1:
2120
2654
  self.saveCal()
2121
- if (self.w_Process_CalVi.PROpar.FlagPlane or self.w_Process_CalVi.PROpar.CamMod==4) and self.w_Vis_CalVi.calibView.calib.FlagCalibration:
2655
+ if self.w_Vis_CalVi.calibView.calib.FlagCalibration and ( (self.w_Process_CalVi.PROpar.FlagPlane and not self.w_Process_CalVi.PROpar.CalibProcType==0) or self.w_Process_CalVi.PROpar.CamMod==4 ):
2122
2656
  if self.w_Input_CalVi.INPpar.FlagOptPlane: self.savePlanePar()
2123
2657
  self.updateINPpar()
2124
2658
  self.saveCal('_Mod')
@@ -2128,6 +2662,8 @@ class gPaIRS(QMainWindow):
2128
2662
  #self.actualBridge('Import',indTree,indItem,ind)
2129
2663
  self.initDataAndSetImgFromGui(self.w_Input_CalVi.INPpar,self.w_Process_CalVi.PROpar)
2130
2664
  self.w_Vis_CalVi.stopCalVi()
2665
+
2666
+ self.closeIfRequested()
2131
2667
 
2132
2668
  def abortCalVi(self):
2133
2669
  self.w_Vis_CalVi.FlagResume=-1
@@ -2152,11 +2688,13 @@ class gPaIRS(QMainWindow):
2152
2688
  outFiles=[f'{data.percorsoOut}{data.NomeFileOut}{c}.cal' for c in INP.cams]
2153
2689
  else:
2154
2690
  outFiles=[f'{data.percorsoOut}{data.NomeFileOut}{1}.cal']
2691
+ appendedFiles=[f for f in outFiles if f not in self.w_Calibration.CALpar.calList]
2155
2692
  self.w_Calibration.buttonAction()
2693
+ if len(appendedFiles)==0: return
2156
2694
  if self.w_Calibration.CALpar.ncam==len(self.w_Calibration.CALpar.calList):
2157
2695
  warningDialog(self,f'The calibration file list already contains a number of files equal to the number of cameras specified ({self.w_Calibration.CALpar.ncam}). The results of the current CalVi process will not be appended to the list.')
2158
2696
  else:
2159
- self.w_Calibration.ui.calTree.importLists(outFiles)
2697
+ self.w_Calibration.ui.calTree.importLists(appendedFiles)
2160
2698
  self.w_Calibration.copyListsFromTree()
2161
2699
  #self.w_Calibration.nullCallback()
2162
2700
  self.w_Calibration.adjustTABparInd()
@@ -2175,32 +2713,48 @@ class gPaIRS(QMainWindow):
2175
2713
  VIS.angAndMask.append([])
2176
2714
  VIS.spotDistAndRemoval.append([])
2177
2715
 
2178
- VIS.orPosAndShift[p].append(calVect.XOr[p] - data.ColPart)
2179
- VIS.orPosAndShift[p].append(calVect.YOr[p] - data.RigaPart)
2180
- VIS.orPosAndShift[p].append(calVect.xOrShift[p])
2181
- VIS.orPosAndShift[p].append(calVect.yOrShift[p])
2716
+ VIS.orPosAndShift[p].append(float(calVect.XOr[p] - data.ColPart))
2717
+ VIS.orPosAndShift[p].append(float(calVect.YOr[p] - data.RigaPart))
2718
+ VIS.orPosAndShift[p].append(float(calVect.xOrShift[p]))
2719
+ VIS.orPosAndShift[p].append(float(calVect.yOrShift[p]))
2182
2720
 
2183
- VIS.angAndMask[p].append(calVect.angCol[p])
2184
- VIS.angAndMask[p].append(calVect.angRow[p])
2721
+ VIS.angAndMask[p].append(float(calVect.angCol[p]))
2722
+ VIS.angAndMask[p].append(float(calVect.angRow[p]))
2185
2723
  for i in self.w_Vis_CalVi.calibView.calib.cal.getPuTrovaCC(p):
2186
- VIS.angAndMask[p].append(i)
2187
-
2188
- VIS.spotDistAndRemoval[p].append(calVect.dColPix[p])
2189
- VIS.spotDistAndRemoval[p].append(calVect.dRigPix[p])
2190
- VIS.spotDistAndRemoval[p].append(calVect.remPointsUp[p])
2191
- VIS.spotDistAndRemoval[p].append(calVect.remPointsDo[p])
2192
- VIS.spotDistAndRemoval[p].append(calVect.remPointsLe[p])
2193
- VIS.spotDistAndRemoval[p].append(calVect.remPointsRi[p])
2724
+ VIS.angAndMask[p].append(float(i))
2725
+
2726
+ VIS.spotDistAndRemoval[p].append(float(calVect.dColPix[p]))
2727
+ VIS.spotDistAndRemoval[p].append(float(calVect.dRigPix[p]))
2728
+ VIS.spotDistAndRemoval[p].append(float(calVect.remPointsUp[p]))
2729
+ VIS.spotDistAndRemoval[p].append(float(calVect.remPointsDo[p]))
2730
+ VIS.spotDistAndRemoval[p].append(float(calVect.remPointsLe[p]))
2731
+ VIS.spotDistAndRemoval[p].append(float(calVect.remPointsRi[p]))
2194
2732
 
2195
2733
  INP=self.w_Input_CalVi.INPpar
2196
2734
  camString=''
2197
2735
  if INP.FlagCam:
2198
2736
  if len(INP.cams)==1: camString=f'_cam{INP.cams[0]}'
2199
- varName=f'{data.percorsoOut}{data.NomeFileOut}{camString}{add_str}{outExt.cal}'
2737
+ varName=f'{data.percorsoOut}{data.NomeFileOut}{camString}{add_str}{outExt.calvi}'
2200
2738
  var=[INP,self.w_Process_CalVi.PROpar,VIS,myStandardPath(os.path.dirname(varName))]
2201
- with open(varName,'wb') as file:
2202
- pickle.dump(var,file)
2203
- pri.Info.blue(f'>>> Saving calibration process file {varName}')
2739
+ try:
2740
+ with open(varName,'wb') as file:
2741
+ pickle.dump(var,file)
2742
+ pri.Info.blue(f'>>> Saving calibration process file {varName}')
2743
+ except:
2744
+ pri.Error.red(f'Error while trying to save the calibration process file: {varName}.\n{traceback.format_exc()}\n')
2745
+
2746
+ self.w_Input_CalVi.adjustTABparInd()
2747
+ self.w_Process_CalVi.adjustTABparInd()
2748
+ self.w_Vis_CalVi.adjustTABparInd()
2749
+ Process=[]
2750
+ for l in self.projectTree.itemList[1:]:
2751
+ Process.append([ l[INP.ind[0]][INP.ind[1]][INP.ind[2]] ])
2752
+ filename=f'{data.percorsoOut}{data.NomeFileOut}{camString}{add_str}{outExt.cal}'
2753
+ try:
2754
+ saveList(Process,filename)
2755
+ except Exception as inst:
2756
+ #warningDialog(self,f'Error while saving the configuration file {filename}!')
2757
+ pri.Error.red(f'Error while saving the configuration file {filename}!\n{inst}')
2204
2758
  return
2205
2759
 
2206
2760
  def savePlanePar(self):
@@ -2216,8 +2770,11 @@ class gPaIRS(QMainWindow):
2216
2770
  for p,v in zip(plapar_names,c):
2217
2771
  dp[p]=v
2218
2772
  plaparName=plaparRad+f"{i+1:d}_z{dp['z (mm)']:.2f}{outExt.pla}"
2219
- with open(plaparName,'w') as file:
2220
- file.write(str(dp).replace('{','{\n ').replace(',',',\n').replace('}','\n}'))
2773
+ try:
2774
+ with open(plaparName,'w') as file:
2775
+ file.write(str(dp).replace('{','{\n ').replace(',',',\n').replace('}','\n}'))
2776
+ except:
2777
+ pri.Error.red(f'Error while trying to save the plane parameter file: {plaparName}.\n{traceback.format_exc()}\n')
2221
2778
  pri.Info.blue(f' Saving plane data file {plaparName}')
2222
2779
 
2223
2780
  def setRunCalViButtonText(self,FlagRunning=True):
@@ -2231,11 +2788,16 @@ class gPaIRS(QMainWindow):
2231
2788
  s=''
2232
2789
  text='Run'
2233
2790
  button.setIcon(self.icon_play)
2791
+ tooltip=f'Run CalVi{" (some issues detected!)" if flag else ""}'
2234
2792
  else:
2235
2793
  s=''
2236
- text='Stop'
2237
- button.setIcon(self.icon_pause)
2794
+ text='Save'
2795
+ button.setIcon(self.icon_save_and_stop)
2796
+ tooltip='Quit CalVi and save results'
2238
2797
  button.setText(text+s)
2798
+ tooltip+=' ('+button.shortcut().toString(QKeySequence.NativeText)+')'
2799
+ button.setToolTip(tooltip)
2800
+ button.setStatusTip(tooltip)
2239
2801
 
2240
2802
  def disableTab_Vis(self,Flag=True):
2241
2803
  self.ui.w_Managing_Tabs.setEnabled(not Flag)
@@ -2245,10 +2807,12 @@ class gPaIRS(QMainWindow):
2245
2807
  w.setEnabled(not Flag)
2246
2808
  self.w_Input.ui.button_back.setEnabled(not Flag)
2247
2809
  self.w_Input.ui.button_forward.setEnabled(not Flag)
2810
+ self.ui.button_Run_CalVi.setVisible(not Flag)
2248
2811
  self.ui.button_Abort_CalVi.setVisible(Flag)
2249
2812
  self.setRunCalViButtonText(FlagRunning=Flag)
2250
2813
 
2251
2814
  self.ui.tabAreaWidget.FlagDisplayControls=not Flag
2815
+ self.ui.tabAreaWidget.ui.button_restore_undo.setVisible(not Flag)
2252
2816
  self.ui.tabAreaWidget.ui.button_back.setVisible(not Flag)
2253
2817
  self.ui.tabAreaWidget.ui.button_forward.setVisible(not Flag)
2254
2818
  self.ui.tabAreaWidget.display_controls()
@@ -2259,7 +2823,7 @@ class gPaIRS(QMainWindow):
2259
2823
  self.w_Vis_CalVi.initDataFromGui(INP,PRO)
2260
2824
  inddel=self.w_Vis_CalVi.setImgFromGui()
2261
2825
  if len(inddel): #todo GP: migliorare? (setto due volte le immagini e faccio in calib il check)
2262
- Message=f'The following image files have sizes not compatible with the first image file of the list ({self.w_Input_CalVi.INPpar.filenames[0]}):\n'
2826
+ Message=f'The following image files encountered issues while importing (they may have incompatible sizes with the first image file of the list "{self.w_Input_CalVi.INPpar.filenames[0]}" or be not in grayscale format):\n'
2263
2827
  for k in inddel:
2264
2828
  if k==inddel[-1]: colon='.'
2265
2829
  else: colon=';'
@@ -2276,7 +2840,6 @@ class gPaIRS(QMainWindow):
2276
2840
  self.w_Vis_CalVi.initDataFromGui(INP,PRO)
2277
2841
  self.w_Vis_CalVi.setImgFromGui()
2278
2842
 
2279
-
2280
2843
  #********************************************* LEGACY
2281
2844
  def setUpdatingState(self,flagUpdating):
2282
2845
  if Flag_DISABLE_onUpdate:
@@ -2318,7 +2881,7 @@ class gPaIRS(QMainWindow):
2318
2881
  parForMul.sleepTime=ParFor_sleepTime #time between calls of callBack
2319
2882
  self.pfPool=pfPool
2320
2883
  self.parForMul=parForMul
2321
- self.parForMul.numUsedCores=self.numUsedThreadsPIV # =NUMTHREADS_PIV#potrebbe essere minore di NUMTHREADS_PIV_MAX con cui è stato impostato
2884
+ self.parForMul.numUsedCores=self.numMaxProcs # =NUMTHREADS_MAX#potrebbe essere minore di NUMTHREADS_PIV_MAX con cui è stato impostato
2322
2885
  self.FlagParPoolInit=True
2323
2886
  self.signals.parPoolInit.emit()
2324
2887
  f3.add_done_callback(initParForComplete)
@@ -2349,28 +2912,62 @@ class gPaIRS(QMainWindow):
2349
2912
  def spin_nworkers_action(self):
2350
2913
  val=self.ui.spin_nworkers.value()
2351
2914
  self.GPApar.NumCores=val
2352
- if val <=NUMTHREADS_PIV_MAX:
2353
- self.numUsedThreadsPIV=val
2915
+ if val <=NUMTHREADS_MAX:
2916
+ self.numMaxProcs=val
2354
2917
 
2355
2918
  #*************************************************** Warnings
2356
- def warningDialog(self,Message,time_milliseconds=0,flagScreenCenter=False,icon=QIcon(),palette=None,pixmap=None,title='Warning!',flagRichText=False,flagNoButtons=False):
2357
- return warningDialog(self,Message,time_milliseconds,flagScreenCenter,icon,palette,pixmap,title,flagRichText,flagNoButtons)
2919
+ def warningDialog(self,Message,time_milliseconds=0,flagScreenCenter=False,icon=QIcon(),palette=None,pixmap=None,title='Warning!',flagRichText=False,flagNoButtons=False,addButton:dict=None):
2920
+ return warningDialog(self,Message,time_milliseconds,flagScreenCenter,icon,palette,pixmap,title,flagRichText,flagNoButtons,addButton)
2358
2921
 
2359
2922
  def questionDialog(self,Message):
2360
2923
  flagYes=questionDialog(self,Message)
2361
2924
  return flagYes
2362
2925
 
2926
+ #*************************************************** Checking
2927
+ def checkProcesses(self,FlagInit=False,ind=None):
2928
+ FlagCheck=ind is None
2929
+ if ind is not None: projects=self.projectTree.itemList[1][ind[0]:ind[0]+1]
2930
+ else: projects=self.projectTree.itemList[1]
2931
+ for ITEs_project in projects:
2932
+ if ind is not None: ITEs_project_ind=ITEs_project[ind[1]:ind[1]+1]
2933
+ else: ITEs_project_ind=ITEs_project
2934
+ for ITEs_tree in ITEs_project_ind:
2935
+ if ind is not None: ITEs_tree_ind=ITEs_tree[ind[2]:ind[2]+1]
2936
+ else: ITEs_tree_ind=ITEs_tree
2937
+ for ITEs in ITEs_tree_ind:
2938
+ if ind is not None: ITEs_ind=ITEs[ind[3]+1:ind[3]+2]
2939
+ else: ITEs_ind=ITEs
2940
+ for ITE in ITEs_ind:
2941
+ ITE:ITEpar
2942
+ ITE.FlagInit=FlagInit
2943
+ indITE=ITE.ind
2944
+ if ind is not None: FlagCheck=True
2945
+ for w in self.tabWidgets:
2946
+ w:gPaIRS_Tab
2947
+ TABpar_ind:TABpar=w.TABpar_at(indITE)
2948
+ if TABpar_ind:
2949
+ if FlagInit:
2950
+ w.checkTABpar(indITE)
2951
+ w.setTABwarn(indITE)
2952
+ TABpar_ind.FlagInit=True
2953
+ else:
2954
+ TABpar_ind.FlagInit=False
2955
+ return FlagCheck
2956
+
2363
2957
  #*************************************************** Projects
2364
2958
  def pauseQuestion(self,taskDescription='continuing',task=lambda:None,FlagFirstQuestion=False):
2365
2959
  if FlagFirstQuestion:
2366
2960
  if not self.questionDialog(f'Are you sure you want to proceed with {taskDescription}?'):
2367
2961
  return
2368
- if self.FlagRun:
2369
- if self.questionDialog(f'PaIRS is currently executing the processes in the current workspace. Do you want to pause them before {taskDescription}?'):
2962
+ if self.FlagRun or self.w_Vis_CalVi.VISpar.FlagRunning:
2963
+ if self.FlagRun: currentTaskDescription='PaIRS is currently executing the processes in the current workspace. '
2964
+ elif self.w_Vis_CalVi.VISpar.FlagRunning: currentTaskDescription='CalVi is currently running. '
2965
+ if self.questionDialog(f'{currentTaskDescription}Do you want to pause them before {taskDescription}?'):
2370
2966
  if self.FlagRun: self.button_run_pause_action()
2371
2967
  self.setEnabled(False)
2372
2968
  self.completingTask=task
2373
2969
  self.waitingDialog=self.warningDialog('Please, wait while stopping the running processes!',pixmap=''+ icons_path +'sandglass.png',flagNoButtons=True)
2970
+ if self.w_Vis_CalVi.VISpar.FlagRunning: self.abortCalVi()
2374
2971
  else:
2375
2972
  task()
2376
2973
  return
@@ -2381,15 +2978,19 @@ class gPaIRS(QMainWindow):
2381
2978
  #dir=self.w_Input.INPpar.path,\
2382
2979
  options=optionNativeDialog)
2383
2980
  if not filename: return
2981
+ errorString=''
2384
2982
  try:
2385
- data=loadList(filename)
2386
- except Exception as inst:
2983
+ data, errorMessage=loadList(filename)
2984
+ errorString+=errorMessage
2985
+ except:
2986
+ errorString+=traceback.format_exc()
2987
+ if errorString:
2387
2988
  WarningMessage=f'Error with loading the file: {filename}\n'
2388
2989
  warningDialog(self,WarningMessage)
2389
- pri.Error.red(f'{WarningMessage}\n{traceback.format_exc()}\n')
2990
+ pri.Error.red(f'{WarningMessage}\n{errorString}\n')
2390
2991
  try:
2391
2992
  ind=self.projectTree.topLevelItemCount()
2392
- insert_at_depth(self.projectTree.itemList,self.projectTree.listDepth,[ind],data)
2993
+ insert_at_depth(self.projectTree.itemList,self.projectTree.listDepth,ind,data)
2393
2994
  self.modifyWorkspace()
2394
2995
  TRE:TREpar=self.projectTree.itemList[0][ind]
2395
2996
  TRE.project=ind
@@ -2418,6 +3019,11 @@ class gPaIRS(QMainWindow):
2418
3019
  filename=filename+ext
2419
3020
  if FlagSave:saveList(filename)
2420
3021
  return filename
3022
+
3023
+ def updateWorkspaceTitle(self):
3024
+ self.GPApar.name=self.ui.title_workspace.label.text().replace(self.GPApar.saveBullet(),'')
3025
+ self.GPApar.FlagSaved=False
3026
+ self.adjustWorkspaceHeader()
2421
3027
 
2422
3028
  def save_current_project(self,filename):
2423
3029
  Project=[]
@@ -2473,18 +3079,21 @@ class gPaIRS(QMainWindow):
2473
3079
  self.pauseQuestion('copying the selected process',lambda: ProcessTree.button_copy_action(self.processTree))
2474
3080
 
2475
3081
  def delete_process(self):
2476
- if self.ui.Explorer.ITEpar.FlagQueue and self.ui.Explorer.currentTree==self.processTree:
3082
+ if self.ui.Explorer.currentTree==self.processTree:
3083
+ #if self.ui.Explorer.ITEpar.FlagQueue: self.ui.Explorer.ITEpar.FlagQueue=False
2477
3084
  self.pauseQuestion('deleting the selected process',lambda: ProcessTree.button_delete_action(self.processTree))
2478
3085
 
2479
3086
  def clean_processes(self):
2480
3087
  if self.ui.Explorer.currentTree==self.processTree:
2481
3088
  self.pauseQuestion('cleaning the whole process list',lambda: ProcessTree.button_clean_action(self.processTree))
2482
3089
 
2483
- #*************************************************** Menus
2484
- #********************* File
3090
+ #*************************************************** Sizes, font & layout
2485
3091
  def updateGPAparGeometry(self):
2486
3092
  self.GPApar.Geometry=self.saveGeometry().toBase64().data().decode()
2487
3093
  self.GPApar.WindowState=self.saveState().toBase64().data().decode()
3094
+ #g=self.geometry()
3095
+ #self.GPApar.Geometry=[g.x(), g.y(), g.width(), g.height()]
3096
+ #self.GPApar.WindowState=[self.windowState().value,self.windowState().name]
2488
3097
  splitterSizes={}
2489
3098
  for s in self.ui.Explorer.findChildren(QSplitter)+[self.ui.main_splitter,self.ui.Operating_Tabs_splitter]:
2490
3099
  s:QSplitter
@@ -2498,13 +3107,129 @@ class gPaIRS(QMainWindow):
2498
3107
  scrollAreaValues[a.objectName()]=[a.horizontalScrollBar().value(),a.verticalScrollBar().value()]
2499
3108
  self.GPApar.ScrollAreaValues=scrollAreaValues
2500
3109
  return
3110
+
3111
+ def setFontPixelSize(self):
3112
+ if self.fontPixelSize==self.GPApar.fontPixelSize: return
3113
+ fPixSize=self.GPApar.fontPixelSize
3114
+ font=QFont()
3115
+ font.setFamily(fontName)
3116
+ font.setPixelSize(fPixSize)
3117
+ if self.app: self.app.setFont(font)
3118
+ setFontPixelSize(self,fPixSize)
3119
+ self.setFurtherFontPixelSizes(fPixSize)
3120
+ if self.aboutDialog:
3121
+ self.aboutDialog.fontPixelSize=self.GPApar.fontPixelSize
3122
+ self.aboutDialog.setFontSizeText()
3123
+ if self.logChanges: self.logChanges.setFontPixelSize(fPixSize)
3124
+ if self.menuDebug: self.menuDebug.setFont(self.ui.menuFile.font())
3125
+ self.fontPixelSize=fPixSize
3126
+
3127
+ def setFurtherFontPixelSizes(self,fPixSize):
3128
+ self.setTabFontPixelSize(fPixSize)
3129
+
3130
+ lab:QLabel=self.ui.title
3131
+ fPixSize_TabNames=min([fPixSize*2,30])
3132
+ font=lab.font()
3133
+ font.setFamily(fontName)
3134
+ font.setPixelSize(fPixSize_TabNames)
3135
+ lab.setFont(font)
3136
+ self.ui.title_workspace.setFont(font)
3137
+
3138
+ lab:QLabel=self.ui.subtitle
3139
+ font=lab.font()
3140
+ font.setFamily(fontName)
3141
+ font.setPixelSize(fPixSize+4)
3142
+ lab.setFont(font)
3143
+ self.ui.subtitle_workspace.setFont(font)
3144
+
3145
+ lab:QLabel=self.onlyReadLabel
3146
+ font=lab.font()
3147
+ font.setFamily(fontName)
3148
+ font.setPixelSize(fPixSize+1)
3149
+ lab.setFont(font)
3150
+
3151
+ self.ui.projectPage.setFontPixelSize(fPixSize)
3152
+ self.ui.processPage.setFontPixelSize(fPixSize)
3153
+ self.ui.stepPage.setFontPixelSize(fPixSize)
3154
+
3155
+ self.w_Log.setLogFont(fontPixelSize-dfontLog)
3156
+ self.w_Vis_CalVi.setLogFont(fontPixelSize-dfontLog)
3157
+
3158
+ def setTabFontPixelSize(self,fPixSize):
3159
+ fPixSize_TabNames=min([fPixSize*2,30])
3160
+ for w in self.ui.tabAreaWidget.widgets:
3161
+ setFontPixelSize(w,fPixSize)
3162
+ w:gPaIRS_Tab
3163
+ for lab in w.findChildren(QLabel):
3164
+ lab:QLabel
3165
+ if 'name_tab' in lab.objectName():
3166
+ #lab:QLabel=w.ui.name_tab
3167
+ font=lab.font()
3168
+ font.setPixelSize(fPixSize_TabNames)
3169
+ lab.setFont(font)
3170
+
3171
+ def falseShow(self):
3172
+ FlagHidden=not self.isVisible()
3173
+ total_rect = QGuiApplication.primaryScreen().geometry()
3174
+ for screen in QGuiApplication.screens():
3175
+ total_rect = total_rect.united(screen.geometry())
3176
+ self.move(total_rect.right() + 100, total_rect.bottom() + 100)
3177
+ self.updateGeometry()
3178
+ self.show()
3179
+ self.repaint()
3180
+ return FlagHidden
3181
+
3182
+ def setDefaultSizes(self):
3183
+ margins=self.ui.centralLayout.contentsMargins()
3184
+ main_splitter_sizes=[self.ui.w_Managing_Tabs.baseSize().width(),self.ui.tabAreaWidget.widgetMinimumWidth*2+self.ui.tabAreaWidget.margin*2+self.ui.tabAreaWidget.handleWidth*2] #processTree, main_sep, tabAreaWidget
3185
+ w=margins.left()+self.ui.main_splitter.handleWidth()*2+sum(main_splitter_sizes)+margins.right()
3186
+ h=margins.top()+self.ui.w_header.minimumHeight()+self.ui.tabAreaWidget.tabAreaHeight+self.ui.tabAreaWidget.buttonSize[1]+self.ui.tabAreaWidget.buttonSpacing+self.ui.tabAreaWidget.margin*2+self.ui.w_Operating_Tabs.layout().spacing()+self.ui.statusbar.minimumHeight()+margins.bottom()
3187
+ self.resize(w,h)
3188
+ self.ui.main_splitter.setSizes(main_splitter_sizes)
3189
+ self.updateGeometry()
3190
+ x=(self.maximumGeometry.width()-w)*0.5
3191
+ y=(self.maximumGeometry.height()-h)*0.5
3192
+ if self.falseShow(): self.hide()
3193
+ self.move(x,y)
3194
+ self.app.processEvents()
3195
+ self.updateGPAparGeometry()
3196
+
3197
+ def setGPaIRSTitle(self):
3198
+ cfgString=f': {self.GPApar.outName}' if self.GPApar.outName and self.GPApar.outName!=lastcfgname else ''
3199
+ if not self.GPApar.FlagSaved: cfgString+='*'
3200
+ if Flag_DEBUG:#TA per non incasinarmi
3201
+ windowTitle=f'PaIRS (v{version}.{__subversion__} - {__date__}) -- cfg v{uicfg_version} -- PIV {self.PIVvers} -- {platform.system()} -- Python {platform.python_version()}'
3202
+ else:
3203
+ windowTitle=f'PaIRS (v{version})'
3204
+ windowTitle+=cfgString
3205
+ self.setWindowTitle(windowTitle)
2501
3206
 
3207
+ #*************************************************** Menus
3208
+ #********************* File
2502
3209
  def setGPAlayout(self):
3210
+ self.setFontPixelSize()
3211
+ self.setGPaIRSPalette()
3212
+
2503
3213
  geometry=QByteArray.fromBase64(self.GPApar.Geometry.encode())
2504
3214
  self.restoreGeometry(geometry)
3215
+ #if isinstance(self.GPApar.Geometry,list) and len(self.GPApar.Geometry)==4:
3216
+ # g=self.GPApar.Geometry
3217
+ # try:
3218
+ # self.setGeometry(g[0],g[1],g[2],g[3])
3219
+ # except:
3220
+ # pri.Info.yellow(f'Error while restoring geometry:\n{traceback.format_exc()}\n\nDefault sizes will be set!\n\n')
3221
+ # self.setDefaultSizes()
3222
+ #else:
3223
+ # self.setDefaultSizes()
3224
+
2505
3225
  windowState = QByteArray.fromBase64(self.GPApar.WindowState.encode())
2506
3226
  self.restoreState(windowState)
2507
-
3227
+ #try:
3228
+ # s=self.GPApar.WindowState
3229
+ # self.setWindowState(Qt.WindowState(s[0]))
3230
+ #except:
3231
+ # pri.Info.yellow(f'Error while restoring window state:\n{traceback.format_exc()}\n\nDefault window state will be set!\n\n')
3232
+
2508
3233
  for s in self.ui.Explorer.findChildren(QSplitter)+[self.ui.main_splitter,self.ui.Operating_Tabs_splitter]:
2509
3234
  s:QSplitter
2510
3235
  if s.objectName() in self.GPApar.SplitterSizes:
@@ -2515,13 +3240,11 @@ class gPaIRS(QMainWindow):
2515
3240
  scrollAreaValues=self.GPApar.ScrollAreaValues[a.objectName()]
2516
3241
  a.horizontalScrollBar().setValue(scrollAreaValues[0])
2517
3242
  a.verticalScrollBar().setValue(scrollAreaValues[1])
2518
- self.setFontPixelSize()
2519
- self.setGPaIRSPalette()
2520
3243
  self.setNumCores()
2521
3244
 
2522
3245
  def setNumCores(self):
2523
- if self.GPApar.NumCores >NUMTHREADS_PIV_MAX:
2524
- self.GPApar.NumCores=NUMTHREADS_PIV_MAX
3246
+ if self.GPApar.NumCores >NUMTHREADS_MAX:
3247
+ self.GPApar.NumCores=NUMTHREADS_MAX
2525
3248
  self.numTotUsedThreads=self.GPApar.NumCores
2526
3249
  self.ui.spin_nworkers.setValue(self.GPApar.NumCores)
2527
3250
 
@@ -2560,32 +3283,27 @@ class gPaIRS(QMainWindow):
2560
3283
  #dir=self.w_Input.INPpar.path,\
2561
3284
  options=optionNativeDialog)
2562
3285
  if not filename: return
2563
- waitingWindow=warningDialog(self,'Please, wait while retrieving previous workspace!\nIf this action takes too much time, please consider to close the workspace before quitting PaIRS next time)',pixmap=''+ icons_path +'sandglass.png',flagNoButtons=True,flagScreenCenter=True)
3286
+ waitingWindow=warningDialog(self,'Please, wait while retrieving previous workspace!\n(If this action takes too much time, please consider to close the workspace before quitting PaIRS next time.)',pixmap=''+ icons_path +'sandglass.png',flagNoButtons=True,flagScreenCenter=True)
2564
3287
  self.app.processEvents()
3288
+ errorString=''
2565
3289
  try:
2566
- data=loadList(filename)
3290
+ data, errorMessage=loadList(filename)
3291
+ errorString+=errorMessage
2567
3292
  pri.Time.cyan('Open workspace: load')
2568
- except Exception as inst:
3293
+ except:
3294
+ errorString+=traceback.format_exc()
3295
+ if errorString:
2569
3296
  WarningMessage=f'Error with loading the file: {filename}\n'
2570
3297
  warningDialog(self,WarningMessage)
2571
- pri.Error.red(f'{WarningMessage}\n{traceback.format_exc()}\n')
3298
+ pri.Error.red(f'{WarningMessage}\n{errorString}\n')
2572
3299
  try:
2573
3300
  self.projectTree.clean_action()
2574
- all_indexes=[i for i in range(len(data[2]))]
2575
- insert_at_depth(self.projectTree.itemList,self.projectTree.listDepth,all_indexes,data[2])
2576
- for ITEs_project in self.projectTree.itemList[1]:
2577
- for ITEs_tree in ITEs_project:
2578
- for ITEs in ITEs_tree:
2579
- for ITE in ITEs:
2580
- ITE:ITEpar
2581
- ITE.FlagInit=False
2582
- for w in self.tabWidgets:
2583
- w:gPaIRS_Tab
2584
- TABpar_ind:TABpar=w.TABpar_at(ITE.ind)
2585
- if TABpar_ind: TABpar_ind.FlagInit=False
3301
+ #all_indexes=[i for i in range(len(data[2]))]
3302
+ insert_at_depth(self.projectTree.itemList,self.projectTree.listDepth,0,data[2])
3303
+ self.checkProcesses()
2586
3304
  self.ui.Explorer.ITEpar.FlagInit=False
2587
- for ind in range(len(self.projectTree.itemList[0])):
2588
- self.projectTree.createProjectItem(ind,FlagNewItem=False)
3305
+ for _ in range(len(self.projectTree.itemList[0])):
3306
+ self.projectTree.createProjectItem(FlagNewItem=False)
2589
3307
  """
2590
3308
  item=self.projectTree.topLevelItem(0)
2591
3309
  self.projectTree.setCurrentItem(item)
@@ -2599,11 +3317,12 @@ class gPaIRS(QMainWindow):
2599
3317
  # self.move(0, -1e6) #todo: capire come aggiornare la geometria senza lo show
2600
3318
  # self.show()
2601
3319
  pri.Time.cyan('Open workspace: set data')
2602
- self.TREpar.step=None
3320
+ #self.TREpar.step=None
3321
+ #FlagShown=self.falseShow()
3322
+ if FlagSetGeometry: self.setGPAlayout()
2603
3323
  self.adjustProjectSelection()
2604
- #self.ui.Explorer.selectStep()
3324
+ #if FlagShown: self.hide()
2605
3325
  pri.Time.cyan('Open workspace: selection')
2606
- if FlagSetGeometry: self.setGPAlayout()
2607
3326
  pri.Time.cyan('Open workspace: geometry (end)')
2608
3327
  except Exception as inst:
2609
3328
  if filename==lastcfgname:
@@ -2626,7 +3345,10 @@ class gPaIRS(QMainWindow):
2626
3345
 
2627
3346
  def save_current_workspace(self,filename,FlagAdjustHeader=True):
2628
3347
  self.updateGPAparGeometry()
2629
- if filename!=lastcfgname: self.GPApar.outName=filename
3348
+ if filename!=lastcfgname:
3349
+ if not self.GPApar.outName:
3350
+ self.GPApar.name=os.path.splitext(os.path.basename(filename))[0]
3351
+ self.GPApar.outName=filename
2630
3352
  self.GPApar.savedDate=currentTimeString()
2631
3353
  self.GPApar.FlagSaved=True
2632
3354
  Workspace=[self.GPApar.duplicate(),self.TREpar.duplicate(),self.projectTree.itemList]
@@ -2676,6 +3398,11 @@ class gPaIRS(QMainWindow):
2676
3398
  url = QUrl("https://www.pairs.unina.it/web/PaIRS-UniNa-v020-Guide.pdf")
2677
3399
  QDesktopServices.openUrl(url)
2678
3400
 
3401
+ def downloadApp(self):
3402
+ #url = QUrl("http://wpage.unina.it/etfd/PaIRS/PaIRS-UniNa-Guide.pdf")
3403
+ url = QUrl(EXEurl)
3404
+ QDesktopServices.openUrl(url)
3405
+
2679
3406
  def about(self):
2680
3407
  if self.aboutDialog:
2681
3408
  self.aboutDialog.hide()
@@ -2702,16 +3429,26 @@ class gPaIRS(QMainWindow):
2702
3429
 
2703
3430
  self.ui.aDeleteLastCfg = self.menuDebug.addAction("Delete lastWorkspace"+outExt.cfg)
2704
3431
  def delete_lastcfg():
2705
- os.remove(lastcfgname)
2706
- pri.Info.white(f' xxxxx Deleting last ui configuration file:\t{lastcfgname}')
3432
+ if os.path.exists(lastcfgname):
3433
+ os.remove(lastcfgname)
3434
+ pri.Info.white(f' xxxxx Deleting last ui configuration file:\t{lastcfgname}')
3435
+ else:
3436
+ pri.Info.white(f' xxxxx Last ui configuration file:\t{lastcfgname}\t already deleted!')
2707
3437
  self.delete_lastcfg=delete_lastcfg
2708
3438
  self.ui.aDeleteLastCfg.triggered.connect(delete_lastcfg)
2709
3439
 
3440
+ self.ui.aReloadLastCfg = self.menuDebug.addAction("Reload lastWorkspace"+outExt.cfg)
3441
+ def reloadLastCfg():
3442
+ if os.path.exists(lastcfgname): self.initialize()
3443
+ else: self.new_workspace_debug()
3444
+ self.ui.aReloadLastCfg.triggered.connect(reloadLastCfg)
3445
+
2710
3446
  #--------------------------- printings
2711
3447
  self.menuDebug.addSeparator()
2712
3448
  self.ui.printMenu=self.menuDebug.addMenu('Print')
2713
3449
  printTypes_list=list(self.GPApar.printTypes)
2714
3450
  printActions=[]
3451
+ printCallbacks=[]
2715
3452
  def setPrint(name,act,k):
2716
3453
  flag=act.isChecked()
2717
3454
  self.GPApar.printTypes[name]=flag
@@ -2728,8 +3465,13 @@ class gPaIRS(QMainWindow):
2728
3465
  n=name
2729
3466
  a=act
2730
3467
  j=k
2731
- return lambda: setPrint(n,a,j)
3468
+ def callback():
3469
+ setPrint(n,a,j)
3470
+ self.menuDebug.popup(self.menuDebug.pos())
3471
+ self.ui.printMenu.exec_()
3472
+ return callback
2732
3473
  for k,name in enumerate(printTypes_list):
3474
+ if not hasattr(pri,name): continue
2733
3475
  flagFullDebug=getattr(getattr(pri,name),'flagFullDebug')
2734
3476
  if flagFullDebug and not Flag_fullDEBUG: continue
2735
3477
  act=self.ui.printMenu.addAction(name)
@@ -2738,8 +3480,22 @@ class gPaIRS(QMainWindow):
2738
3480
  flag=self.GPApar.printTypes[name]
2739
3481
  act.setChecked(flag)
2740
3482
  setPrint(name,act,k)
2741
- act.triggered.connect(genCallback(name,act,k))
2742
-
3483
+ printCallbacks.append(genCallback(name,act,k))
3484
+ act.triggered.connect(printCallbacks[-1])
3485
+ self.ui.printMenu.addSeparator()
3486
+ allPrintsAct=self.ui.printMenu.addAction('All printings')
3487
+ allPrintsAct.setCheckable(True)
3488
+ def setAllPrints():
3489
+ flag=allPrintsAct.isChecked()
3490
+ for a in printActions:
3491
+ a:QAction
3492
+ a.setChecked(flag)
3493
+ setPrint(a.text(),a,None)
3494
+ self.menuDebug.popup(self.menuDebug.pos())
3495
+ self.ui.printMenu.exec_()
3496
+ return
3497
+ allPrintsAct.triggered.connect(setAllPrints)
3498
+
2743
3499
  #--------------------------- operation
2744
3500
  if Flag_fullDEBUG:
2745
3501
  self.menuDebug.addSeparator()
@@ -2760,14 +3516,25 @@ class gPaIRS(QMainWindow):
2760
3516
  self.ui.button_PaIRS_download.setVisible(not self.ui.button_PaIRS_download.isVisible())
2761
3517
  self.ui.aShowDownload.triggered.connect(aShowDownload)
2762
3518
 
3519
+ self.ui.aBetaDownload = self.menuDebug.addAction("Change download button icon")
3520
+ def aBetaDownload():
3521
+ b=self.ui.button_PaIRS_download
3522
+ if b.icon().pixmap(b.size()).toImage()==self.flaticon_PaIRS_download.pixmap(b.size()).toImage():
3523
+ b.setIcon(self.flaticon_PaIRS_beta)
3524
+ else:
3525
+ b.setIcon(self.flaticon_PaIRS_download)
3526
+ self.ui.aBetaDownload.triggered.connect(aBetaDownload)
3527
+
2763
3528
  self.ui.aResetFlagOutDated = self.menuDebug.addAction("Reset FlagOutDated")
2764
3529
  def aResetFlagOutDated():
2765
- self.GPApar.FlagOutDated=0 if self.GPApar.currentVersion==self.GPApar.latestVersion else 1
3530
+ self.GPApar.FlagOutDated=0 if self.GPApar.currentVersion==self.GPApar.latestVersion else 1 if self.GPApar.FlagOutDated>0 else -1
2766
3531
  packageName='PaIRS-UniNa'
2767
3532
  currentVersion=self.GPApar.currentVersion
2768
3533
  latestVersion=self.GPApar.latestVersion
2769
3534
  if self.GPApar.FlagOutDated==1:
2770
3535
  sOut=f'{packageName} the current version ({currentVersion}) of {packageName} is obsolete! Please, install the latest version: {latestVersion} by using:\npython -m pip install --upgrade {packageName}'
3536
+ elif self.GPApar.FlagOutDated==1:
3537
+ sOut=f'The version of the current instance of {packageName} ({currentVersion}) is newer than the latest official releas ({latestVersion})!\nYou should contact Tommaso and Gerardo if you are a developer and some relevant change is made by yourself!\nIf you are a user, enjoy this beta version and please report any issue!'
2771
3538
  else:
2772
3539
  sOut=f'{packageName} The current version ({currentVersion}) of {packageName} is up-to-date! Enjoy it!'
2773
3540
  pri.Info.yellow(f'[{self.GPApar.FlagOutDated}] '+sOut)
@@ -2792,7 +3559,7 @@ class gPaIRS(QMainWindow):
2792
3559
 
2793
3560
  self.ui.aShowWhatsNew = self.menuDebug.addAction("Show What's new window")
2794
3561
  def aShowWhatsNew():
2795
- whatsNew(self)
3562
+ self.whatsNew()
2796
3563
  self.ui.aShowWhatsNew.triggered.connect(aShowWhatsNew)
2797
3564
 
2798
3565
  self.menuDebug.addSeparator()
@@ -2805,14 +3572,40 @@ class gPaIRS(QMainWindow):
2805
3572
 
2806
3573
  self.ui.aFocusWid = self.menuDebug.addAction("Print widget with focus")
2807
3574
  def aFocusWid():
2808
- pri.General.yellow(f"The widget with focus is: {self.focusWidget()}")
3575
+ pri.Info.yellow(f"The widget with focus is: {self.focusWidget()}")
2809
3576
  self.aCheckConnections=aFocusWid
2810
3577
  self.ui.aFocusWid.triggered.connect(aFocusWid)
3578
+
3579
+ if not Flag_ISEXE:
3580
+ self.menuDebug.addSeparator()
3581
+ self.ui.aResetRequiredPackagesFile = self.menuDebug.addAction("Reset rqrdpckgs.txt file")
3582
+ def aResetRequiredPackagesFile():
3583
+ resetRequiredPackagesFile()
3584
+ self.ui.aResetRequiredPackagesFile.triggered.connect(aResetRequiredPackagesFile)
3585
+
3586
+ self.ui.aCheckRequiredPackages = self.menuDebug.addAction("Requirements' version check")
3587
+ def aCheckRequiredPackages():
3588
+ checkRequiredPackages(self,FlagDisplay=True)
3589
+ self.ui.aCheckRequiredPackages.triggered.connect(aCheckRequiredPackages)
3590
+
3591
+ self.ui.aShowPackIssue = self.menuDebug.addAction("Show/hide version check button")
3592
+ def aShowPackIssue():
3593
+ self.FlagPackIssue=not self.FlagPackIssue
3594
+ self.ui.button_packissue.setVisible(self.FlagPackIssue)
3595
+ self.ui.aShowPackIssue.triggered.connect(aShowPackIssue)
3596
+
3597
+ self.ui.aTryCheckRequiredPackages = self.menuDebug.addAction("Try requirements' version check")
3598
+ def aTryCheckRequiredPackages():
3599
+ checkRequiredPackages(self,FlagDisplay=True,FlagForcePrint=True)
3600
+ self.ui.aTryCheckRequiredPackages.triggered.connect(aTryCheckRequiredPackages)
2811
3601
 
2812
3602
  #--------------------------- graphics
2813
3603
  if Flag_fullDEBUG:
2814
3604
  self.menuDebug.addSeparator()
2815
3605
 
3606
+ self.ui.aDefSizes = self.menuDebug.addAction("Set default sizes")
3607
+ self.ui.aDefSizes.triggered.connect(self.setDefaultSizes)
3608
+
2816
3609
  self.ui.aUndock = self.menuDebug.addAction("Undock a widget")
2817
3610
  self.ui.aUndock.triggered.connect(self.extractWidget)
2818
3611
 
@@ -2835,7 +3628,9 @@ class gPaIRS(QMainWindow):
2835
3628
  def extractWidget(self):
2836
3629
  title="Undock a widget"
2837
3630
  label="Enter the widget name:"
2838
- words = ["self.w_Import", "self.w_Export",
3631
+ words = ["self.w_Input",
3632
+ "self.w_Input.ui.CollapBox_ImSet",
3633
+ "self.w_Output",
2839
3634
  "self.w_Process",
2840
3635
  "self.w_Process.ui.CollapBox_IntWind",
2841
3636
  "self.w_Process.ui.CollapBox_FinIt",
@@ -2843,9 +3638,12 @@ class gPaIRS(QMainWindow):
2843
3638
  "self.w_Process.ui.CollapBox_Interp",
2844
3639
  "self.w_Process.ui.CollapBox_Validation",
2845
3640
  "self.w_Process.ui.CollapBox_Windowing",
2846
- "self.w_Vis","self.w_Vis.ui.CollapBox_PlotTools",
2847
- "self.ui.w_Managing_Tabs","self.w_Tree",
2848
- "self.w_Log","self.ui.w_Buttons",
3641
+ "self.w_Vis", "self.w_Vis.ui.CollapBox_PlotTools",
3642
+ "self.w_Process", "self.w_Log",
3643
+ "self.w_Process_Min","self.w_Process_Disp",
3644
+ "self.w_Calibration",
3645
+ "self.w_Input_CalVi", "self.w_Process_CalVi", "self.w_Vis_CalVi",
3646
+ "self.ui.w_Managing_Tabs",
2849
3647
  ]
2850
3648
 
2851
3649
  ok,text=inputDialog(self,title,label,completer_list=words,width=500)
@@ -2882,6 +3680,19 @@ class gPaIRS(QMainWindow):
2882
3680
  self.setGPaIRSTitle()
2883
3681
  self.menuDebug.menuAction().setVisible(Flag)
2884
3682
 
3683
+ def setButtonDownload(self,):
3684
+ self.ui.button_PaIRS_download.setVisible(self.GPApar.FlagOutDated!=0)
3685
+ if self.GPApar.FlagOutDated>0:
3686
+ self.ui.button_PaIRS_download.setIcon(self.flaticon_PaIRS_download)
3687
+ self.ui.button_PaIRS_download.setToolTip("Download the latest version of PaIRS-UniNa.")
3688
+ elif self.GPApar.FlagOutDated==-1000:
3689
+ self.ui.button_PaIRS_download.setIcon(self.flaticon_PaIRS_download_warning)
3690
+ self.ui.button_PaIRS_download.setToolTip("Issue with verifying the latest release!")
3691
+ else:
3692
+ self.ui.button_PaIRS_download.setIcon(self.flaticon_PaIRS_beta)
3693
+ self.ui.button_PaIRS_download.setToolTip("A beta version is currently used!")
3694
+ self.ui.button_PaIRS_download.setStatusTip(self.ui.button_PaIRS_download.toolTip())
3695
+
2885
3696
  #*************************************************** Greetings
2886
3697
  def setupLogo(self):
2887
3698
  today = datetime.date.today()
@@ -2892,6 +3703,8 @@ class gPaIRS(QMainWindow):
2892
3703
  ['05/02/1969', 'Happy birthday to Tommaso! 🎈🎂🍾'],
2893
3704
  ['11/07/1987', 'Happy birthday to Carlo! 🎈🎂🍾'],
2894
3705
  ['19/09/1963', 'Happy birthday to Gennaro! 🎈🎂🍾'],
3706
+ ['27/11/1940', 'Happy birthday to prof. Carlomagno! 🎈🎂🍾'],
3707
+ ['01/12/1969', 'Happy birthday to Giuseppe S.! 🎈🎂🍾'],
2895
3708
  ['18/10/1985', 'Happy birthday to Stefano! 🎈🎂🍾'],
2896
3709
  ['13/08/1985', 'Happy birthday to Andrea! 🎈🎂🍾'],
2897
3710
  ['22/12/1988', 'Happy birthday to Jack! 🎈🎂🍾'],
@@ -2899,6 +3712,13 @@ class gPaIRS(QMainWindow):
2899
3712
  ['03/11/1989', 'Happy birthday to Massimo! 🎈🎂🍾'],
2900
3713
  ['15/06/1991', 'Happy birthday to Mattia! 🎈🎂🍾'],
2901
3714
  ['14/07/1993', 'Happy birthday to Mirko! 🎈🎂🍾'],
3715
+ ['13/03/1997', 'Happy birthday to Giosuè! 🎈🎂🍾'],
3716
+ ['24/09/1998', 'Happy birthday to Piergiorgio! 🎈🎂🍾'],
3717
+ ['15/01/1999', 'Happy birthday to Alessandro! 🎈🎂🍾'],
3718
+ ['20/02/1999', 'Happy birthday to Cristina! 🎈🎂🍾'],
3719
+ ['20/09/2000', 'Happy birthday to Antonio M.! 🎈🎂🍾'],
3720
+ ['21/09/2000', 'Happy birthday to Gabriele! 🎈🎂🍾'],
3721
+ ['16/11/2000', 'Happy birthday to Antonio D.! 🎈🎂🍾'],
2902
3722
  ['01/01', 'Happy New Year! 🎊🧨'],
2903
3723
  ['25/12', 'Merry Christmas! 🎄✨'],
2904
3724
  ['31/10', 'Happy Halloween! 🎃👻'],
@@ -2921,6 +3741,34 @@ class gPaIRS(QMainWindow):
2921
3741
  self.ui.logo.setPixmap(QPixmap(u""+ icons_path +"logo_PaIRS_rect.png"))
2922
3742
  self.ui.lab_happy_days.hide()
2923
3743
 
3744
+ def startHappyLogoWatcher(self):
3745
+ """Re-check date at next midnight and periodically as keep-alive."""
3746
+ # one-shot timer to just-after-midnight (00:01)
3747
+ def _schedule_midnight():
3748
+ now=QDateTime.currentDateTime()
3749
+ next_day = now.date().addDays(1)
3750
+ next_midnight = QDateTime(next_day, QTime(0, 0))
3751
+ msec=now.msecsTo(next_midnight.addSecs(60)) # 00:01
3752
+ if msec<60_000: msec=60_000 # safety minimum
3753
+ self._happy_midnight=QTimer(self)
3754
+ self._happy_midnight.setSingleShot(True)
3755
+ self._happy_midnight.timeout.connect(_on_tick)
3756
+ self._happy_midnight.start(msec)
3757
+
3758
+ def _on_tick():
3759
+ # Re-apply logo state and reschedule
3760
+ self.setupLogo()
3761
+ _schedule_midnight()
3762
+
3763
+ # keep-alive each few hours (handles sleep/wake or clock drift)
3764
+ self._happy_keepalive=QTimer(self)
3765
+ self._happy_keepalive.setInterval(3*60*60*1000) # 3h
3766
+ self._happy_keepalive.timeout.connect(self.setupLogo)
3767
+ self._happy_keepalive.start()
3768
+
3769
+ # initial schedule
3770
+ _schedule_midnight()
3771
+
2924
3772
  def happyLogo(self):
2925
3773
  self.FlagHappyLogo=not self.FlagHappyLogo
2926
3774
  if self.FlagHappyLogo:
@@ -2930,7 +3778,7 @@ class gPaIRS(QMainWindow):
2930
3778
  else:
2931
3779
  self.ui.logo.setPixmap(QPixmap(u""+ icons_path +"logo_PaIRS_rect.png"))
2932
3780
  self.ui.lab_happy_days.hide()
2933
-
3781
+
2934
3782
  #*************************************************** Palette
2935
3783
  def setGPaIRSPalette(self):
2936
3784
  setAppGuiPalette(self,self.palettes[self.GPApar.paletteType])
@@ -2967,7 +3815,7 @@ def launchPaIRS(flagDebug=False,flagInputDebug=False):
2967
3815
  import ctypes
2968
3816
  ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('PaIRS')
2969
3817
  except:
2970
- pri.General.red('It was not possible to set the application icon')
3818
+ pri.Info.red('It was not possible to set the application icon')
2971
3819
 
2972
3820
  if not flagDebug or Flag_SHOWSPLASH:
2973
3821
  splash=showSplash()
@@ -2983,15 +3831,16 @@ def launchPaIRS(flagDebug=False,flagInputDebug=False):
2983
3831
  if p.flagFullDebug and not Flag_fullDEBUG:
2984
3832
  p.prio=PrintTAPriority.never
2985
3833
  p.setPrints()
3834
+
3835
+ if FlagAddMotherBoard and Flag_fullDEBUG:
3836
+ pri.Info.yellow(f"{'-'*50}\nHi, developer!\nMaybe it could be useful for you to add the current computer identifier:\n{currentID}\nto the 'developerIDs' dictionary in PaIRS_pypacks.py!\n{'-'*50}\n")
2986
3837
 
2987
3838
  if flagInputDebug:
2988
3839
  _,text=inputDialog(None,'Debug','Insert password for debug mode:',icon=icon,palette=standardPalette,width=300)
2989
3840
  flagDebug=text==pwddbg
2990
3841
  if not flagDebug:
2991
3842
  warningDialog(None,'Password for debug mode is wrong!\nPaIRS will be started in normal mode.',icon=icon,time_milliseconds=5000)
2992
- gui=gPaIRS(flagDebug,app)
2993
- gui.palettes[2]=standardPalette
2994
- gui.setGPaIRSPalette()
3843
+ gui=gPaIRS(flagDebug,app, standardPalette)
2995
3844
 
2996
3845
  currentVersion=__version__ #if __subversion__=='0' else __version__+'.'+__subversion__
2997
3846
  flagStopAndDownload=checkLatestVersion(gui,currentVersion,app,splash)
@@ -3016,7 +3865,12 @@ def launchPaIRS(flagDebug=False,flagInputDebug=False):
3016
3865
  splashAnimation(splash,gui.ui.logo)
3017
3866
  #QTimer.singleShot(time_showSplashOnTop,splash.hide)
3018
3867
  print('\nWelcome to PaIRS!\nEnjoy it!')
3019
- if os.path.exists(fileWhatsNew[0]): whatsNew(gui)
3868
+ if not getattr(sys, 'frozen', False): #made by pyInstaller
3869
+ checkRequiredPackages(gui)
3870
+ else:
3871
+ gui.FlagPackIssue=False
3872
+ gui.ui.button_packissue.setVisible(gui.FlagPackIssue)
3873
+ if os.path.exists(fileWhatsNew[0]): gui.whatsNew()
3020
3874
  app.exec()
3021
3875
  return [app,gui,True]
3022
3876
 
@@ -3041,7 +3895,7 @@ def splashAnimation(self:QLabel,logo:QLabel):
3041
3895
  self.anim_group.finished.connect(self.hide)
3042
3896
  self.anim_group.finished.connect(logo.show)
3043
3897
  self.anim_group.start()
3044
-
3898
+
3045
3899
  def quitPaIRS(app:QApplication,flagPrint=True):
3046
3900
  app.setWindowIcon(app.pyicon)
3047
3901
  app.quit()