scipion-pyworkflow 3.3.1__tar.gz → 3.5.0__tar.gz

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 (252) hide show
  1. {scipion-pyworkflow-3.3.1/scipion_pyworkflow.egg-info → scipion-pyworkflow-3.5.0}/PKG-INFO +1 -1
  2. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/apps/pw_project.py +3 -8
  3. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/config.py +68 -8
  4. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/constants.py +10 -1
  5. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/browser.py +3 -11
  6. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/canvas.py +1 -1
  7. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/dialog.py +36 -27
  8. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/form.py +9 -97
  9. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/graph_layout.py +39 -28
  10. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/gui.py +36 -13
  11. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/base.py +1 -1
  12. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/project.py +0 -10
  13. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/searchrun.py +19 -12
  14. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/viewdata.py +1 -34
  15. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/viewprotocols.py +47 -110
  16. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/viewprotocols_extra.py +1 -1
  17. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/tree.py +2 -2
  18. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/widgets.py +1 -1
  19. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/object.py +37 -11
  20. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/plugin.py +9 -9
  21. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/__init__.py +1 -1
  22. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/config.py +0 -15
  23. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/project.py +172 -12
  24. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/protocol/executor.py +12 -0
  25. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/protocol/launch.py +32 -25
  26. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/protocol/protocol.py +32 -8
  27. scipion-pyworkflow-3.5.0/pyworkflow/resources/sprites.png +0 -0
  28. scipion-pyworkflow-3.5.0/pyworkflow/resources/sprites.xcf +0 -0
  29. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/template.py +1 -1
  30. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/log.py +2 -2
  31. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/path.py +28 -2
  32. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/properties.py +164 -99
  33. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/utils.py +10 -0
  34. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/viewer.py +7 -1
  35. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/tests/test_object.py +8 -0
  36. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/tests/test_utils.py +74 -4
  37. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0/scipion_pyworkflow.egg-info}/PKG-INFO +1 -1
  38. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/scipion_pyworkflow.egg-info/SOURCES.txt +2 -86
  39. scipion-pyworkflow-3.3.1/pyworkflow/resources/backward-solid.png +0 -0
  40. scipion-pyworkflow-3.3.1/pyworkflow/resources/beta.png +0 -0
  41. scipion-pyworkflow-3.3.1/pyworkflow/resources/binoculares.png +0 -0
  42. scipion-pyworkflow-3.3.1/pyworkflow/resources/bookmark.png +0 -0
  43. scipion-pyworkflow-3.3.1/pyworkflow/resources/broom-solid.png +0 -0
  44. scipion-pyworkflow-3.3.1/pyworkflow/resources/class_obj.png +0 -0
  45. scipion-pyworkflow-3.3.1/pyworkflow/resources/clipboard-regular.png +0 -0
  46. scipion-pyworkflow-3.3.1/pyworkflow/resources/code-branch-solid.png +0 -0
  47. scipion-pyworkflow-3.3.1/pyworkflow/resources/debug.png +0 -0
  48. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-arrow-down.png +0 -0
  49. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-arrow-left.png +0 -0
  50. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-arrow-up.png +0 -0
  51. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-ban.png +0 -0
  52. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-bars.png +0 -0
  53. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-check.png +0 -0
  54. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-checked.png +0 -0
  55. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-cog.png +0 -0
  56. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-cogs.png +0 -0
  57. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-database.png +0 -0
  58. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-delete-operation.png +0 -0
  59. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-download.png +0 -0
  60. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-external-link.png +0 -0
  61. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-eye.png +0 -0
  62. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-failure.png +0 -0
  63. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-file-o.png +0 -0
  64. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-files-o.png +0 -0
  65. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-folder-open.png +0 -0
  66. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-home.png +0 -0
  67. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-install.png +0 -0
  68. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-installed.png +0 -0
  69. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-lightbulb-o.png +0 -0
  70. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-list-ul.png +0 -0
  71. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-magic.png +0 -0
  72. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-minus-square.png +0 -0
  73. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-next.png +0 -0
  74. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-pencil.png +0 -0
  75. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-play-circle-o.png +0 -0
  76. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-plus-square.png +0 -0
  77. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-previous.png +0 -0
  78. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-processing.png +0 -0
  79. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-question-circle.png +0 -0
  80. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-refresh.png +0 -0
  81. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-rocket.png +0 -0
  82. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-save.png +0 -0
  83. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-sign-in.png +0 -0
  84. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-sign-out.png +0 -0
  85. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-sitemap.png +0 -0
  86. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-stop-workflow.png +0 -0
  87. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-stop.png +0 -0
  88. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-tags.png +0 -0
  89. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-times.png +0 -0
  90. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-to_install.png +0 -0
  91. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-trash-o.png +0 -0
  92. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-unchecked.png +0 -0
  93. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-undo.png +0 -0
  94. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-uninstall.png +0 -0
  95. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-update.png +0 -0
  96. scipion-pyworkflow-3.3.1/pyworkflow/resources/fa-upload.png +0 -0
  97. scipion-pyworkflow-3.3.1/pyworkflow/resources/file.png +0 -0
  98. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_folder.png +0 -0
  99. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_folder_link.png +0 -0
  100. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_generic.png +0 -0
  101. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_generic_link.png +0 -0
  102. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_image.png +0 -0
  103. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_image_link.png +0 -0
  104. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_java.png +0 -0
  105. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_log.png +0 -0
  106. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_md.png +0 -0
  107. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_md_link.png +0 -0
  108. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_python.png +0 -0
  109. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_sqlite.png +0 -0
  110. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_stack.png +0 -0
  111. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_stack_link.png +0 -0
  112. scipion-pyworkflow-3.3.1/pyworkflow/resources/file_text.png +0 -0
  113. scipion-pyworkflow-3.3.1/pyworkflow/resources/new.png +0 -0
  114. scipion-pyworkflow-3.3.1/pyworkflow/resources/no-image.png +0 -0
  115. scipion-pyworkflow-3.3.1/pyworkflow/resources/paste-solid.png +0 -0
  116. scipion-pyworkflow-3.3.1/pyworkflow/resources/power-off-solid.png +0 -0
  117. scipion-pyworkflow-3.3.1/pyworkflow/resources/production.png +0 -0
  118. scipion-pyworkflow-3.3.1/pyworkflow/resources/prot_disabled.png +0 -0
  119. scipion-pyworkflow-3.3.1/pyworkflow/resources/question.png +0 -0
  120. scipion-pyworkflow-3.3.1/pyworkflow/resources/rename.png +0 -0
  121. scipion-pyworkflow-3.3.1/pyworkflow/resources/root.png +0 -0
  122. scipion-pyworkflow-3.3.1/pyworkflow/resources/updated.png +0 -0
  123. scipion-pyworkflow-3.3.1/pyworkflow/resources/users.png +0 -0
  124. scipion-pyworkflow-3.3.1/pyworkflow/resources/workflow.png +0 -0
  125. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/LICENSE.txt +0 -0
  126. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/MANIFEST.in +0 -0
  127. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/README.rst +0 -0
  128. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/__init__.py +0 -0
  129. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/apps/__init__.py +0 -0
  130. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/apps/pw_manager.py +0 -0
  131. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/apps/pw_plot.py +0 -0
  132. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/apps/pw_protocol_list.py +0 -0
  133. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/apps/pw_protocol_run.py +0 -0
  134. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/apps/pw_run_tests.py +0 -0
  135. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/apps/pw_schedule_run.py +0 -0
  136. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/apps/pw_sleep.py +0 -0
  137. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/apps/pw_sync_data.py +0 -0
  138. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/apps/pw_viewer.py +0 -0
  139. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/exceptions.py +0 -0
  140. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/__init__.py +0 -0
  141. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/graph.py +0 -0
  142. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/matplotlib_image.py +0 -0
  143. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/plotter.py +0 -0
  144. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/__init__.py +0 -0
  145. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/constants.py +0 -0
  146. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/labels.py +0 -0
  147. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/searchprotocol.py +0 -0
  148. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/steps.py +0 -0
  149. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/utils.py +0 -0
  150. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/project/viewprojects.py +0 -0
  151. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/text.py +0 -0
  152. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/gui/tooltip.py +0 -0
  153. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/mapper/__init__.py +0 -0
  154. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/mapper/mapper.py +0 -0
  155. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/mapper/sqlite.py +0 -0
  156. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/mapper/sqlite_db.py +0 -0
  157. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/mapper/xmlmapper.py +0 -0
  158. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/manager.py +0 -0
  159. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/scripts/clean_projects.py +0 -0
  160. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/scripts/config.py +0 -0
  161. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/scripts/create.py +0 -0
  162. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/scripts/edit_workflow.py +0 -0
  163. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/scripts/fix_links.py +0 -0
  164. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/scripts/load.py +0 -0
  165. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/scripts/refresh.py +0 -0
  166. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/scripts/schedule.py +0 -0
  167. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/scripts/stack2volume.py +0 -0
  168. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/project/scripts/stop.py +0 -0
  169. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/protocol/__init__.py +0 -0
  170. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/protocol/bibtex.py +0 -0
  171. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/protocol/constants.py +0 -0
  172. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/protocol/hosts.py +0 -0
  173. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/protocol/package.py +0 -0
  174. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/protocol/params.py +0 -0
  175. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/Imagej.png +0 -0
  176. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/chimera.png +0 -0
  177. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/fa-exclamation-triangle_alert.png +0 -0
  178. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/fa-info-circle_alert.png +0 -0
  179. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/fa-search.png +0 -0
  180. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/fa-times-circle_alert.png +0 -0
  181. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/file_vol.png +0 -0
  182. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/loading.gif +0 -0
  183. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/no-image128.png +0 -0
  184. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/scipion_bn.png +0 -0
  185. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/scipion_icon.png +0 -0
  186. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/scipion_icon.svg +0 -0
  187. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/scipion_icon_proj.png +0 -0
  188. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/scipion_icon_projs.png +0 -0
  189. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/scipion_icon_prot.png +0 -0
  190. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/scipion_logo.png +0 -0
  191. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/scipion_logo_normal.png +0 -0
  192. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/scipion_logo_small.png +0 -0
  193. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/arrowDown.png +0 -0
  194. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/arrowUp.png +0 -0
  195. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/background_section.png +0 -0
  196. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/colRowModeOff.png +0 -0
  197. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/colRowModeOn.png +0 -0
  198. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/delete.png +0 -0
  199. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/doc_icon.png +0 -0
  200. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/download_icon.png +0 -0
  201. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/enabled_gallery.png +0 -0
  202. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/galleryViewOff.png +0 -0
  203. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/galleryViewOn.png +0 -0
  204. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/goto.png +0 -0
  205. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/menu.png +0 -0
  206. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/separator.png +0 -0
  207. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/tableViewOff.png +0 -0
  208. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/tableViewOn.png +0 -0
  209. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  210. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  211. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  212. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/volumeOff.png +0 -0
  213. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/showj/volumeOn.png +0 -0
  214. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/resources/wait.gif +0 -0
  215. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/tests/__init__.py +0 -0
  216. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/tests/test_utils.py +0 -0
  217. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/tests/tests.py +0 -0
  218. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/__init__.py +0 -0
  219. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/dataset.py +0 -0
  220. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/echo.py +0 -0
  221. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/graph.py +0 -0
  222. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/process.py +0 -0
  223. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/profiler.py +0 -0
  224. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/progressbar.py +0 -0
  225. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/reflection.py +0 -0
  226. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/utils/which.py +0 -0
  227. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/webservices/__init__.py +0 -0
  228. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/webservices/config.py +0 -0
  229. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/webservices/notifier.py +0 -0
  230. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/webservices/repository.py +0 -0
  231. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflow/wizard.py +0 -0
  232. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/__init__.py +0 -0
  233. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/bibtex.py +0 -0
  234. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/objects.py +0 -0
  235. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/protocols.py +0 -0
  236. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/tests/__init__.py +0 -0
  237. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/tests/test_canvas.py +0 -0
  238. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/tests/test_domain.py +0 -0
  239. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/tests/test_logs.py +0 -0
  240. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/tests/test_mappers.py +0 -0
  241. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/tests/test_project.py +0 -0
  242. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/tests/test_protocol_execution.py +0 -0
  243. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/tests/test_protocol_export.py +0 -0
  244. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/tests/test_protocol_output.py +0 -0
  245. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/pyworkflowtests/tests/test_streaming.py +0 -0
  246. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/requirements.txt +0 -0
  247. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/scipion_pyworkflow.egg-info/dependency_links.txt +0 -0
  248. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/scipion_pyworkflow.egg-info/entry_points.txt +0 -0
  249. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/scipion_pyworkflow.egg-info/requires.txt +0 -0
  250. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/scipion_pyworkflow.egg-info/top_level.txt +0 -0
  251. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/setup.cfg +0 -0
  252. {scipion-pyworkflow-3.3.1 → scipion-pyworkflow-3.5.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scipion-pyworkflow
3
- Version: 3.3.1
3
+ Version: 3.5.0
4
4
  Summary: Simple workflow platform used in scientific applications, initially developed within the Scipion framework for image processing in Electron Microscopy.
5
5
  Home-page: https://github.com/scipion-em/scipion-pyworkflow
6
6
  Author: J.M. De la Rosa Trevin, Roberto Marabini, Grigory Sharov, Josue Gomez Blanco, Pablo Conesa, Yunior Fonseca Reyna
@@ -36,19 +36,14 @@ from pyworkflow.project import Manager
36
36
  from pyworkflow.gui.project import ProjectWindow
37
37
  import pyworkflow.utils as pwutils
38
38
 
39
- import logging
40
-
41
39
  HERE = 'here'
42
-
43
40
  LAST = 'last'
44
-
45
41
  LIST = 'list'
46
- logger = logging.getLogger(__name__)
47
42
 
48
43
  def openProject(projectName):
49
44
  """ Opens a scipion project:
50
45
 
51
- :param projectName: Name of a existing project to open,
46
+ :param projectName: Name of an existing project to open,
52
47
  or "here" to create a project in the current working dir,
53
48
  or "last" to open the most recent project
54
49
 
@@ -97,7 +92,7 @@ def openProject(projectName):
97
92
  projWindow = ProjectWindow(projPath)
98
93
  projWindow.show()
99
94
  else:
100
- logger.error("Can't open project %s. It does not exist" % projPath)
95
+ print("Can't open project %s. It does not exist" % projPath)
101
96
 
102
97
  #Show the list of projects
103
98
  showProjectList(manager)
@@ -115,4 +110,4 @@ if __name__ == '__main__':
115
110
  if len(sys.argv) > 1:
116
111
  openProject(sys.argv[1])
117
112
  else:
118
- logger.info("usage: pw_project.py PROJECT_NAME or %s or %s or %s" % (HERE, LAST, LIST))
113
+ print("usage: pw_project.py PROJECT_NAME or %s or %s or %s" % (HERE, LAST, LIST))
@@ -1,4 +1,4 @@
1
-
1
+ import enum
2
2
  import logging
3
3
  logger = logging.getLogger(__file__)
4
4
  import ast
@@ -20,12 +20,15 @@ def join(*paths):
20
20
  return os.path.join(HOME, *paths)
21
21
 
22
22
 
23
- __resourcesPath = [join('resources')]
23
+ __resourcesPath = join('resources')
24
+
25
+ def getResourcesPath(file=None):
24
26
 
27
+ return __resourcesPath if file is None else os.path.join(__resourcesPath, file)
25
28
 
26
29
  def findResource(filename):
27
30
  from .utils.path import findFile
28
- return findFile(filename, *__resourcesPath)
31
+ return findFile(filename, *[__resourcesPath])
29
32
 
30
33
 
31
34
  def genNotesHeading():
@@ -62,6 +65,49 @@ def getModuleFolder(moduleName):
62
65
  spec = importlib.util.find_spec(moduleName)
63
66
  return os.path.dirname(spec.origin)
64
67
 
68
+ class VarTypes(enum.Enum):
69
+ STRING = 1
70
+ INTEGER = 2
71
+ BOOLEAN = 3
72
+ PATH = 4
73
+
74
+ class Variable(object):
75
+ """ Class for variables of the Config class."""
76
+ def __init__(self, value, varType:VarTypes=VarTypes.STRING):
77
+ """
78
+ :param value: Value of the variable
79
+ :param type: Type of the variable"""
80
+ super().__init__()
81
+ self.value = value
82
+ self.varType = varType
83
+ def __bool__(self):
84
+ return bool(self.value)
85
+
86
+ def __int__(self):
87
+ return int(self.value)
88
+ def __str__(self):
89
+ return str(self.value)
90
+
91
+ def __eq__(self, other):
92
+ return other == self.value
93
+
94
+ def __repr__(self):
95
+ return self.__str__()
96
+
97
+ def __fspath__(self):
98
+ return self.__str__()
99
+
100
+ " We migth need to imlement more like this--> https://docs.python.org/3.3/reference/datamodel.html#object.__truediv__"
101
+ def __truediv__(self, other):
102
+ return float(self.value)/other
103
+
104
+ def __rtruediv__(self, other):
105
+ return other / float(self.value)
106
+
107
+ def __add__(self, other):
108
+ return self.value+other
109
+ def __radd__(self, other):
110
+ return other+self.value
65
111
 
66
112
  class Config:
67
113
  """ Main Config for pyworkflow. It contains the main Scipion configuration variables
@@ -104,7 +150,7 @@ class Config:
104
150
  SCIPION_HOME_DEFINED = _get(SCIPION_HOME_VAR, False)
105
151
  "False if SCIPION_HOME is not found in the environment"
106
152
 
107
- _root = Root(SCIPION_HOME)
153
+ _root = Root(str(SCIPION_HOME))
108
154
  _join = _root.join
109
155
 
110
156
  # Internal cached variables, use __ so they are not returned in getVars
@@ -157,8 +203,6 @@ class Config:
157
203
 
158
204
  SCIPION_SUPPORT_EMAIL = _get('SCIPION_SUPPORT_EMAIL', 'scipion@cnb.csic.es')
159
205
 
160
- SCIPION_LOGO = _get('SCIPION_LOGO', 'scipion_logo.gif')
161
-
162
206
  # Config variables
163
207
  SCIPION_CONFIG = _get('SCIPION_CONFIG', 'scipion.conf')
164
208
  "Path to the scipion configuration file where all this variables could be defined."
@@ -209,6 +253,15 @@ class Config:
209
253
  WIZARD_MASK_COLOR = _get('WIZARD_MASK_COLOR', '[0.125, 0.909, 0.972]')
210
254
  "Color to use in some wizards."
211
255
 
256
+ SCIPION_SPRITES_FILE = _get('SCIPION_SPRITES_FILE', _join(getResourcesPath(),'sprites.png'))
257
+ "File (png) with the icons in a collage. Default is found at pyworkflow/resources/sprites.png. And a GIMP file could be found at the same folder in the github repo."
258
+
259
+ SCIPION_SHOW_TEXT_IN_TOOLBAR = _get('SCIPION_SHOW_TEXT_IN_TOOLBAR', TRUE_STR) == TRUE_STR
260
+ "Define it to anything else except False to show the label of the icons. It will take more space."
261
+
262
+ SCIPION_ICON_ZOOM = int(_get('SCIPION_ICON_ZOOM', 50))
263
+ "Define it to anything else except False to show the label of the icons. It will take more space."
264
+
212
265
  # Notification
213
266
  SCIPION_NOTIFY = _get('SCIPION_NOTIFY', TRUE_STR) == TRUE_STR
214
267
  "If set to False, Scipion developers will know almost nothing about Scipion usage and will have less information to improve it."
@@ -249,6 +302,12 @@ class Config:
249
302
  SCIPION_USE_QUEUE = _get("SCIPION_USE_QUEUE", FALSE_STR) != FALSE_STR
250
303
  "Default value for using the queue. By default is False. ANY value will be True except and empty value. \"False\" or \"0\" will be True too."
251
304
 
305
+ SCIPION_DEFAULT_EXECUTION_ACTION = int(_get('SCIPION_DEFAULT_EXECUTION_ACTION', DEFAULT_EXECUTION_ACTION_ASK))
306
+ """Ask if you want to launch a single protocol or a sub-workflow. The default value is 1
307
+ 1: Scipion always ask
308
+ 2: Run a single protocol
309
+ 3: Run a sub-workflow """
310
+
252
311
  try:
253
312
  VIEWERS = ast.literal_eval(_get('VIEWERS', "{}"))
254
313
  except Exception as e:
@@ -300,7 +359,7 @@ class Config:
300
359
  for name, value in vars(baseCls).items():
301
360
  # Skip methods and internal attributes starting with __
302
361
  # (e.g __doc__, __module__, etc)
303
- if (isinstance(value, str) or isinstance(value, int)) and not name.startswith('__'):
362
+ if isinstance(value, (str, int, Variable)) and not name.startswith('__'):
304
363
  configVars[name] = str(value)
305
364
  return configVars
306
365
 
@@ -354,7 +413,8 @@ class Config:
354
413
 
355
414
  @staticmethod
356
415
  def debugSQLOn():
357
- return Config.debugOn()
416
+ from .utils import envVarOn
417
+ return bool(envVarOn(SCIPION_DEBUG_SQLITE))
358
418
 
359
419
  @staticmethod
360
420
  def toggleDebugSQL():
@@ -42,7 +42,7 @@ VERSION_1 = '1.0.0'
42
42
  VERSION_1_1 = '1.1.0'
43
43
  VERSION_1_2 = '1.2.0'
44
44
  VERSION_2_0 = '2.0.0'
45
- VERSION_3_0 = '3.3.1'
45
+ VERSION_3_0 = '3.5.0'
46
46
 
47
47
  # For a new release, define a new constant and assign it to LAST_VERSION
48
48
  # The existing one has to be added to OLD_VERSIONS list.
@@ -198,3 +198,12 @@ class TK:
198
198
  LEFT_DOUBLE_CLICK = '<Double-1>'
199
199
  TREEVIEW_OPEN = '<<TreeviewOpen>>'
200
200
  TREEVIEW_CLOSE = '<<TreeviewClose>>'
201
+
202
+
203
+ HELP_DURATION_FORMAT = "Duration format example: 1d 20h 30m 30s --> 1 day 20 hours 30 minutes and 30 seconds"
204
+
205
+ # Run protocol modes
206
+ DEFAULT_EXECUTION_ACTION_ASK = 1
207
+ DEFAULT_EXECUTION_ACTION_SINGLE = 2
208
+ DEFAULT_EXECUTION_ACTION_ALL = 3
209
+
@@ -34,6 +34,7 @@ import stat
34
34
  import tkinter as tk
35
35
  import time
36
36
  import logging
37
+
37
38
  logger = logging.getLogger(__name__)
38
39
 
39
40
  import pyworkflow.utils as pwutils
@@ -124,7 +125,7 @@ class ObjectBrowser(tk.Frame):
124
125
  img, desc = self.treeProvider.getObjectPreview(obj)
125
126
  # Update image preview
126
127
  if self.showPreviewTop:
127
- if isinstance(img, str):
128
+ if isinstance(img, (str, pwutils.SpriteImage)):
128
129
  img = self.getImage(img)
129
130
  if img is None:
130
131
  img = self.noImage
@@ -716,13 +717,4 @@ class FileBrowserWindow(BrowserWindow):
716
717
  '.txt', '.log', '.out', '.err', '.stdout', '.stderr', '.emx',
717
718
  '.json', '.xml', '.pam')
