shinestacker 1.0.1__tar.gz → 1.0.3__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.

Potentially problematic release.


This version of shinestacker might be problematic. Click here for more details.

Files changed (136) hide show
  1. {shinestacker-1.0.1 → shinestacker-1.0.3}/CHANGELOG.md +36 -0
  2. {shinestacker-1.0.1/src/shinestacker.egg-info → shinestacker-1.0.3}/PKG-INFO +2 -1
  3. {shinestacker-1.0.1 → shinestacker-1.0.3}/README.md +1 -0
  4. shinestacker-1.0.3/src/shinestacker/_version.py +1 -0
  5. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/multilayer.py +2 -2
  6. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/stack_framework.py +1 -1
  7. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/gui_run.py +2 -2
  8. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/main_window.py +9 -6
  9. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/project_controller.py +8 -6
  10. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/image_editor_ui.py +1 -2
  11. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/io_gui_handler.py +8 -5
  12. {shinestacker-1.0.1 → shinestacker-1.0.3/src/shinestacker.egg-info}/PKG-INFO +2 -1
  13. shinestacker-1.0.1/src/shinestacker/_version.py +0 -1
  14. {shinestacker-1.0.1 → shinestacker-1.0.3}/.coveragerc +0 -0
  15. {shinestacker-1.0.1 → shinestacker-1.0.3}/.flake8 +0 -0
  16. {shinestacker-1.0.1 → shinestacker-1.0.3}/.github/workflows/ci-multiplatform.yml +0 -0
  17. {shinestacker-1.0.1 → shinestacker-1.0.3}/.github/workflows/pylint.yml +0 -0
  18. {shinestacker-1.0.1 → shinestacker-1.0.3}/.github/workflows/pypi-publish.yml +0 -0
  19. {shinestacker-1.0.1 → shinestacker-1.0.3}/.github/workflows/release.yml +0 -0
  20. {shinestacker-1.0.1 → shinestacker-1.0.3}/.gitignore +0 -0
  21. {shinestacker-1.0.1 → shinestacker-1.0.3}/.pylintrc +0 -0
  22. {shinestacker-1.0.1 → shinestacker-1.0.3}/.readthedocs.yaml +0 -0
  23. {shinestacker-1.0.1 → shinestacker-1.0.3}/LICENSE +0 -0
  24. {shinestacker-1.0.1 → shinestacker-1.0.3}/MANIFEST.in +0 -0
  25. {shinestacker-1.0.1 → shinestacker-1.0.3}/THIRD_PARTY_LICENSES.txt +0 -0
  26. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/alignment.md +0 -0
  27. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/api.md +0 -0
  28. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/balancing.md +0 -0
  29. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/conf.py +0 -0
  30. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/focus_stacking.md +0 -0
  31. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/gui.md +0 -0
  32. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/index.md +0 -0
  33. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/job.md +0 -0
  34. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/main.md +0 -0
  35. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/multilayer.md +0 -0
  36. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/noise.md +0 -0
  37. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/requirements.txt +0 -0
  38. {shinestacker-1.0.1 → shinestacker-1.0.3}/docs/vignetting.md +0 -0
  39. {shinestacker-1.0.1 → shinestacker-1.0.3}/img/coffee.gif +0 -0
  40. {shinestacker-1.0.1 → shinestacker-1.0.3}/img/coffee_stack.jpg +0 -0
  41. {shinestacker-1.0.1 → shinestacker-1.0.3}/img/extreme-vignetting.jpg +0 -0
  42. {shinestacker-1.0.1 → shinestacker-1.0.3}/img/flies.gif +0 -0
  43. {shinestacker-1.0.1 → shinestacker-1.0.3}/img/flies_stack.jpg +0 -0
  44. {shinestacker-1.0.1 → shinestacker-1.0.3}/img/flow-diagram.png +0 -0
  45. {shinestacker-1.0.1 → shinestacker-1.0.3}/img/gui-finder.png +0 -0
  46. {shinestacker-1.0.1 → shinestacker-1.0.3}/img/gui-project-new.png +0 -0
  47. {shinestacker-1.0.1 → shinestacker-1.0.3}/img/gui-project-run.png +0 -0
  48. {shinestacker-1.0.1 → shinestacker-1.0.3}/img/gui-retouch.png +0 -0
  49. {shinestacker-1.0.1 → shinestacker-1.0.3}/pyproject.toml +0 -0
  50. {shinestacker-1.0.1 → shinestacker-1.0.3}/requirements.txt +0 -0
  51. {shinestacker-1.0.1 → shinestacker-1.0.3}/scripts/build_release.py +0 -0
  52. {shinestacker-1.0.1 → shinestacker-1.0.3}/scripts/git-rev-list.sh +0 -0
  53. {shinestacker-1.0.1 → shinestacker-1.0.3}/scripts/validate-tomli.py +0 -0
  54. {shinestacker-1.0.1 → shinestacker-1.0.3}/setup.cfg +0 -0
  55. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/__init__.py +0 -0
  56. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/__init__.py +0 -0
  57. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/align.py +0 -0
  58. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/balance.py +0 -0
  59. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/base_stack_algo.py +0 -0
  60. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/denoise.py +0 -0
  61. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/depth_map.py +0 -0
  62. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/exif.py +0 -0
  63. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/noise_detection.py +0 -0
  64. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/pyramid.py +0 -0
  65. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/sharpen.py +0 -0
  66. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/stack.py +0 -0
  67. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/utils.py +0 -0
  68. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/vignetting.py +0 -0
  69. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/algorithms/white_balance.py +0 -0
  70. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/app/__init__.py +0 -0
  71. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/app/about_dialog.py +0 -0
  72. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/app/gui_utils.py +0 -0
  73. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/app/help_menu.py +0 -0
  74. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/app/main.py +0 -0
  75. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/app/open_frames.py +0 -0
  76. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/app/project.py +0 -0
  77. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/app/retouch.py +0 -0
  78. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/config/__init__.py +0 -0
  79. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/config/config.py +0 -0
  80. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/config/constants.py +0 -0
  81. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/config/gui_constants.py +0 -0
  82. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/core/__init__.py +0 -0
  83. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/core/colors.py +0 -0
  84. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/core/core_utils.py +0 -0
  85. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/core/exceptions.py +0 -0
  86. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/core/framework.py +0 -0
  87. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/core/logging.py +0 -0
  88. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/__init__.py +0 -0
  89. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/action_config.py +0 -0
  90. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/action_config_dialog.py +0 -0
  91. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/base_form_dialog.py +0 -0
  92. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/colors.py +0 -0
  93. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/gui_images.py +0 -0
  94. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/gui_logging.py +0 -0
  95. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/ico/focus_stack_bkg.png +0 -0
  96. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/ico/shinestacker.icns +0 -0
  97. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/ico/shinestacker.ico +0 -0
  98. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/ico/shinestacker.png +0 -0
  99. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/ico/shinestacker.svg +0 -0
  100. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/img/close-round-line-icon.png +0 -0
  101. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/img/forward-button-icon.png +0 -0
  102. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/img/play-button-round-icon.png +0 -0
  103. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/img/plus-round-line-icon.png +0 -0
  104. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/menu_manager.py +0 -0
  105. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/new_project.py +0 -0
  106. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/project_converter.py +0 -0
  107. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/project_editor.py +0 -0
  108. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/project_model.py +0 -0
  109. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/select_path_widget.py +0 -0
  110. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/tab_widget.py +0 -0
  111. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/gui/time_progress_bar.py +0 -0
  112. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/__init__.py +0 -0
  113. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/base_filter.py +0 -0
  114. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/brush.py +0 -0
  115. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/brush_gradient.py +0 -0
  116. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/brush_preview.py +0 -0
  117. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/brush_tool.py +0 -0
  118. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/denoise_filter.py +0 -0
  119. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/display_manager.py +0 -0
  120. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/exif_data.py +0 -0
  121. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/file_loader.py +0 -0
  122. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/filter_manager.py +0 -0
  123. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/icon_container.py +0 -0
  124. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/image_viewer.py +0 -0
  125. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/io_manager.py +0 -0
  126. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/layer_collection.py +0 -0
  127. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/shortcuts_help.py +0 -0
  128. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/undo_manager.py +0 -0
  129. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/unsharp_mask_filter.py +0 -0
  130. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/vignetting_filter.py +0 -0
  131. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker/retouch/white_balance_filter.py +0 -0
  132. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker.egg-info/SOURCES.txt +0 -0
  133. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker.egg-info/dependency_links.txt +0 -0
  134. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker.egg-info/entry_points.txt +0 -0
  135. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker.egg-info/requires.txt +0 -0
  136. {shinestacker-1.0.1 → shinestacker-1.0.3}/src/shinestacker.egg-info/top_level.txt +0 -0
