datalab-platform 0.0.1.dev0__py3-none-any.whl → 1.0.1__py3-none-any.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 (496) hide show
  1. datalab/__init__.py +35 -2
  2. datalab/adapters_metadata/__init__.py +31 -0
  3. datalab/adapters_metadata/base_adapter.py +316 -0
  4. datalab/adapters_metadata/common.py +422 -0
  5. datalab/adapters_metadata/geometry_adapter.py +98 -0
  6. datalab/adapters_metadata/table_adapter.py +84 -0
  7. datalab/adapters_plotpy/__init__.py +54 -0
  8. datalab/adapters_plotpy/annotations.py +124 -0
  9. datalab/adapters_plotpy/base.py +110 -0
  10. datalab/adapters_plotpy/converters.py +86 -0
  11. datalab/adapters_plotpy/factories.py +80 -0
  12. datalab/adapters_plotpy/objects/__init__.py +0 -0
  13. datalab/adapters_plotpy/objects/base.py +197 -0
  14. datalab/adapters_plotpy/objects/image.py +157 -0
  15. datalab/adapters_plotpy/objects/scalar.py +565 -0
  16. datalab/adapters_plotpy/objects/signal.py +264 -0
  17. datalab/adapters_plotpy/roi/__init__.py +0 -0
  18. datalab/adapters_plotpy/roi/base.py +146 -0
  19. datalab/adapters_plotpy/roi/factory.py +93 -0
  20. datalab/adapters_plotpy/roi/image.py +207 -0
  21. datalab/adapters_plotpy/roi/signal.py +72 -0
  22. datalab/app.py +98 -0
  23. datalab/config.py +817 -0
  24. datalab/control/__init__.py +0 -0
  25. datalab/control/baseproxy.py +776 -0
  26. datalab/control/proxy.py +343 -0
  27. datalab/control/remote.py +1005 -0
  28. datalab/data/doc/DataLab_en.pdf +0 -0
  29. datalab/data/doc/DataLab_fr.pdf +0 -0
  30. datalab/data/icons/analysis/delete_results.svg +109 -0
  31. datalab/data/icons/analysis/fw1e2.svg +156 -0
  32. datalab/data/icons/analysis/fwhm.svg +156 -0
  33. datalab/data/icons/analysis/histogram.svg +49 -0
  34. datalab/data/icons/analysis/peak_detect.svg +160 -0
  35. datalab/data/icons/analysis/plot_results.svg +151 -0
  36. datalab/data/icons/analysis/show_results.svg +83 -0
  37. datalab/data/icons/analysis/stats.svg +49 -0
  38. datalab/data/icons/analysis.svg +120 -0
  39. datalab/data/icons/apply.svg +3 -0
  40. datalab/data/icons/check_all.svg +15 -0
  41. datalab/data/icons/collapse.svg +44 -0
  42. datalab/data/icons/collapse_selection.svg +63 -0
  43. datalab/data/icons/console.svg +101 -0
  44. datalab/data/icons/create/1d-normal.svg +8 -0
  45. datalab/data/icons/create/1d-poisson.svg +9 -0
  46. datalab/data/icons/create/1d-uniform.svg +8 -0
  47. datalab/data/icons/create/1d-zero.svg +57 -0
  48. datalab/data/icons/create/2d-gaussian.svg +56 -0
  49. datalab/data/icons/create/2d-normal.svg +38 -0
  50. datalab/data/icons/create/2d-poisson.svg +38 -0
  51. datalab/data/icons/create/2d-ramp.svg +90 -0
  52. datalab/data/icons/create/2d-sinc.svg +62 -0
  53. datalab/data/icons/create/2d-uniform.svg +38 -0
  54. datalab/data/icons/create/2d-zero.svg +13 -0
  55. datalab/data/icons/create/checkerboard.svg +39 -0
  56. datalab/data/icons/create/cosine.svg +12 -0
  57. datalab/data/icons/create/exponential.svg +55 -0
  58. datalab/data/icons/create/gaussian.svg +12 -0
  59. datalab/data/icons/create/grating.svg +29 -0
  60. datalab/data/icons/create/linear_chirp.svg +7 -0
  61. datalab/data/icons/create/logistic.svg +7 -0
  62. datalab/data/icons/create/lorentzian.svg +12 -0
  63. datalab/data/icons/create/planck.svg +12 -0
  64. datalab/data/icons/create/polynomial.svg +7 -0
  65. datalab/data/icons/create/pulse.svg +12 -0
  66. datalab/data/icons/create/ring.svg +18 -0
  67. datalab/data/icons/create/sawtooth.svg +7 -0
  68. datalab/data/icons/create/siemens.svg +35 -0
  69. datalab/data/icons/create/sinc.svg +12 -0
  70. datalab/data/icons/create/sine.svg +7 -0
  71. datalab/data/icons/create/square.svg +7 -0
  72. datalab/data/icons/create/square_pulse.svg +7 -0
  73. datalab/data/icons/create/step.svg +7 -0
  74. datalab/data/icons/create/step_pulse.svg +12 -0
  75. datalab/data/icons/create/triangle.svg +7 -0
  76. datalab/data/icons/create/voigt.svg +12 -0
  77. datalab/data/icons/edit/annotations.svg +72 -0
  78. datalab/data/icons/edit/annotations_copy.svg +114 -0
  79. datalab/data/icons/edit/annotations_delete.svg +83 -0
  80. datalab/data/icons/edit/annotations_edit.svg +98 -0
  81. datalab/data/icons/edit/annotations_export.svg +85 -0
  82. datalab/data/icons/edit/annotations_import.svg +85 -0
  83. datalab/data/icons/edit/annotations_paste.svg +100 -0
  84. datalab/data/icons/edit/copy_titles.svg +109 -0
  85. datalab/data/icons/edit/delete.svg +84 -0
  86. datalab/data/icons/edit/delete_all.svg +214 -0
  87. datalab/data/icons/edit/duplicate.svg +64 -0
  88. datalab/data/icons/edit/goto_source.svg +60 -0
  89. datalab/data/icons/edit/metadata.svg +60 -0
  90. datalab/data/icons/edit/metadata_add.svg +80 -0
  91. datalab/data/icons/edit/metadata_copy.svg +96 -0
  92. datalab/data/icons/edit/metadata_delete.svg +62 -0
  93. datalab/data/icons/edit/metadata_export.svg +68 -0
  94. datalab/data/icons/edit/metadata_import.svg +68 -0
  95. datalab/data/icons/edit/metadata_paste.svg +79 -0
  96. datalab/data/icons/edit/move_down.svg +55 -0
  97. datalab/data/icons/edit/move_up.svg +54 -0
  98. datalab/data/icons/edit/new_group.svg +76 -0
  99. datalab/data/icons/edit/recompute.svg +60 -0
  100. datalab/data/icons/edit/rename.svg +49 -0
  101. datalab/data/icons/edit.svg +16 -0
  102. datalab/data/icons/expand.svg +44 -0
  103. datalab/data/icons/expand_selection.svg +63 -0
  104. datalab/data/icons/fit/cdf_fit.svg +56 -0
  105. datalab/data/icons/fit/exponential_fit.svg +55 -0
  106. datalab/data/icons/fit/gaussian_fit.svg +62 -0
  107. datalab/data/icons/fit/interactive_fit.svg +101 -0
  108. datalab/data/icons/fit/linear_fit.svg +57 -0
  109. datalab/data/icons/fit/lorentzian_fit.svg +209 -0
  110. datalab/data/icons/fit/multigaussian_fit.svg +85 -0
  111. datalab/data/icons/fit/multilorentzian_fit.svg +85 -0
  112. datalab/data/icons/fit/piecewiseexponential_fit.svg +209 -0
  113. datalab/data/icons/fit/planckian_fit.svg +62 -0
  114. datalab/data/icons/fit/polynomial_fit.svg +59 -0
  115. datalab/data/icons/fit/sigmoid_fit.svg +56 -0
  116. datalab/data/icons/fit/sinusoidal_fit.svg +72 -0
  117. datalab/data/icons/fit/twohalfgaussian_fit.svg +63 -0
  118. datalab/data/icons/fit/voigt_fit.svg +57 -0
  119. datalab/data/icons/group.svg +56 -0
  120. datalab/data/icons/h5/h5array.svg +59 -0
  121. datalab/data/icons/h5/h5attrs.svg +75 -0
  122. datalab/data/icons/h5/h5browser.svg +133 -0
  123. datalab/data/icons/h5/h5file.svg +69 -0
  124. datalab/data/icons/h5/h5group.svg +49 -0
  125. datalab/data/icons/h5/h5scalar.svg +1 -0
  126. datalab/data/icons/help_pdf.svg +46 -0
  127. datalab/data/icons/history.svg +7 -0
  128. datalab/data/icons/image.svg +135 -0
  129. datalab/data/icons/io/fileopen_directory.svg +60 -0
  130. datalab/data/icons/io/fileopen_h5.svg +84 -0
  131. datalab/data/icons/io/fileopen_ima.svg +187 -0
  132. datalab/data/icons/io/fileopen_py.svg +123 -0
  133. datalab/data/icons/io/fileopen_sig.svg +138 -0
  134. datalab/data/icons/io/filesave_h5.svg +97 -0
  135. datalab/data/icons/io/filesave_ima.svg +200 -0
  136. datalab/data/icons/io/filesave_py.svg +136 -0
  137. datalab/data/icons/io/filesave_sig.svg +151 -0
  138. datalab/data/icons/io/import_text.svg +144 -0
  139. datalab/data/icons/io/save_to_directory.svg +134 -0
  140. datalab/data/icons/io.svg +84 -0
  141. datalab/data/icons/libre-camera-flash-off.svg +1 -0
  142. datalab/data/icons/libre-camera-flash-on.svg +1 -0
  143. datalab/data/icons/libre-gui-about.svg +1 -0
  144. datalab/data/icons/libre-gui-action-delete.svg +1 -0
  145. datalab/data/icons/libre-gui-add.svg +1 -0
  146. datalab/data/icons/libre-gui-arrow-down.svg +1 -0
  147. datalab/data/icons/libre-gui-arrow-left.svg +1 -0
  148. datalab/data/icons/libre-gui-arrow-right.svg +1 -0
  149. datalab/data/icons/libre-gui-arrow-up.svg +1 -0
  150. datalab/data/icons/libre-gui-close.svg +40 -0
  151. datalab/data/icons/libre-gui-cogs.svg +1 -0
  152. datalab/data/icons/libre-gui-globe.svg +1 -0
  153. datalab/data/icons/libre-gui-help.svg +1 -0
  154. datalab/data/icons/libre-gui-link.svg +1 -0
  155. datalab/data/icons/libre-gui-menu.svg +1 -0
  156. datalab/data/icons/libre-gui-pencil.svg +1 -0
  157. datalab/data/icons/libre-gui-plugin.svg +1 -0
  158. datalab/data/icons/libre-gui-questions.svg +1 -0
  159. datalab/data/icons/libre-gui-settings.svg +1 -0
  160. datalab/data/icons/libre-gui-unlink.svg +1 -0
  161. datalab/data/icons/libre-tech-ram.svg +1 -0
  162. datalab/data/icons/libre-toolbox.svg +1 -0
  163. datalab/data/icons/logs.svg +1 -0
  164. datalab/data/icons/markers.svg +74 -0
  165. datalab/data/icons/menu.svg +13 -0
  166. datalab/data/icons/new_ima.svg +148 -0
  167. datalab/data/icons/new_sig.svg +123 -0
  168. datalab/data/icons/operations/abs.svg +116 -0
  169. datalab/data/icons/operations/arithmetic.svg +123 -0
  170. datalab/data/icons/operations/average.svg +124 -0
  171. datalab/data/icons/operations/complex_from_magnitude_phase.svg +116 -0
  172. datalab/data/icons/operations/complex_from_real_imag.svg +124 -0
  173. datalab/data/icons/operations/constant.svg +116 -0
  174. datalab/data/icons/operations/constant_add.svg +109 -0
  175. datalab/data/icons/operations/constant_divide.svg +109 -0
  176. datalab/data/icons/operations/constant_multiply.svg +109 -0
  177. datalab/data/icons/operations/constant_subtract.svg +109 -0
  178. datalab/data/icons/operations/convert_dtype.svg +117 -0
  179. datalab/data/icons/operations/convolution.svg +46 -0
  180. datalab/data/icons/operations/deconvolution.svg +57 -0
  181. datalab/data/icons/operations/derivative.svg +127 -0
  182. datalab/data/icons/operations/difference.svg +52 -0
  183. datalab/data/icons/operations/division.svg +139 -0
  184. datalab/data/icons/operations/exp.svg +116 -0
  185. datalab/data/icons/operations/flip_horizontally.svg +69 -0
  186. datalab/data/icons/operations/flip_vertically.svg +74 -0
  187. datalab/data/icons/operations/im.svg +124 -0
  188. datalab/data/icons/operations/integral.svg +50 -0
  189. datalab/data/icons/operations/inverse.svg +143 -0
  190. datalab/data/icons/operations/log10.svg +109 -0
  191. datalab/data/icons/operations/phase.svg +116 -0
  192. datalab/data/icons/operations/power.svg +118 -0
  193. datalab/data/icons/operations/product.svg +124 -0
  194. datalab/data/icons/operations/profile.svg +379 -0
  195. datalab/data/icons/operations/profile_average.svg +399 -0
  196. datalab/data/icons/operations/profile_radial.svg +261 -0
  197. datalab/data/icons/operations/profile_segment.svg +262 -0
  198. datalab/data/icons/operations/quadratic_difference.svg +84 -0
  199. datalab/data/icons/operations/re.svg +124 -0
  200. datalab/data/icons/operations/rotate_left.svg +72 -0
  201. datalab/data/icons/operations/rotate_right.svg +72 -0
  202. datalab/data/icons/operations/signals_to_image.svg +314 -0
  203. datalab/data/icons/operations/sqrt.svg +110 -0
  204. datalab/data/icons/operations/std.svg +124 -0
  205. datalab/data/icons/operations/sum.svg +102 -0
  206. datalab/data/icons/play_demo.svg +9 -0
  207. datalab/data/icons/processing/axis_transform.svg +62 -0
  208. datalab/data/icons/processing/bandpass.svg +79 -0
  209. datalab/data/icons/processing/bandstop.svg +71 -0
  210. datalab/data/icons/processing/binning.svg +126 -0
  211. datalab/data/icons/processing/clip.svg +119 -0
  212. datalab/data/icons/processing/detrending.svg +173 -0
  213. datalab/data/icons/processing/distribute_on_grid.svg +769 -0
  214. datalab/data/icons/processing/edge_detection.svg +46 -0
  215. datalab/data/icons/processing/erase.svg +1 -0
  216. datalab/data/icons/processing/exposure.svg +143 -0
  217. datalab/data/icons/processing/fourier.svg +104 -0
  218. datalab/data/icons/processing/highpass.svg +59 -0
  219. datalab/data/icons/processing/interpolation.svg +71 -0
  220. datalab/data/icons/processing/level_adjustment.svg +70 -0
  221. datalab/data/icons/processing/lowpass.svg +60 -0
  222. datalab/data/icons/processing/morphology.svg +49 -0
  223. datalab/data/icons/processing/noise_addition.svg +114 -0
  224. datalab/data/icons/processing/noise_reduction.svg +38 -0
  225. datalab/data/icons/processing/normalize.svg +84 -0
  226. datalab/data/icons/processing/offset_correction.svg +131 -0
  227. datalab/data/icons/processing/resampling1d.svg +101 -0
  228. datalab/data/icons/processing/resampling2d.svg +240 -0
  229. datalab/data/icons/processing/reset_positions.svg +185 -0
  230. datalab/data/icons/processing/resize.svg +9 -0
  231. datalab/data/icons/processing/reverse_signal_x.svg +171 -0
  232. datalab/data/icons/processing/stability.svg +11 -0
  233. datalab/data/icons/processing/swap_x_y.svg +65 -0
  234. datalab/data/icons/processing/thresholding.svg +63 -0
  235. datalab/data/icons/processing/windowing.svg +45 -0
  236. datalab/data/icons/properties.svg +26 -0
  237. datalab/data/icons/reset.svg +9 -0
  238. datalab/data/icons/restore.svg +40 -0
  239. datalab/data/icons/roi/roi.svg +76 -0
  240. datalab/data/icons/roi/roi_coordinate.svg +78 -0
  241. datalab/data/icons/roi/roi_copy.svg +112 -0
  242. datalab/data/icons/roi/roi_delete.svg +81 -0
  243. datalab/data/icons/roi/roi_export.svg +87 -0
  244. datalab/data/icons/roi/roi_graphical.svg +78 -0
  245. datalab/data/icons/roi/roi_grid.svg +67 -0
  246. datalab/data/icons/roi/roi_ima.svg +188 -0
  247. datalab/data/icons/roi/roi_import.svg +87 -0
  248. datalab/data/icons/roi/roi_new.svg +81 -0
  249. datalab/data/icons/roi/roi_new_circle.svg +95 -0
  250. datalab/data/icons/roi/roi_new_polygon.svg +110 -0
  251. datalab/data/icons/roi/roi_new_rectangle.svg +70 -0
  252. datalab/data/icons/roi/roi_paste.svg +98 -0
  253. datalab/data/icons/roi/roi_sig.svg +124 -0
  254. datalab/data/icons/shapes.svg +134 -0
  255. datalab/data/icons/signal.svg +103 -0
  256. datalab/data/icons/table.svg +85 -0
  257. datalab/data/icons/table_unavailable.svg +102 -0
  258. datalab/data/icons/to_signal.svg +124 -0
  259. datalab/data/icons/tour/next.svg +44 -0
  260. datalab/data/icons/tour/previous.svg +44 -0
  261. datalab/data/icons/tour/rewind.svg +51 -0
  262. datalab/data/icons/tour/stop.svg +47 -0
  263. datalab/data/icons/tour/tour.svg +16 -0
  264. datalab/data/icons/uncheck_all.svg +78 -0
  265. datalab/data/icons/view/curve_antialiasing.svg +50 -0
  266. datalab/data/icons/view/new_window.svg +98 -0
  267. datalab/data/icons/view/refresh-auto.svg +57 -0
  268. datalab/data/icons/view/refresh-manual.svg +51 -0
  269. datalab/data/icons/view/reset_curve_styles.svg +96 -0
  270. datalab/data/icons/view/show_first.svg +55 -0
  271. datalab/data/icons/view/show_titles.svg +46 -0
  272. datalab/data/icons/visualization.svg +51 -0
  273. datalab/data/logo/DataLab-Banner-150.png +0 -0
  274. datalab/data/logo/DataLab-Banner-200.png +0 -0
  275. datalab/data/logo/DataLab-Banner2-100.png +0 -0
  276. datalab/data/logo/DataLab-Splash.png +0 -0
  277. datalab/data/logo/DataLab-watermark.png +0 -0
  278. datalab/data/logo/DataLab.svg +83 -0
  279. datalab/data/tests/reordering_test.h5 +0 -0
  280. datalab/data/tutorials/fabry_perot/fabry-perot1.jpg +0 -0
  281. datalab/data/tutorials/fabry_perot/fabry-perot2.jpg +0 -0
  282. datalab/data/tutorials/laser_beam/TEM00_z_13.jpg +0 -0
  283. datalab/data/tutorials/laser_beam/TEM00_z_18.jpg +0 -0
  284. datalab/data/tutorials/laser_beam/TEM00_z_23.jpg +0 -0
  285. datalab/data/tutorials/laser_beam/TEM00_z_30.jpg +0 -0
  286. datalab/data/tutorials/laser_beam/TEM00_z_35.jpg +0 -0
  287. datalab/data/tutorials/laser_beam/TEM00_z_40.jpg +0 -0
  288. datalab/data/tutorials/laser_beam/TEM00_z_45.jpg +0 -0
  289. datalab/data/tutorials/laser_beam/TEM00_z_50.jpg +0 -0
  290. datalab/data/tutorials/laser_beam/TEM00_z_55.jpg +0 -0
  291. datalab/data/tutorials/laser_beam/TEM00_z_60.jpg +0 -0
  292. datalab/data/tutorials/laser_beam/TEM00_z_65.jpg +0 -0
  293. datalab/data/tutorials/laser_beam/TEM00_z_70.jpg +0 -0
  294. datalab/data/tutorials/laser_beam/TEM00_z_75.jpg +0 -0
  295. datalab/data/tutorials/laser_beam/TEM00_z_80.jpg +0 -0
  296. datalab/env.py +542 -0
  297. datalab/gui/__init__.py +89 -0
  298. datalab/gui/actionhandler.py +1701 -0
  299. datalab/gui/docks.py +473 -0
  300. datalab/gui/h5io.py +150 -0
  301. datalab/gui/macroeditor.py +310 -0
  302. datalab/gui/main.py +2081 -0
  303. datalab/gui/newobject.py +217 -0
  304. datalab/gui/objectview.py +766 -0
  305. datalab/gui/panel/__init__.py +48 -0
  306. datalab/gui/panel/base.py +3254 -0
  307. datalab/gui/panel/image.py +157 -0
  308. datalab/gui/panel/macro.py +607 -0
  309. datalab/gui/panel/signal.py +164 -0
  310. datalab/gui/plothandler.py +800 -0
  311. datalab/gui/processor/__init__.py +84 -0
  312. datalab/gui/processor/base.py +2456 -0
  313. datalab/gui/processor/catcher.py +75 -0
  314. datalab/gui/processor/image.py +1214 -0
  315. datalab/gui/processor/signal.py +755 -0
  316. datalab/gui/profiledialog.py +333 -0
  317. datalab/gui/roieditor.py +633 -0
  318. datalab/gui/roigrideditor.py +208 -0
  319. datalab/gui/settings.py +612 -0
  320. datalab/gui/tour.py +908 -0
  321. datalab/h5/__init__.py +12 -0
  322. datalab/h5/common.py +314 -0
  323. datalab/h5/generic.py +580 -0
  324. datalab/h5/native.py +39 -0
  325. datalab/h5/utils.py +95 -0
  326. datalab/objectmodel.py +640 -0
  327. datalab/plugins/_readme_.txt +9 -0
  328. datalab/plugins/datalab_imageformats.py +175 -0
  329. datalab/plugins/datalab_testdata.py +190 -0
  330. datalab/plugins.py +355 -0
  331. datalab/tests/__init__.py +199 -0
  332. datalab/tests/backbone/__init__.py +1 -0
  333. datalab/tests/backbone/config_unit_test.py +170 -0
  334. datalab/tests/backbone/config_versioning_unit_test.py +34 -0
  335. datalab/tests/backbone/dictlistserial_app_test.py +38 -0
  336. datalab/tests/backbone/errorcatcher_unit_test.py +69 -0
  337. datalab/tests/backbone/errormsgbox_unit_test.py +50 -0
  338. datalab/tests/backbone/execenv_unit.py +262 -0
  339. datalab/tests/backbone/loadtest_gdi.py +147 -0
  340. datalab/tests/backbone/long_callback.py +96 -0
  341. datalab/tests/backbone/main_app_test.py +137 -0
  342. datalab/tests/backbone/memory_leak.py +43 -0
  343. datalab/tests/backbone/procisolation1_unit.py +128 -0
  344. datalab/tests/backbone/procisolation2_unit.py +171 -0
  345. datalab/tests/backbone/procisolation_unit_test.py +22 -0
  346. datalab/tests/backbone/profiling_app.py +27 -0
  347. datalab/tests/backbone/strings_unit_test.py +65 -0
  348. datalab/tests/backbone/title_formatting_unit_test.py +82 -0
  349. datalab/tests/conftest.py +131 -0
  350. datalab/tests/features/__init__.py +1 -0
  351. datalab/tests/features/applauncher/__init__.py +1 -0
  352. datalab/tests/features/applauncher/launcher1_app_test.py +28 -0
  353. datalab/tests/features/applauncher/launcher2_app_test.py +30 -0
  354. datalab/tests/features/common/__init__.py +1 -0
  355. datalab/tests/features/common/add_metadata_app_test.py +134 -0
  356. datalab/tests/features/common/add_metadata_unit_test.py +267 -0
  357. datalab/tests/features/common/annotations_management_unit_test.py +152 -0
  358. datalab/tests/features/common/auto_analysis_recompute_unit_test.py +240 -0
  359. datalab/tests/features/common/createobject_unit_test.py +50 -0
  360. datalab/tests/features/common/geometry_results_app_test.py +135 -0
  361. datalab/tests/features/common/interactive_processing_test.py +1109 -0
  362. datalab/tests/features/common/io_app_test.py +75 -0
  363. datalab/tests/features/common/large_results_app_test.py +187 -0
  364. datalab/tests/features/common/metadata_all_patterns_test.py +103 -0
  365. datalab/tests/features/common/metadata_app_test.py +139 -0
  366. datalab/tests/features/common/metadata_io_unit_test.py +60 -0
  367. datalab/tests/features/common/misc_app_test.py +236 -0
  368. datalab/tests/features/common/multiple_geometry_results_unit_test.py +122 -0
  369. datalab/tests/features/common/multiple_table_results_unit_test.py +64 -0
  370. datalab/tests/features/common/operation_modes_app_test.py +392 -0
  371. datalab/tests/features/common/plot_results_app_test.py +278 -0
  372. datalab/tests/features/common/reorder_app_test.py +75 -0
  373. datalab/tests/features/common/result_deletion_unit_test.py +96 -0
  374. datalab/tests/features/common/result_merged_label_unit_test.py +154 -0
  375. datalab/tests/features/common/result_shape_settings_unit_test.py +223 -0
  376. datalab/tests/features/common/roi_plotitem_unit_test.py +64 -0
  377. datalab/tests/features/common/roieditor_unit_test.py +102 -0
  378. datalab/tests/features/common/save_to_dir_app_test.py +163 -0
  379. datalab/tests/features/common/save_to_dir_unit_test.py +474 -0
  380. datalab/tests/features/common/stat_app_test.py +40 -0
  381. datalab/tests/features/common/stats_tools_unit_test.py +77 -0
  382. datalab/tests/features/common/table_results_app_test.py +52 -0
  383. datalab/tests/features/common/textimport_unit_test.py +131 -0
  384. datalab/tests/features/common/uuid_preservation_test.py +281 -0
  385. datalab/tests/features/common/worker_unit_test.py +402 -0
  386. datalab/tests/features/control/__init__.py +1 -0
  387. datalab/tests/features/control/connect_dialog.py +28 -0
  388. datalab/tests/features/control/embedded1_unit_test.py +304 -0
  389. datalab/tests/features/control/embedded2_unit_test.py +52 -0
  390. datalab/tests/features/control/remoteclient_app_test.py +219 -0
  391. datalab/tests/features/control/remoteclient_unit.py +75 -0
  392. datalab/tests/features/control/simpleclient_unit_test.py +321 -0
  393. datalab/tests/features/hdf5/__init__.py +1 -0
  394. datalab/tests/features/hdf5/h5browser1_unit_test.py +31 -0
  395. datalab/tests/features/hdf5/h5browser2_unit.py +55 -0
  396. datalab/tests/features/hdf5/h5browser_app_test.py +77 -0
  397. datalab/tests/features/hdf5/h5import_app_test.py +25 -0
  398. datalab/tests/features/hdf5/h5importer_app_test.py +34 -0
  399. datalab/tests/features/image/__init__.py +1 -0
  400. datalab/tests/features/image/annotations_app_test.py +28 -0
  401. datalab/tests/features/image/annotations_unit_test.py +80 -0
  402. datalab/tests/features/image/average_app_test.py +46 -0
  403. datalab/tests/features/image/background_dialog_test.py +70 -0
  404. datalab/tests/features/image/blobs_app_test.py +50 -0
  405. datalab/tests/features/image/contour_app_test.py +42 -0
  406. datalab/tests/features/image/contour_fabryperot_app_test.py +51 -0
  407. datalab/tests/features/image/denoise_app_test.py +31 -0
  408. datalab/tests/features/image/distribute_on_grid_app_test.py +95 -0
  409. datalab/tests/features/image/edges_app_test.py +31 -0
  410. datalab/tests/features/image/erase_app_test.py +21 -0
  411. datalab/tests/features/image/fft2d_app_test.py +27 -0
  412. datalab/tests/features/image/flatfield_app_test.py +40 -0
  413. datalab/tests/features/image/geometry_transform_unit_test.py +396 -0
  414. datalab/tests/features/image/imagetools_app_test.py +51 -0
  415. datalab/tests/features/image/imagetools_unit_test.py +27 -0
  416. datalab/tests/features/image/load_app_test.py +73 -0
  417. datalab/tests/features/image/morph_app_test.py +32 -0
  418. datalab/tests/features/image/offsetcorrection_app_test.py +30 -0
  419. datalab/tests/features/image/peak2d_app_test.py +53 -0
  420. datalab/tests/features/image/profile_app_test.py +73 -0
  421. datalab/tests/features/image/profile_dialog_test.py +56 -0
  422. datalab/tests/features/image/roi_app_test.py +98 -0
  423. datalab/tests/features/image/roi_circ_app_test.py +62 -0
  424. datalab/tests/features/image/roi_manipulation_app_test.py +268 -0
  425. datalab/tests/features/image/roigrid_unit_test.py +60 -0
  426. datalab/tests/features/image/side_by_side_app_test.py +52 -0
  427. datalab/tests/features/macro/__init__.py +1 -0
  428. datalab/tests/features/macro/macro_app_test.py +28 -0
  429. datalab/tests/features/macro/macroeditor_unit_test.py +102 -0
  430. datalab/tests/features/signal/__init__.py +1 -0
  431. datalab/tests/features/signal/baseline_dialog_test.py +53 -0
  432. datalab/tests/features/signal/deltax_dialog_unit_test.py +34 -0
  433. datalab/tests/features/signal/fft1d_app_test.py +26 -0
  434. datalab/tests/features/signal/filter_app_test.py +44 -0
  435. datalab/tests/features/signal/fitdialog_unit_test.py +50 -0
  436. datalab/tests/features/signal/interpolation_app_test.py +110 -0
  437. datalab/tests/features/signal/loadbigsignal_app_test.py +80 -0
  438. datalab/tests/features/signal/multiple_rois_unit_test.py +132 -0
  439. datalab/tests/features/signal/pulse_features_app_test.py +118 -0
  440. datalab/tests/features/signal/pulse_features_roi_app_test.py +55 -0
  441. datalab/tests/features/signal/roi_app_test.py +78 -0
  442. datalab/tests/features/signal/roi_manipulation_app_test.py +261 -0
  443. datalab/tests/features/signal/select_xy_cursor_unit_test.py +46 -0
  444. datalab/tests/features/signal/signalpeakdetection_dialog_test.py +33 -0
  445. datalab/tests/features/signal/signals_to_image_app_test.py +98 -0
  446. datalab/tests/features/signal/xarray_compat_app_test.py +128 -0
  447. datalab/tests/features/tour_unit_test.py +22 -0
  448. datalab/tests/features/utilities/__init__.py +1 -0
  449. datalab/tests/features/utilities/installconf_unit_test.py +21 -0
  450. datalab/tests/features/utilities/logview_app_test.py +21 -0
  451. datalab/tests/features/utilities/logview_error.py +24 -0
  452. datalab/tests/features/utilities/logview_unit_test.py +21 -0
  453. datalab/tests/features/utilities/memstatus_app_test.py +42 -0
  454. datalab/tests/features/utilities/settings_unit_test.py +88 -0
  455. datalab/tests/scenarios/__init__.py +1 -0
  456. datalab/tests/scenarios/beautiful_app.py +121 -0
  457. datalab/tests/scenarios/common.py +463 -0
  458. datalab/tests/scenarios/demo.py +212 -0
  459. datalab/tests/scenarios/example_app_test.py +47 -0
  460. datalab/tests/scenarios/scenario_h5_app_test.py +75 -0
  461. datalab/tests/scenarios/scenario_ima1_app_test.py +34 -0
  462. datalab/tests/scenarios/scenario_ima2_app_test.py +34 -0
  463. datalab/tests/scenarios/scenario_mac_app_test.py +58 -0
  464. datalab/tests/scenarios/scenario_sig1_app_test.py +36 -0
  465. datalab/tests/scenarios/scenario_sig2_app_test.py +35 -0
  466. datalab/utils/__init__.py +1 -0
  467. datalab/utils/conf.py +304 -0
  468. datalab/utils/dephash.py +105 -0
  469. datalab/utils/qthelpers.py +633 -0
  470. datalab/utils/strings.py +34 -0
  471. datalab/utils/tests.py +0 -0
  472. datalab/widgets/__init__.py +1 -0
  473. datalab/widgets/connection.py +138 -0
  474. datalab/widgets/filedialog.py +91 -0
  475. datalab/widgets/fileviewer.py +84 -0
  476. datalab/widgets/fitdialog.py +788 -0
  477. datalab/widgets/h5browser.py +1048 -0
  478. datalab/widgets/imagebackground.py +111 -0
  479. datalab/widgets/instconfviewer.py +175 -0
  480. datalab/widgets/logviewer.py +80 -0
  481. datalab/widgets/signalbaseline.py +90 -0
  482. datalab/widgets/signalcursor.py +208 -0
  483. datalab/widgets/signaldeltax.py +151 -0
  484. datalab/widgets/signalpeak.py +199 -0
  485. datalab/widgets/status.py +249 -0
  486. datalab/widgets/textimport.py +786 -0
  487. datalab/widgets/warningerror.py +223 -0
  488. datalab/widgets/wizard.py +286 -0
  489. datalab_platform-1.0.1.dist-info/METADATA +121 -0
  490. datalab_platform-1.0.1.dist-info/RECORD +494 -0
  491. datalab_platform-0.0.1.dev0.dist-info/METADATA +0 -67
  492. datalab_platform-0.0.1.dev0.dist-info/RECORD +0 -7
  493. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.1.dist-info}/WHEEL +0 -0
  494. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.1.dist-info}/entry_points.txt +0 -0
  495. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.1.dist-info}/licenses/LICENSE +0 -0
  496. {datalab_platform-0.0.1.dev0.dist-info → datalab_platform-1.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,223 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ Module providing a warning/error message box
5
+ """
6
+
7
+ import os.path as osp
8
+ import re
9
+ import subprocess
10
+ import traceback
11
+
12
+ from guidata.config import CONF
13
+ from guidata.configtools import get_font
14
+ from guidata.qthelpers import exec_dialog, get_std_icon
15
+ from guidata.widgets.console.shell import PythonShellWidget
16
+ from qtpy import QtCore as QC
17
+ from qtpy import QtWidgets as QW
18
+
19
+ from datalab.config import Conf, _, get_mod_source_dir
20
+
21
+
22
+ def go_to_error(text: str) -> None:
23
+ """Go to error: open file with external editor, and go to line number
24
+
25
+ Args:
26
+ text (str): Error text
27
+ """
28
+ pattern = r'File "(.+)", line (\d+),'
29
+ match = re.search(pattern, text)
30
+ if match:
31
+ path = match.group(1)
32
+ line_number = match.group(2)
33
+ mod_src_dir = get_mod_source_dir()
34
+ if not osp.isfile(path) and mod_src_dir is not None:
35
+ otherpath = osp.join(mod_src_dir, path)
36
+ if not osp.isfile(otherpath):
37
+ # TODO: [P3] For frozen app, go to error is implemented only when the
38
+ # source code is available locally (development mode).
39
+ # How about using a web browser to open the source code on github?
40
+ return
41
+ path = otherpath
42
+ if not osp.isfile(path):
43
+ return # File not found (unhandled case)
44
+ fdict = {"path": path, "line_number": line_number}
45
+ args = Conf.console.external_editor_args.get().format(**fdict).split(" ")
46
+ editor_path = Conf.console.external_editor_path.get()
47
+ subprocess.run([editor_path] + args, shell=True, check=False)
48
+
49
+
50
+ def insert_spaces(text: str, nbchars: int) -> str:
51
+ """
52
+ Inserts spaces regularly in a string, every nbchars characters, after certain
53
+ characters (",", ";", "-", "+", "*", ")"), and keeps searching until detecting
54
+ one of those characters.
55
+
56
+ Args:
57
+ text (str): The input string.
58
+ nbchars (int): The number of characters after which a space should be inserted.
59
+
60
+ Returns:
61
+ str: The modified string with spaces inserted.
62
+ """
63
+ special_chars = (",", ";", "-", "+", "*", ")", "_")
64
+ new_text = ""
65
+ index = 0
66
+ while index < len(text):
67
+ if (
68
+ index + nbchars < len(text)
69
+ and text[index + nbchars] not in special_chars
70
+ and not any(c in special_chars for c in text[index : index + nbchars + 1])
71
+ ):
72
+ new_text += text[index : index + nbchars] # Append characters
73
+ index += nbchars
74
+ else:
75
+ new_text += text[index : index + nbchars] + " " # Insert space
76
+ index += nbchars
77
+ return new_text
78
+
79
+
80
+ class WarningErrorMessageBox(QW.QDialog):
81
+ """Warning/Error message box
82
+
83
+ Args:
84
+ parent (QW.QWidget): parent widget
85
+ category (str): message category ("error" or "warning")
86
+ context (str | None): context. Defaults to None.
87
+ message (str | None): message. Defaults to None.
88
+ tip (str | None): tip. Defaults to None.
89
+ """
90
+
91
+ def __init__(
92
+ self,
93
+ parent: QW.QWidget,
94
+ category: str,
95
+ context: str = None,
96
+ message: str = None,
97
+ tip: str = None,
98
+ ) -> None:
99
+ super().__init__(parent)
100
+ assert category in ("error", "warning")
101
+ self.setWindowTitle(parent.window().objectName())
102
+
103
+ self.shell = PythonShellWidget(self, read_only=True)
104
+ self.shell.go_to_error.connect(go_to_error)
105
+ font = get_font(CONF, "console")
106
+ font.setPointSize(9)
107
+ self.shell.set_font(font)
108
+ message = traceback.format_exc() if message is None else message
109
+ self.shell.insert_text(message, at_end=True, error=True)
110
+
111
+ bbox = QW.QDialogButtonBox(QW.QDialogButtonBox.Ok)
112
+ bbox.accepted.connect(self.accept)
113
+ if category == "warning":
114
+ bbox.addButton(QW.QDialogButtonBox.Ignore).clicked.connect(self.ignore)
115
+
116
+ layout = QW.QVBoxLayout()
117
+
118
+ if category == "error":
119
+ width, height = 725, 400
120
+ icon = "MessageBoxCritical"
121
+ tb_title = _("Error message")
122
+ tb_text = _("The following traceback may help to understand the problem:")
123
+ else:
124
+ width, height = 725, 200
125
+ icon = "MessageBoxWarning"
126
+ tb_title = _("Warning message")
127
+ tb_text = _("Please take into account the following warning message:")
128
+
129
+ if context is not None:
130
+ context = insert_spaces(context, 80)
131
+ msgprefix = _("An error has occured during the following context:")
132
+ text = "<br>".join([msgprefix, f"<b>{context}</b>"])
133
+ ct_groupbox = QW.QGroupBox(_("Context"), self)
134
+ ct_layout = QW.QHBoxLayout()
135
+ ct_image_layout = QW.QVBoxLayout()
136
+ ct_image = QW.QLabel()
137
+ ct_image.setPixmap(get_std_icon(icon).pixmap(24, 24))
138
+ ct_image.setSizePolicy(QW.QSizePolicy.Fixed, QW.QSizePolicy.Fixed)
139
+ ct_image_layout.addWidget(ct_image)
140
+ ct_image_layout.addStretch()
141
+ ct_layout.addLayout(ct_image_layout)
142
+ ct_label = QW.QLabel(text)
143
+ ct_label.setWordWrap(True)
144
+ ct_label.setAlignment(QC.Qt.AlignLeft | QC.Qt.AlignTop)
145
+ ct_layout.addWidget(ct_label)
146
+ ct_groupbox.setLayout(ct_layout)
147
+ ct_groupbox.setSizePolicy(
148
+ QW.QSizePolicy.MinimumExpanding, QW.QSizePolicy.Fixed
149
+ )
150
+ layout.addWidget(ct_groupbox)
151
+
152
+ tb_groupbox = QW.QGroupBox(tb_title, self)
153
+ tb_layout = QW.QVBoxLayout()
154
+ tb_layout.addWidget(QW.QLabel(tb_text))
155
+ tb_layout.addWidget(self.shell)
156
+ tb_groupbox.setLayout(tb_layout)
157
+ layout.addWidget(tb_groupbox)
158
+
159
+ if tip is not None:
160
+ tip_groupbox = QW.QGroupBox(_("Tip"), self)
161
+ tip_layout = QW.QHBoxLayout()
162
+ tip_image_layout = QW.QVBoxLayout()
163
+ tip_image = QW.QLabel()
164
+ tip_image.setPixmap(get_std_icon("MessageBoxInformation").pixmap(24, 24))
165
+ tip_image.setSizePolicy(QW.QSizePolicy.Fixed, QW.QSizePolicy.Fixed)
166
+ tip_image_layout.addWidget(tip_image)
167
+ tip_image_layout.addStretch()
168
+ tip_layout.addLayout(tip_image_layout)
169
+ tip_label = QW.QLabel(tip)
170
+ tip_label.setWordWrap(True)
171
+ tip_label.setAlignment(QC.Qt.AlignLeft | QC.Qt.AlignTop)
172
+ tip_layout.addWidget(tip_label)
173
+ tip_groupbox.setLayout(tip_layout)
174
+ tip_groupbox.setSizePolicy(
175
+ QW.QSizePolicy.MinimumExpanding, QW.QSizePolicy.Fixed
176
+ )
177
+ layout.addWidget(tip_groupbox)
178
+
179
+ layout.addSpacing(10)
180
+ if category == "warning":
181
+ layout.addWidget(
182
+ QW.QLabel(
183
+ _(
184
+ "Please click on the 'Ignore' button to "
185
+ "ignore this warning next time."
186
+ )
187
+ )
188
+ )
189
+ layout.addSpacing(10)
190
+
191
+ layout.addWidget(bbox)
192
+
193
+ self.setLayout(layout)
194
+ self.resize(width, height)
195
+
196
+ bbox.button(QW.QDialogButtonBox.Ok).setFocus()
197
+
198
+ def ignore(self):
199
+ """Ignore warning next time"""
200
+ Conf.proc.ignore_warnings.set(True)
201
+ self.accept()
202
+
203
+
204
+ def show_warning_error(
205
+ parent: QW.QWidget,
206
+ category: str,
207
+ context: str = None,
208
+ message: str = None,
209
+ tip: str = None,
210
+ ) -> None:
211
+ """Show error message
212
+
213
+ Args:
214
+ parent (QW.QWidget): parent widget
215
+ category (str): message category ("error" or "warning")
216
+ context (str | None): context. Defaults to None.
217
+ message (str | None): message. Defaults to None.
218
+ tip (str | None): tip. Defaults to None.
219
+ """
220
+ if category == "warning" and Conf.proc.ignore_warnings.get():
221
+ return
222
+ dlg = WarningErrorMessageBox(parent, category, context, message, tip)
223
+ exec_dialog(dlg)
@@ -0,0 +1,286 @@
1
+ # Copyright (c) DataLab Platform Developers, BSD 3-Clause license, see LICENSE file.
2
+
3
+ """
4
+ DataLab Wizard Widget
5
+ ---------------------
6
+
7
+ The DataLab Wizard is a widget that guides the user through a series of steps
8
+ to complete a task. It is implemented as a series of pages, each of which is
9
+ a separate widget.
10
+
11
+ The `Wizard` class is the main widget that contains the pages. The `WizardPage`
12
+ class is the base class for the pages.
13
+
14
+ This module is strongly inspired from Qt's `QWizard` and `QWizardPage` classes.
15
+
16
+ .. note::
17
+
18
+ The only motivation for reimplementing the wizard widget is to
19
+ support complete styling with `QPalette` and `QStyle` (e.g. `guidata`'s
20
+ dark mode is not supported on Windows).
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ from qtpy import QtCore as QC
26
+ from qtpy import QtWidgets as QW
27
+ from qtpy.compat import getopenfilename
28
+ from qtpy.QtWidgets import QWidget
29
+
30
+ from datalab.config import _
31
+
32
+
33
+ class WizardPage(QW.QWidget):
34
+ """Wizard page base class
35
+
36
+ We create our own wizard page class instead of using QWizardPage because
37
+ the latter does not support complete styling with `QPalette` and `QStyle`
38
+ (e.g. `guidata`'s dark mode is not supported on Windows).
39
+
40
+ This class reimplements the `QWizardPage` features.
41
+
42
+ """
43
+
44
+ SIG_INITIALIZE_PAGE = QC.Signal()
45
+ SIG_VALID_STATE_CHANGED = QC.Signal()
46
+
47
+ def __init__(self, parent: QW.QWidget | None = None) -> None:
48
+ super().__init__(parent)
49
+ self.__is_valid: bool = True
50
+ self.wizard: Wizard | None = None
51
+ self._main_layout = QW.QVBoxLayout()
52
+ self._user_layout = QW.QVBoxLayout()
53
+ self._title_label = QW.QLabel("")
54
+ font = self._title_label.font()
55
+ font.setPointSize(font.pointSize() + 4)
56
+ font.setBold(True)
57
+ self._title_label.setFont(font)
58
+ self._title_label.setStyleSheet("color: #1E90FF")
59
+ horiz_line = QW.QFrame()
60
+ horiz_line.setFrameShape(QW.QFrame.HLine)
61
+ horiz_line.setFrameShadow(QW.QFrame.Sunken)
62
+ self._subtitle_label = QW.QLabel("")
63
+ self._main_layout.addWidget(self._title_label)
64
+ self._main_layout.addWidget(self._subtitle_label)
65
+ self._main_layout.addWidget(horiz_line)
66
+ self._main_layout.addLayout(self._user_layout)
67
+ self.setLayout(self._main_layout)
68
+
69
+ def set_wizard(self, wizard: Wizard) -> None:
70
+ """Set the wizard"""
71
+ self.wizard = wizard
72
+
73
+ def get_wizard(self) -> Wizard:
74
+ """Return the wizard"""
75
+ return self.wizard
76
+
77
+ def set_title(self, title: str) -> None:
78
+ """Set the title of the page"""
79
+ self._title_label.setText(title)
80
+
81
+ def set_subtitle(self, subtitle: str) -> None:
82
+ """Set the subtitle of the page"""
83
+ self._subtitle_label.setText(subtitle)
84
+
85
+ def set_valid(self, is_valid: bool) -> None:
86
+ """Set the page as valid"""
87
+ self.__is_valid = is_valid
88
+ self.SIG_VALID_STATE_CHANGED.emit()
89
+
90
+ def is_valid(self) -> bool:
91
+ """Return whether the page is valid"""
92
+ return self.__is_valid
93
+
94
+ def add_to_layout(self, layout: QW.QLayout | QW.QWidget) -> None:
95
+ """Add a layout to the user layout"""
96
+ if isinstance(layout, QW.QWidget):
97
+ self._user_layout.addWidget(layout)
98
+ else:
99
+ self._user_layout.addLayout(layout)
100
+
101
+ def add_stretch(self) -> None:
102
+ """Add a stretch to the user layout"""
103
+ self._user_layout.addStretch()
104
+
105
+ def initialize_page(self) -> None:
106
+ """Initialize the page"""
107
+ self.SIG_INITIALIZE_PAGE.emit()
108
+
109
+ def validate_page(self) -> bool:
110
+ """Validate the page"""
111
+ return self.is_valid()
112
+
113
+
114
+ class Wizard(QW.QDialog):
115
+ """Wizard base class"""
116
+
117
+ def __init__(self, parent: QWidget | None = None) -> None:
118
+ super().__init__(parent)
119
+
120
+ _main_layout = QW.QVBoxLayout()
121
+ self.setLayout(_main_layout)
122
+
123
+ self._pages_widget = QW.QStackedWidget()
124
+ _main_layout.addWidget(self._pages_widget)
125
+
126
+ btn_layout = QW.QHBoxLayout()
127
+ self._back_btn = QW.QPushButton(_("Back"))
128
+ self._back_btn.clicked.connect(self.go_to_previous_page)
129
+ self._next_btn = QW.QPushButton(_("Next"))
130
+ self._next_btn.clicked.connect(self.go_to_next_page)
131
+ self._finish_btn = QW.QPushButton(_("Finish"))
132
+ self._finish_btn.clicked.connect(self.accept)
133
+ self._cancel_btn = QW.QPushButton(_("Cancel"))
134
+ self._cancel_btn.clicked.connect(self.reject)
135
+ btn_layout.addWidget(self._back_btn)
136
+ btn_layout.addWidget(self._next_btn)
137
+ btn_layout.addWidget(self._finish_btn)
138
+ btn_layout.addWidget(self._cancel_btn)
139
+ _main_layout.addLayout(btn_layout)
140
+
141
+ self.setSizePolicy(
142
+ QW.QSizePolicy(QW.QSizePolicy.Minimum, QW.QSizePolicy.Minimum)
143
+ )
144
+
145
+ def add_page(self, page: WizardPage, last_page: bool = False) -> None:
146
+ """Add a page to the wizard"""
147
+ page.set_wizard(self)
148
+ page.SIG_INITIALIZE_PAGE.connect(self.__update_button_states)
149
+ page.SIG_VALID_STATE_CHANGED.connect(self.__update_button_states)
150
+ self._pages_widget.addWidget(page)
151
+ if last_page:
152
+ self._pages_widget.widget(0).initialize_page()
153
+
154
+ def __update_button_states(self, index: int | None = None) -> None:
155
+ """Update button states"""
156
+ if index is None:
157
+ index = self._pages_widget.currentIndex()
158
+ self._back_btn.setEnabled(index > 0)
159
+ not_last_page = index < self._pages_widget.count() - 1
160
+ page_valid = self._pages_widget.currentWidget().is_valid()
161
+ self._next_btn.setEnabled(not_last_page and page_valid)
162
+ is_last_page = index == self._pages_widget.count() - 1
163
+ self._finish_btn.setEnabled(is_last_page and page_valid)
164
+
165
+ def go_to_previous_page(self) -> None:
166
+ """Go to the previous page"""
167
+ self._pages_widget.setCurrentIndex(self._pages_widget.currentIndex() - 1)
168
+ self.__update_button_states()
169
+
170
+ def go_to_next_page(self) -> None:
171
+ """Go to the next page"""
172
+ if self.validate_page():
173
+ self._pages_widget.setCurrentIndex(self._pages_widget.currentIndex() + 1)
174
+ self.initialize_page()
175
+
176
+ def initialize_page(self) -> None:
177
+ """Initialize the page"""
178
+ self._pages_widget.currentWidget().initialize_page()
179
+
180
+ def validate_page(self) -> bool:
181
+ """Validate the page"""
182
+ return self._pages_widget.currentWidget().validate_page()
183
+
184
+ def accept(self) -> None:
185
+ """Accept the wizard"""
186
+ if self.validate_page():
187
+ super().accept()
188
+
189
+
190
+ class ExamplePage1(WizardPage):
191
+ """Example wizard page 1"""
192
+
193
+ def __init__(self) -> None:
194
+ super().__init__()
195
+ self.set_title(_("Welcome to the Example Wizard"))
196
+ self.set_subtitle(
197
+ _("This wizard will guide you through the process of importing data.")
198
+ )
199
+
200
+ def initialize_page(self) -> None:
201
+ """Initialize the page"""
202
+ print("ExamplePage1 initialized")
203
+ super().initialize_page()
204
+
205
+ def validate_page(self) -> bool:
206
+ """Validate the page"""
207
+ print("ExamplePage1 validated")
208
+ return super().validate_page()
209
+
210
+
211
+ class ExamplePage2(WizardPage):
212
+ """Example wizard page 2"""
213
+
214
+ def __init__(self) -> None:
215
+ super().__init__()
216
+ self.set_title(_("Select the Source of the Data"))
217
+ self.set_subtitle(
218
+ _("Select the source of the data to be imported (clipboard or file).")
219
+ )
220
+ self._clipboard_rb = QW.QRadioButton(_("Clipboard"))
221
+ self._file_rb = QW.QRadioButton(_("File"))
222
+ self._file_rb.toggled.connect(self.file_rb_toggled)
223
+ self._file_le = QW.QLineEdit()
224
+ self._file_btn = QW.QPushButton(_("Browse..."))
225
+ self._file_btn.clicked.connect(self.browse_file)
226
+ self.add_to_layout(self._clipboard_rb)
227
+ self.add_to_layout(self._file_rb)
228
+ self.add_to_layout(self._file_le)
229
+ self.add_to_layout(self._file_btn)
230
+
231
+ def initialize_page(self) -> None:
232
+ """Initialize the page"""
233
+ print("ExamplePage2 initialized")
234
+ super().initialize_page()
235
+
236
+ def file_rb_toggled(self, checked: bool) -> None:
237
+ """File radio button toggled"""
238
+ self._file_le.setEnabled(checked)
239
+ self._file_btn.setEnabled(checked)
240
+
241
+ def browse_file(self) -> None:
242
+ """Browse file"""
243
+ file_name, _filt = getopenfilename(
244
+ self,
245
+ _("Select the File to Import"),
246
+ "",
247
+ _("CSV Files (*.csv);;Text Files (*.txt);;All Files (*)"),
248
+ )
249
+ if file_name:
250
+ self._file_le.setText(file_name)
251
+
252
+ def validate_page(self) -> bool:
253
+ """Validate the page"""
254
+ if self._file_rb.isChecked() and not self._file_le.text():
255
+ QW.QMessageBox.critical(
256
+ self,
257
+ _("Error"),
258
+ _("Please select the file to import."),
259
+ QW.QMessageBox.Ok,
260
+ )
261
+ return False
262
+ return True
263
+
264
+
265
+ class ExampleWizard(Wizard):
266
+ """Example wizard widget"""
267
+
268
+ def __init__(self) -> None:
269
+ super().__init__()
270
+ self.setWindowTitle(_("Example Wizard"))
271
+ self.add_page(ExamplePage1())
272
+ self.add_page(ExamplePage2(), last_page=True)
273
+
274
+
275
+ def test_example_wizard():
276
+ """Test the import wizard"""
277
+ # pylint: disable=import-outside-toplevel
278
+ from guidata.qthelpers import qt_app_context
279
+
280
+ with qt_app_context():
281
+ wizard = ExampleWizard()
282
+ wizard.exec()
283
+
284
+
285
+ if __name__ == "__main__":
286
+ test_example_wizard()
@@ -0,0 +1,121 @@
1
+ Metadata-Version: 2.4
2
+ Name: datalab-platform
3
+ Version: 1.0.1
4
+ Summary: DataLab is a data processing and analysis software for scientific and industrial applications
5
+ Author-email: Pierre Raybaut <p.raybaut@codra.fr>
6
+ Maintainer-email: DataLab Platform Developers <p.raybaut@codra.fr>
7
+ License-Expression: BSD-3-Clause
8
+ Project-URL: Homepage, https://datalab-platform.com/
9
+ Project-URL: Documentation, https://datalab-platform.com/
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Education
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Intended Audience :: End Users/Desktop
15
+ Classifier: Operating System :: MacOS :: MacOS X
16
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 7
17
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 8
18
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 10
19
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 11
20
+ Classifier: Operating System :: POSIX :: Linux
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Topic :: Scientific/Engineering
27
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
28
+ Classifier: Topic :: Scientific/Engineering :: Human Machine Interfaces
29
+ Classifier: Topic :: Scientific/Engineering :: Visualization
30
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
31
+ Classifier: Topic :: Software Development :: Widget Sets
32
+ Requires-Python: <4,>=3.9
33
+ Description-Content-Type: text/markdown
34
+ License-File: LICENSE
35
+ Requires-Dist: guidata>=3.13.3
36
+ Requires-Dist: PlotPy>=2.8.2
37
+ Requires-Dist: Sigima>=1.0.2
38
+ Requires-Dist: NumPy>=1.22
39
+ Requires-Dist: SciPy>=1.10.1
40
+ Requires-Dist: scikit-image>=0.19.2
41
+ Requires-Dist: pandas>=1.4
42
+ Requires-Dist: PyWavelets>=1.2
43
+ Requires-Dist: psutil>=5.8
44
+ Requires-Dist: packaging>=21.3
45
+ Provides-Extra: qt
46
+ Requires-Dist: PyQt5>=5.15.6; extra == "qt"
47
+ Provides-Extra: opencv
48
+ Requires-Dist: opencv-python-headless>=4.8.1.78; extra == "opencv"
49
+ Provides-Extra: exe
50
+ Requires-Dist: pyinstaller==6.16.0; extra == "exe"
51
+ Requires-Dist: opencv-python-headless>=4.8.1.78; extra == "exe"
52
+ Requires-Dist: PyQt5>=5.15.6; extra == "exe"
53
+ Provides-Extra: dev
54
+ Requires-Dist: build; extra == "dev"
55
+ Requires-Dist: babel; extra == "dev"
56
+ Requires-Dist: Coverage; extra == "dev"
57
+ Requires-Dist: pylint; extra == "dev"
58
+ Requires-Dist: ruff; extra == "dev"
59
+ Requires-Dist: pre-commit; extra == "dev"
60
+ Provides-Extra: doc
61
+ Requires-Dist: sphinx; extra == "doc"
62
+ Requires-Dist: sphinx_intl; extra == "doc"
63
+ Requires-Dist: sphinx-sitemap; extra == "doc"
64
+ Requires-Dist: myst_parser; extra == "doc"
65
+ Requires-Dist: sphinx_design; extra == "doc"
66
+ Requires-Dist: sphinx-copybutton; extra == "doc"
67
+ Requires-Dist: pydata-sphinx-theme; extra == "doc"
68
+ Provides-Extra: test
69
+ Requires-Dist: pytest; extra == "test"
70
+ Requires-Dist: pytest-xvfb; extra == "test"
71
+ Dynamic: license-file
72
+
73
+ ![DataLab](https://raw.githubusercontent.com/DataLab-Platform/DataLab/main/doc/images/DataLab-banner.png)
74
+
75
+ [![license](https://img.shields.io/pypi/l/datalab-platform.svg)](./LICENSE)
76
+ [![pypi version](https://img.shields.io/pypi/v/datalab-platform.svg)](https://pypi.org/project/datalab-platform/)
77
+ [![PyPI status](https://img.shields.io/pypi/status/datalab-platform.svg)](https://github.com/DataLab-Platform/DataLab)
78
+ [![PyPI pyversions](https://img.shields.io/pypi/pyversions/datalab-platform.svg)](https://pypi.python.org/pypi/datalab-platform/)
79
+
80
+ DataLab is an **open-source platform for scientific and technical data processing
81
+ and visualization** with unique features designed to meet industrial requirements.
82
+
83
+ See [DataLab website](https://datalab-platform.com/) for more details.
84
+
85
+ > **Note:** This project (DataLab Platform) should not be confused with the [datalab-org](https://datalab-org.io/) project, which is a separate and unrelated initiative focused on materials science databases and computational tools.
86
+
87
+ ℹ️ Created by [CODRA](https://codra.net/)/[Pierre Raybaut](https://github.com/PierreRaybaut) in 2023, developed and maintained by DataLab Platform Developers.
88
+
89
+ ![DataLab](https://raw.githubusercontent.com/DataLab-Platform/DataLab/main/doc/images/shots/i_blob_detection_flower.png)
90
+
91
+ 🧮 DataLab's processing power comes from the advanced algorithms of the object-oriented signal and image processing library [Sigima](https://github.com/DataLab-Platform/Sigima) 🚀 which is part of the DataLab Platform.
92
+
93
+ ![Sigima](https://raw.githubusercontent.com/DataLab-Platform/DataLab/main/doc/images/logos/Sigima-Power.png)
94
+
95
+ ℹ️ DataLab is powered by [PlotPyStack](https://github.com/PlotPyStack) 🚀 for curve plotting and fast image visualization.
96
+
97
+ ![PlotPyStack](https://raw.githubusercontent.com/PlotPyStack/.github/main/data/plotpy-stack-powered.png)
98
+
99
+ ℹ️ DataLab is built on Python and scientific libraries.
100
+
101
+ ![Python](https://raw.githubusercontent.com/DataLab-Platform/DataLab/main/doc/images/logos/Python.png) ![NumPy](https://raw.githubusercontent.com/DataLab-Platform/DataLab/main/doc/images/logos/NumPy.png) ![SciPy](https://raw.githubusercontent.com/DataLab-Platform/DataLab/main/doc/images/logos/SciPy.png) ![scikit-image](https://raw.githubusercontent.com/DataLab-Platform/DataLab/main/doc/images/logos/scikit-image.png) ![OpenCV](https://raw.githubusercontent.com/DataLab-Platform/DataLab/main/doc/images/logos/OpenCV.png) ![PlotPyStack](https://raw.githubusercontent.com/DataLab-Platform/DataLab/main/doc/images/logos/plotpystack.png) ![Sigima](https://raw.githubusercontent.com/DataLab-Platform/DataLab/main/doc/images/logos/Sigima.png)
102
+
103
+ ----
104
+
105
+ Try DataLab online, without installing anything, using Binder:
106
+
107
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/DataLab-Platform/DataLab/binder-environments?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252FDataLab-Platform%252FDataLab%26urlpath%3Ddesktop%252F%26branch%3Dbinder-environments)
108
+
109
+ ----
110
+
111
+ ✨ Add features to DataLab by writing your own [plugin](https://datalab-platform.com/en/features/advanced/plugins.html)
112
+ (see [plugin examples](https://github.com/DataLab-Platform/DataLab/tree/main/plugins/examples))
113
+ or macro (see [macro examples](https://github.com/DataLab-Platform/DataLab/tree/main/macros/examples))
114
+
115
+ ✨ DataLab may be remotely controlled from a third-party application (such as Jupyter,
116
+ Spyder or any IDE):
117
+
118
+ * Using the integrated [remote control](https://datalab-platform.com/en/features/advanced/remote.html)
119
+ feature (this requires to install DataLab as a Python package)
120
+
121
+ * Using the lightweight client integrated in [Sigima](https://github.com/DataLab-Platform/Sigima) (`pip install sigima`)