718
719
  register(TextFileHandler(pwutils.Icon.PYTHON_FILE), '.py')
719
- register(TextFileHandler(pwutils.Icon.JAVA_FILE), '.java')
720
- register(SqlFileHandler(), '.sqlite', '.db')
721
- # register(MdFileHandler(), '.xmd', '.star', '.pos', '.ctfparam', '.doc')
722
- # register(ParticleFileHandler(),
723
- # '.xmp', '.tif', '.tiff', '.spi', '.mrc', '.map', '.raw',
724
- # '.inf', '.dm3', '.em', '.pif', '.psd', '.spe', '.ser', '.img',
725
- # '.hed', *STANDARD_IMAGE_EXTENSIONS)
726
- # register(VolFileHandler(), '.vol')
727
- # register(StackHandler(), '.stk', '.mrcs', '.st', '.pif', '.dm4')
728
- # register(ChimeraHandler(), '.bild')
720
+ register(SqlFileHandler(), '.sqlite', '.db')
@@ -134,7 +134,7 @@ class Canvas(tk.Canvas, Scrollable):
134
134
  return self._runsFont
135
135
 
136
136
  def getImage(self, img):
137
- return gui.getImage(img, self._images)
137
+ return gui.getImage(img)
138
138
 
139
139
  def _unpostMenu(self, e=None):
140
140
  self._menu.unpost()
@@ -34,7 +34,7 @@ from tkcolorpicker import askcolor as _askColor
34
34
  from pyworkflow import Config
35
35
  from pyworkflow.exceptions import PyworkflowException
36
36
  from pyworkflow.utils import Message, Icon, Color
37
- from . import gui, Window, widgets, configureWeigths, LIST_TREEVIEW, defineStyle
37
+ from . import gui, Window, widgets, configureWeigths, LIST_TREEVIEW, defineStyle, ToolTip
38
38
  from .tree import BoundTree, Tree
39
39
  from .text import Text, TaggedText
40
40
 
@@ -58,7 +58,7 @@ class Dialog(tk.Toplevel):
58
58
  An image name can be passed to display left to the message.
59
59
  """
60
60
 
61
- def __init__(self, parent, title, **kwargs):
61
+ def __init__(self, parent, title, lockGui=True, **kwargs):
62
62
  """Initialize a dialog.
63
63
  Arguments:
64
64
  parent -- a parent window (the application window)
@@ -82,7 +82,7 @@ class Dialog(tk.Toplevel):
82
82
  # If the master is not viewable, don't
83
83
  # make the child transient, or else it
84
84
  # would be opened withdrawn
85
- if parent.winfo_viewable():
85
+ if parent.winfo_viewable() and lockGui:
86
86
  self.transient(parent)
87
87
 
88
88
  if title:
@@ -102,7 +102,7 @@ class Dialog(tk.Toplevel):
102
102
  # Frame for the info/message label
103
103
  infoFrame = tk.Frame(self)
104
104
  infoFrame.grid(row=1, column=0, sticky='sew',
105
- padx=5, pady=(0, 5))
105
+ padx=5, pady=(0, 5))
106
106
  self.floatingMessage = tk.Label(infoFrame, text="", fg=Config.SCIPION_MAIN_COLOR)
107
107
  self.floatingMessage.grid(row=0, column=0, sticky='news')
108
108
 
@@ -141,7 +141,8 @@ class Dialog(tk.Toplevel):
141
141
  # window ".139897767953072.139897384058440" was deleted before its visibility changed
142
142
  # wait for window to appear on screen before calling grab_set
143
143
  self.wait_visibility()
144
- self.grab_set()
144
+ if lockGui:
145
+ self.grab_set()
145
146
  self.wait_window(self)
146
147
 
147
148
  def destroy(self):
@@ -191,7 +192,8 @@ class Dialog(tk.Toplevel):
191
192
  self.result = resultValue
192
193
  noCancel = self.result != RESULT_CANCEL and self.result != RESULT_CLOSE
193
194
 
194
- if noCancel and not self.validate():
195
+ callBack = self.validate if noCancel else self.validateClose
196
+ if not callBack():
195
197
  self.initial_focus.focus_set() # put focus back
196
198
  return
197
199
 
@@ -227,6 +229,9 @@ class Dialog(tk.Toplevel):
227
229
  """
228
230
  return 1 # override
229
231
 
232
+ def validateClose(self):
233
+ return True
234
+
230
235
  def apply(self):
231
236
  """process the data
232
237
  This method is called automatically to process the data, *after*
@@ -236,7 +241,7 @@ class Dialog(tk.Toplevel):
236
241
 
237
242
  def getImage(self, imgName):
238
243
  """A shortcut to get an image from its name"""
239
- return gui.getImage(imgName, self._images)
244
+ return gui.getImage(imgName)
240
245
 
241
246
  def getResult(self):
242
247
  return self.result
@@ -328,7 +333,7 @@ class ExceptionDialog(MessageDialog):
328
333
  detailsText = TaggedText(bodyFrame, bg=Config.SCIPION_BG_COLOR, bd=0, highlightthickness=0)
329
334
  traceStr = traceback.format_exc()
330
335
  fillMessageText(detailsText, traceStr)
331
- detailsText.frame.grid(row=row+1, column=0, columnspan=2, sticky='news', padx=5, pady=5)
336
+ detailsText.frame.grid(row=row + 1, column=0, columnspan=2, sticky='news', padx=5, pady=5)
332
337
  event.widget.grid_forget()
333
338
 
334
339
  row = 1
@@ -337,7 +342,7 @@ class ExceptionDialog(MessageDialog):
337
342
  if isinstance(self._exception, PyworkflowException):
338
343
  helpUrl = self._exception.getUrl()
339
344
  labelUrl = TaggedText(bodyFrame, bg=Config.SCIPION_BG_COLOR, bd=0, highlightthickness=0)
340
- fillMessageText(labelUrl,"Please go here for more details: %s" % helpUrl)
345
+ fillMessageText(labelUrl, "Please go here for more details: %s" % helpUrl)
341
346
  labelUrl.grid(row=row, column=0, columnspan=2, sticky='news')
342
347
  row += 1
343
348
 
@@ -621,7 +626,7 @@ class ListDialog(Dialog):
621
626
 
622
627
  def _createPreviewPanel(self, parent):
623
628
  self.previewFrame = tk.Frame(parent)
624
- self.previewFrame.grid(row=1,column=1)
629
+ self.previewFrame.grid(row=1, column=1)
625
630
 
626
631
  def _createFilterBox(self, content):
627
632
  """ Create the Frame with Filter widgets """
@@ -696,11 +701,12 @@ class ToolbarButton:
696
701
  Store information about the buttons that will be added to the toolbar.
697
702
  """
698
703
 
699
- def __init__(self, text, command, icon=None, tooltip=None):
704
+ def __init__(self, text, command, icon=None, tooltip=None, shortcut=None):
700
705
  self.text = text
701
706
  self.command = command
702
707
  self.icon = icon
703
708
  self.tooltip = tooltip
709
+ self.shortcut = shortcut
704
710
 
705
711
 
706
712
  class ToolbarListDialog(ListDialog):
@@ -725,29 +731,36 @@ class ToolbarListDialog(ListDialog):
725
731
  ListDialog.__init__(self, parent, title, provider, message, **kwargs)
726
732
 
727
733
  def body(self, bodyFrame):
728
- bodyFrame.config(bg=Config.SCIPION_BG_COLOR)
729
734
  gui.configureWeigths(bodyFrame, 1, 0)
730
735
 
731
736
  # Add an extra frame to insert the Toolbar
732
737
  # and another one for the ListDialog's body
733
- self.toolbarFrame = tk.Frame(bodyFrame, bg=Config.SCIPION_BG_COLOR)
738
+ self.toolbarFrame = tk.Frame(bodyFrame)
734
739
  self.toolbarFrame.grid(row=0, column=0, sticky='new')
735
- if self.toolbarButtons:
736
- for i, b in enumerate(self.toolbarButtons):
737
- self._addButton(b, i)
738
740
 
739
741
  subBody = tk.Frame(bodyFrame)
740
742
  subBody.grid(row=1, column=0, sticky='news', padx=5, pady=5)
741
743
  ListDialog.body(self, subBody)
744
+
745
+ if self.toolbarButtons:
746
+ for i, b in enumerate(self.toolbarButtons):
747
+ self._addButton(b, i)
748
+
742
749
  if self._itemDoubleClick:
743
750
  self.tree.itemDoubleClick = self._itemDoubleClick
744
751
 
745
752
  def _addButton(self, button, col):
746
753
  btn = tk.Label(self.toolbarFrame, text=button.text,
747
754
  image=self.getImage(button.icon),
748
- compound=tk.LEFT, cursor='hand2', bg=Config.SCIPION_BG_COLOR)
755
+ compound=tk.LEFT, cursor='hand2')
749
756
  btn.grid(row=0, column=col, sticky='nw', padx=(5, 0), pady=(5, 0))
750
757
  btn.bind('<Button-1>', button.command)
758
+ if button.tooltip:
759
+ tooltip = button.tooltip + ' (%s)' % button.shortcut if button.shortcut else button.tooltip
760
+ self.bind(button.shortcut, button.command)
761
+ ToolTip(btn, tooltip, delay=150)
762
+ if button.shortcut:
763
+ self.bind(button.shortcut, button.command)
751
764
 
752
765
 
753
766
  class FlashMessage:
@@ -781,10 +794,9 @@ class FlashMessage:
781
794
  class FloatingMessage:
782
795
  def __init__(self, master, msg, xPos=None, yPos=None, textWidth=280,
783
796
  font='Helvetica', size=12, bd=1, bg=Config.SCIPION_MAIN_COLOR, fg='white'):
784
-
785
797
  if xPos is None:
786
- xPos = (master.winfo_width()-textWidth)/2
787
- yPos = master.winfo_height()/2
798
+ xPos = (master.winfo_width() - textWidth) / 2
799
+ yPos = master.winfo_height() / 2
788
800
 
789
801
  self.floatingMessage = tk.Label(master, text=" %s " % msg,
790
802
  bd=bd, bg=bg, fg=fg)
@@ -839,9 +851,6 @@ class FileBrowseDialog(Dialog):
839
851
  return True
840
852
 
841
853
 
842
-
843
-
844
-
845
854
  class SearchBaseWindow(Window):
846
855
  """ Base window for searching in a list
847
856
  You are going to implement several elements:
@@ -874,7 +883,7 @@ class SearchBaseWindow(Window):
874
883
 
875
884
  def __init__(self, parentWindow, title="Search element", onClick=None, onDoubleClick=None, **kwargs):
876
885
  super().__init__(title=title,
877
- masterWindow=parentWindow)
886
+ masterWindow=parentWindow)
878
887
 
879
888
  self.onClick = self._click if onClick is None else onClick
880
889
  self.onDoubleClick = self._double_click if onDoubleClick is None else onDoubleClick
@@ -905,8 +914,8 @@ class SearchBaseWindow(Window):
905
914
  entry.focus_set()
906
915
  entry.grid(row=0, column=1, sticky='nw')
907
916
  btn = widgets.IconButton(frame, "Search",
908
- imagePath=Icon.ACTION_SEARCH,
909
- command=self._onSearchClick)
917
+ imagePath=Icon.ACTION_SEARCH,
918
+ command=self._onSearchClick)
910
919
  btn.grid(row=0, column=2, sticky='nw')
911
920
 
912
921
  frame.grid(row=0, column=0, sticky='new', padx=5, pady=(10, 5))
@@ -947,7 +956,7 @@ class SearchBaseWindow(Window):
947
956
 
948
957
  if searchtext in linelower[index]:
949
958
  # prioritize findings in label
950
- weight += column[self.WEIGHT_INDEX]*2
959
+ weight += column[self.WEIGHT_INDEX] * 2
951
960
 
952
961
  elif " " in searchtext:
953
962
  for word in searchtext.split():
@@ -464,105 +464,12 @@ class SubclassesTreeProvider(TreeProvider):
464
464
  # Get the classes that are valid as input object in this Domain
465
465
  domain = pw.Config.getDomain()
466
466
  classes = [domain.findClass(c.strip()) for c in className.split(",")]
467
- objects = []
468
-
469
- # Do no refresh again and take the runs that are loaded
470
- # already in the project. We will prefer to save time
471
- # here than have the 'very last' version of the runs and objects
472
- runs = project.getRuns(refresh=False)
473
-
474
- for prot in runs:
475
- # Make sure we don't include previous output of the same
476
- # protocol, it will cause a recursive loop
477
- if prot.getObjId() != self.protocol.getObjId():
478
- # Check if the protocol itself is one of the desired classes
479
- if any(issubclass(prot.getClass(), c) for c in classes):
480
- p = pwobj.Pointer(prot)
481
- objects.append(p)
482
-
483
- try:
484
- # paramName and attr must be set to None
485
- # Otherwise, if a protocol has failed and the corresponding output object of type XX does not exist
486
- # any other protocol that uses objects of type XX as input will not be able to choose then using
487
- # the magnifier glass (object selector of type XX)
488
- paramName = None
489
- attr = None
490
- for paramName, attr in prot.iterOutputAttributes(includePossible=True):
491
- def _checkParam(paramName, attr):
492
- # If attr is a sub-classes of any desired one, add it to the list
493
- # we should also check if there is a condition, the object
494
- # must comply with the condition
495
- p = None
496
-
497
- match = False
498
- cancelConditionEval = False
499
- possibleOutput = isinstance(attr, type)
500
-
501
- # Go through all compatible Classes coming from in pointerClass string
502
- for c in classes:
503
- # If attr is instance
504
- if isinstance(attr, c):
505
- match = True
506
- break
507
- # If it is a class already: "possibleOutput" case. In this case attr is the class and not
508
- # an instance of c. In this special case
509
- elif possibleOutput and attr == c:
510
- match = True
511
- cancelConditionEval = True
512
-
513
- # If attr matches the class
514
- if match:
515
- if cancelConditionEval or not condition or attr.evalCondition(condition):
516
- p = pwobj.Pointer(prot, extended=paramName)
517
- p._allowsSelection = True
518
- objects.append(p)
519
- return
520
-
521
- # JMRT: For all sets, we don't want to include the
522
- # subitems here for performance reasons (e.g SetOfParticles)
523
- # Thus, a Set class can define EXPOSE_ITEMS = True
524
- # to enable the inclusion of its items here
525
- if getattr(attr, 'EXPOSE_ITEMS', False) and not possibleOutput:
526
- # If the ITEM type match any of the desired classes
527
- # we will add some elements from the set
528
- if (attr.ITEM_TYPE is not None and
529
- any(issubclass(attr.ITEM_TYPE, c) for c in classes)):
530
- if p is None: # This means the set have not be added
531
- p = pwobj.Pointer(prot, extended=paramName)
532
- p._allowsSelection = False
533
- objects.append(p)
534
- # Add each item on the set to the list of objects
535
- try:
536
- for i, item in enumerate(attr):
537
- if i == self.maxNum: # Only load up to NUM particles
538
- break
539
- pi = pwobj.Pointer(prot, extended=paramName)
540
- pi.addExtended(item.getObjId())
541
- pi._parentObject = p
542
- objects.append(pi)
543
- except Exception as ex:
544
- print("Error loading items from:")
545
- print(" protocol: %s, attribute: %s"
546
- % (prot.getRunName(), paramName))
547
- print(" dbfile: ",
548
- os.path.join(project.getPath(),
549
- attr.getFileName()))
550
- print(ex)
551
-
552
- _checkParam(paramName, attr)
553
- # The following is a dirty fix for the RCT case where there
554
- # are inner output, maybe we should consider extend this for
555
- # in a more general manner
556
- for subParam in ['_untilted', '_tilted']:
557
- if hasattr(attr, subParam):
558
- _checkParam('%s.%s' % (paramName, subParam),
559
- getattr(attr, subParam))
560
- except Exception as e:
561
- print("Cannot read attributes for %s (%s)" % (prot.getClass(), e))
467
+ # Obtaining only the outputs of the protocols that do not violate the sense of processing,
468
+ # thus avoiding circular references between protocols
469
+ objects = project.getProtocolCompatibleOutputs(self.protocol, classes, condition)
562
470
 
563
471
  # Sort objects before returning them
564
472
  self._sortObjects(objects)
565
-
566
473
  return objects
567
474
 
568
475
  def _sortObjects(self, objects):
@@ -654,7 +561,7 @@ class SubclassesTreeProvider(TreeProvider):
654
561
  viewers = domain.findViewers(obj.getClassName(), DESKTOP_TKINTER)
655
562
  proj = self.protocol.getProject()
656
563
  for v in viewers:
657
- actions.append(('Open with %s' % v.__name__,
564
+ actions.append((v.getName(),
658
565
  lambda: v(project=proj).visualize(obj)))
659
566
  return actions
660
567
 
@@ -2242,6 +2149,11 @@ class FormWindow(Window):
2242
2149
  errors, resultAction = ProtocolsView._launchSubWorkflow(self.protocol,
2243
2150
  mode, self.root,
2244
2151
  askSingleAll=True)
2152
+
2153
+ if errors:
2154
+ self.showInfo(errors)
2155
+ return
2156
+
2245
2157
  if resultAction == RESULT_CANCEL:
2246
2158
  return
2247
2159
  elif resultAction == RESULT_RUN_ALL:
@@ -88,9 +88,10 @@ class LevelTreeLayout(GraphLayout):
88
88
  # Setup empty layout for each node
89
89
  for node in graph.getNodes():
90
90
  node._layout = {}
91
-
91
+
92
+ visitDict = dict()
92
93
  # Do some level initialization on each node
93
- self._setLayoutLevel(rootNode, 1, None)
94
+ self._setLayoutLevel(rootNode, 1, None, visitDict)
94
95
  self._computeNodeOffsets(rootNode, 1)
95
96
  # Compute extreme left limit
96
97
  m = 9999
@@ -106,36 +107,46 @@ class LevelTreeLayout(GraphLayout):
106
107
  def _isNewNode(self, node):
107
108
  return node.x == 0 or node.y == 0 or node.isRoot()
108
109
 
109
- def _setLayoutLevel(self, node, level, parent):
110
+ def _setLayoutLevel(self, node, level, parent, visitDict=None, ancestors=[]):
110
111
  """ Iterate over all nodes and set _layout dict.
111
112
  Also set the node level, which is defined
112
113
  as the max level of a parent + 1
113
114
  """
114
- if level > self.maxLevel:
115
- return
116
-
117
- layout = node._layout
118
-
119
- if level > layout.get('level', 0):
120
- # Calculate the y-position depending on the level
121
- # and the delta-Y (DY)
122
- if not self.partial or self._isNewNode(node):
123
- node.y = level * self.getY()
124
- layout['level'] = level
125
- layout['parent'] = parent
126
- if hasattr(node, 'width'):
127
- half = node.width / 2
128
- else:
129
- half = 50
130
- layout['half'] = half
131
- layout['hLimits'] = [[-half, half]]
132
- layout['offset'] = 0
133
-
134
- if self.__isNodeExpanded(node):
135
- for child in node.getChilds():
136
- if Config.debugOn():
137
- print("%s: Setting layout for child %s" % ("-" * level, child), flush=True)
138
- self._setLayoutLevel(child, level+1, node)
115
+ if visitDict is None:
116
+ visitDict = {}
117
+
118
+ if node.getName() not in visitDict:
119
+ visitDict[node.getName()] = True
120
+
121
+ if level > self.maxLevel:
122
+ return
123
+
124
+ layout = node._layout
125
+
126
+ if level > layout.get('level', 0):
127
+ # Calculate the y-position depending on the level
128
+ # and the delta-Y (DY)
129
+ if not self.partial or self._isNewNode(node):
130
+ node.y = level * self.getY()
131
+ layout['level'] = level
132
+ layout['parent'] = parent
133
+ if hasattr(node, 'width'):
134
+ half = node.width / 2
135
+ else:
136
+ half = 50
137
+ layout['half'] = half
138
+ layout['hLimits'] = [[-half, half]]
139
+ layout['offset'] = 0
140
+
141
+ if self.__isNodeExpanded(node):
142
+ ancestors.append(node.getName())
143
+ for child in node.getChilds():
144
+ if child.getName() in ancestors:
145
+ logger.warning("WARNING: There might be a cyclic redundancy error in this protocol: %s (%s)" %(child.getLabel(),
146
+ child.getName()))
147
+ if Config.debugOn():
148
+ print("%s: Setting layout for child %s" % ("-" * level, child), flush=True)
149
+ self._setLayoutLevel(child, level+1, node, visitDict, ancestors.copy())
139
150
 
140
151
  def __isNodeExpanded(self, node):
141
152
  """ Check if the status of the node is expanded or collapsed. """