@@ -2,6 +2,38 @@
2
2
 
3
3
  This page reports the main releases only and the main changes therein.
4
4
 
5
+ ## [v1.0.3] - 2025-08-26
6
+ **Bug fixes**
7
+
8
+ ### Changes
9
+
10
+ * fixed menu text
11
+ * fixed crash multilayer module
12
+ * fixed multilayer module
13
+ * code cleanup
14
+
15
+ ---
16
+
17
+ ## [v1.0.2] - 2025-08-25
18
+ **Bug fixes**
19
+
20
+ ### Changes
21
+
22
+ * fixed context menu
23
+ * fixed retouch callback for shiestacker-project app
24
+ * fixed double image loading
25
+
26
+ ---
27
+
28
+ ## [v1.0.1] - 2025-08-25
29
+ **First stable release**
30
+
31
+ ### Changes
32
+
33
+ * added source file missing by mistake in v1.0.0
34
+
35
+ ---
36
+
5
37
  ## [v1.0.0] - 2025-08-25
6
38
  **First stable release**
7
39
 
@@ -17,6 +49,10 @@ This page reports the main releases only and the main changes therein.
17
49
  * code refactoring and various cleanup
18
50
  * bug fixes
19
51
 
52
+ Note
53
+
54
+ A source file was missing in this tag, and was added in v1.0.1
55
+
20
56
  ---
21
57
 
22
58
  ## [v0.5.0] - 2025-08-20
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shinestacker
3
- Version: 1.0.1
3
+ Version: 1.0.3
4
4
  Summary: ShineStacker
5
5
  Author-email: Luca Lista <luka.lista@gmail.com>
6
6
  License-Expression: LGPL-3.0
@@ -87,6 +87,7 @@ Pyramid methods in image processing
87
87
  # License
88
88
 
89
89
  <img src="https://www.gnu.org/graphics/lgplv3-147x51.png" alt="LGPL 3 logo">
90
+
90
91
  - **Code**: The software is provided as is under the [GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.en.html). See [LICENSE](https://github.com/lucalista/shinestacker/blob/main/LICENSE) for details.
91
92
  <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/src/shinestacker/gui/ico/shinestacker.png' width="150" referrerpolicy="no-referrer" alt="Shine Stacker Logo">
92
93
 
@@ -56,6 +56,7 @@ Pyramid methods in image processing
56
56
  # License
57
57
 
58
58
  <img src="https://www.gnu.org/graphics/lgplv3-147x51.png" alt="LGPL 3 logo">
59
+
59
60
  - **Code**: The software is provided as is under the [GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.en.html). See [LICENSE](https://github.com/lucalista/shinestacker/blob/main/LICENSE) for details.
60
61
  <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/src/shinestacker/gui/ico/shinestacker.png' width="150" referrerpolicy="no-referrer" alt="Shine Stacker Logo">
61
62
 
@@ -0,0 +1 @@
1
+ __version__ = '1.0.3'
@@ -177,7 +177,7 @@ class MultiLayer(JobBase, FrameMultiDirectory):
177
177
  raise RuntimeError("input_path option must contain a path or an array of paths")
178
178
  if len(paths) == 0:
179
179
  self.print_message(color_str("no input paths specified",
180
- constants.LOG_COLOR_LEVEL_ALERT),
180
+ constants.LOG_COLOR_ALERT),
181
181
  level=logging.WARNING)
182
182
  return
183
183
  files = self.folder_filelist()
@@ -186,7 +186,7 @@ class MultiLayer(JobBase, FrameMultiDirectory):
186
186
  color_str(f"no input in {len(paths)} specified path" +
187
187
  ('s' if len(paths) > 1 else '') + ": "
188
188
  ", ".join([f"'{p}'" for p in paths]),
189
- constants.LOG_COLOR_LEVEL_ALERT),
189
+ constants.LOG_COLOR_ALERT),
190
190
  level=logging.WARNING)
191
191
  return
192
192
  self.print_message(color_str("merging frames in " + self.folder_list_str(),
@@ -92,7 +92,7 @@ class FramePaths:
92
92
  ('' if self.working_path[-1] == '/' else '/') + self.plot_path
93
93
  if not os.path.exists(self.plot_path):
94
94
  os.makedirs(self.plot_path)
95
- if self.input_path == '':
95
+ if self.input_path in ['', []]:
96
96
  if len(job.paths) == 0:
97
97
  raise RuntimeError(f"Job {job.name} does not have any configured path")
98
98
  self.input_path = job.paths[-1]
@@ -133,11 +133,11 @@ class RunWindow(QTextEditLogger):
133
133
  def find_parent(widget, class_name):
134
134
  current = widget
135
135
  while current is not None:
136
- if current.__class__.__name__ == class_name:
136
+ if current.objectName() == class_name:
137
137
  return current
138
138
  current = current.parent()
139
139
  return None
140
- parent = find_parent(self, "MainWindow")
140
+ parent = find_parent(self, "mainWindow")
141
141
  if parent:
142
142
  parent.retouch_callback(path[1])
143
143
  else:
@@ -52,6 +52,7 @@ class MainWindow(QMainWindow, LogManager):
52
52
  def __init__(self):
53
53
  QMainWindow.__init__(self)
54
54
  LogManager.__init__(self)
55
+ self.setObjectName("mainWindow")
55
56
  self.project_controller = ProjectController(self)
56
57
  self.project_editor = self.project_controller.project_editor
57
58
  actions = {
@@ -139,6 +140,8 @@ class MainWindow(QMainWindow, LogManager):
139
140
  self.project_controller.activate_window_requested.connect(self.activateWindow)
140
141
  self.project_controller.enable_save_actions_requested.connect(
141
142
  self.menu_manager.save_actions_set_enabled)
143
+ self.project_controller.enable_sub_actions_requested.connect(
144
+ self.menu_manager.set_enabled_sub_actions_gui)
142
145
 
143
146
  def modified(self):
144
147
  return self.project_editor.modified()
@@ -275,7 +278,7 @@ class MainWindow(QMainWindow, LogManager):
275
278
  current_action = None
276
279
  if item:
277
280
  index = self.job_list().row(item)
278
- current_action = self.get_job_at(index)
281
+ current_action = self.project_editor.get_job_at(index)
279
282
  self.set_current_job(index)
280
283
  item = self.action_list().itemAt(self.action_list().viewport().mapFrom(self, event.pos()))
281
284
  if item:
@@ -286,9 +289,9 @@ class MainWindow(QMainWindow, LogManager):
286
289
  if current_action:
287
290
  menu = QMenu(self)
288
291
  if current_action.enabled():
289
- menu.addAction(self.disable_action)
292
+ menu.addAction(self.menu_manager.disable_action)
290
293
  else:
291
- menu.addAction(self.enable_action)
294
+ menu.addAction(self.menu_manager.enable_action)
292
295
  edit_config_action = QAction("Edit configuration")
293
296
  edit_config_action.triggered.connect(self.edit_current_action)
294
297
  menu.addAction(edit_config_action)
@@ -325,15 +328,15 @@ class MainWindow(QMainWindow, LogManager):
325
328
  self.current_action_output_path = f"{self.current_action_working_path}/{op}"
326
329
  if os.path.exists(self.current_action_output_path):
327
330
  action_name = "Browse Output Path" + (f" > {name}" if name != '' else '')
328
- n_files = len(next(os.walk(op))[2])
331
+ n_files = len(next(os.walk(self.current_action_output_path))[2])
329
332
  s = "" if n_files == 1 else "s"
330
333
  action_name += f" ({n_files} file{s})"
331
334
  self.browse_output_path_action = QAction(action_name)
332
335
  self.browse_output_path_action.triggered.connect(self.browse_output_path)
333
336
  menu.addAction(self.browse_output_path_action)
334
337
  menu.addSeparator()
335
- menu.addAction(self.run_job_action)
336
- menu.addAction(self.run_all_jobs_action)
338
+ menu.addAction(self.menu_manager.run_job_action)
339
+ menu.addAction(self.menu_manager.run_all_jobs_action)
337
340
  if current_action.type_name == constants.ACTION_JOB:
338
341
  retouch_path = self.get_retouch_path(current_action)
339
342
  if len(retouch_path) > 0:
@@ -19,6 +19,7 @@ class ProjectController(QObject):
19
19
  refresh_ui_requested = Signal(int, int)
20
20
  activate_window_requested = Signal()
21
21
  enable_save_actions_requested = Signal(bool)
22
+ enable_sub_actions_requested = Signal(bool)
22
23
 
23
24
  def __init__(self, parent):
24
25
  super().__init__(parent)
@@ -203,11 +204,12 @@ class ProjectController(QObject):
203
204
  input_path.append("focus-stack-depth-map")
204
205
  if dialog.get_bunch_stack():
205
206
  input_path.append("bunches")
206
- else:
207
- input_path.append(input_path)
208
- multi_layer = ActionConfig(constants.ACTION_MULTILAYER,
209
- {'name': 'multi-layer',
210
- 'input_path': ','.join(input_path)})
207
+ multi_layer = ActionConfig(
208
+ constants.ACTION_MULTILAYER,
209
+ {
210
+ 'name': 'multi-layer',
211
+ 'input_path': constants.PATH_SEPARATOR.join(input_path)
212
+ })
211
213
  job.add_sub_action(multi_layer)
212
214
  self.add_job_to_project(job)
213
215
  self.mark_as_modified(True)
@@ -323,7 +325,7 @@ class ProjectController(QObject):
323
325
  current_action, is_sub_action = self.get_current_action_at(job, action_index)
324
326
  if current_action:
325
327
  if not is_sub_action:
326
- self.set_enabled_sub_actions_gui(
328
+ self.enable_sub_actions_requested.emit(
327
329
  current_action.type_name == constants.ACTION_COMBO)
328
330
  dialog = self.action_config_dialog(current_action)
329
331
  if dialog.exec() == QDialog.Accepted:
@@ -330,9 +330,8 @@ class ImageEditorUI(QMainWindow, LayerCollectionHandler):
330
330
  view_individual_action.setShortcut("L")
331
331
  view_individual_action.triggered.connect(self.set_view_individual)
332
332
  view_menu.addAction(view_individual_action)
333
- view_menu.addSeparator()
334
333
 
335
- toggle_view_master_individual_action = QAction("View Individual", self)
334
+ toggle_view_master_individual_action = QAction("Toggle Master/Individual", self)
336
335
  toggle_view_master_individual_action.setShortcut("T")
337
336
  toggle_view_master_individual_action.triggered.connect(self.toggle_view_master_individual)
338
337
  view_menu.addAction(toggle_view_master_individual_action)
@@ -56,8 +56,9 @@ class IOGuiHandler(QObject, LayerCollectionHandler):
56
56
  self.set_master_layer(master_layer)
57
57
  self.undo_manager.reset()
58
58
  self.blank_layer = np.zeros(master_layer.shape[:2])
59
- self.finish_loading_setup(stack, None, master_layer,
60
- f"Loaded: {self.current_file_path()}")
59
+ self.finish_loading_setup(
60
+ stack, None, master_layer,
61
+ f"Loaded: {self.current_file_path()}")
61
62
 
62
63
  def on_file_error(self, error_msg):
63
64
  QApplication.restoreOverrideCursor()
@@ -136,9 +137,6 @@ class IOGuiHandler(QObject, LayerCollectionHandler):
136
137
  msg.setText(str(e))
137
138
  msg.exec()
138
139
  return
139
- self.finish_loading_setup(stack, labels, master, "Selected frames imported")
140
-
141
- def finish_loading_setup(self, stack, labels, master, message):
142
140
  if self.layer_stack() is None and len(stack) > 0:
143
141
  self.set_layer_stack(np.array(stack))
144
142
  if labels is None:
@@ -153,6 +151,11 @@ class IOGuiHandler(QObject, LayerCollectionHandler):
153
151
  for img, label in zip(stack, labels):
154
152
  self.add_layer_label(label)
155
153
  self.add_layer(img)
154
+ self.finish_loading_setup(
155
+ stack, labels, master,
156
+ "Selected frames imported")
157
+
158
+ def finish_loading_setup(self, stack, labels, master, message):
156
159
  self.display_manager.update_thumbnails()
157
160
  self.mark_as_modified_requested.emit(True)
158
161
  self.change_layer_requested.emit(0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shinestacker
3
- Version: 1.0.1
3
+ Version: 1.0.3
4
4
  Summary: ShineStacker
5
5
  Author-email: Luca Lista <luka.lista@gmail.com>
6
6
  License-Expression: LGPL-3.0
@@ -87,6 +87,7 @@ Pyramid methods in image processing
87
87
  # License
88
88
 
89
89
  <img src="https://www.gnu.org/graphics/lgplv3-147x51.png" alt="LGPL 3 logo">
90
+
90
91
  - **Code**: The software is provided as is under the [GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.en.html). See [LICENSE](https://github.com/lucalista/shinestacker/blob/main/LICENSE) for details.
91
92
  <img src='https://raw.githubusercontent.com/lucalista/shinestacker/main/src/shinestacker/gui/ico/shinestacker.png' width="150" referrerpolicy="no-referrer" alt="Shine Stacker Logo">
92
93
 
@@ -1 +0,0 @@
1
- __version__ = '1.0.1'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes