shinestacker 1.0.1__py3-none-any.whl → 1.0.3__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.

Potentially problematic release.


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

shinestacker/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '1.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,5 +1,5 @@
1
1
  shinestacker/__init__.py,sha256=uq2fjAw2z_6TpH3mOcWFZ98GoEPRsNhTAK8N0MMm_e8,448
2
- shinestacker/_version.py,sha256=bMIenWosteoeUs51RbaWVZetIuzRhWymuyy-n0rfK0I,21
2
+ shinestacker/_version.py,sha256=MpVHFFoITiYyPltTb_qFrdeX2entdTm4x0PczXi3txY,21
3
3
  shinestacker/algorithms/__init__.py,sha256=c4kRrdTLlVI70Q16XkI1RSmz5MD7npDqIpO_02jTG6g,747
4
4
  shinestacker/algorithms/align.py,sha256=XT4DJoD5ZvpkC1-J3W3GWmWRsXJg3qJ-3zr9erT8oW0,17514
5
5
  shinestacker/algorithms/balance.py,sha256=iSjO-pl0vQv58iEQ077EUcDTAExMKDBdtXmJXbMhazk,16721
@@ -7,12 +7,12 @@ shinestacker/algorithms/base_stack_algo.py,sha256=AFV2QkcFNaTcnISpsWHuAVy2De9hha
7
7
  shinestacker/algorithms/denoise.py,sha256=GL3Z4_6MHxSa7Wo4ZzQECZS87tHBFqO0sIVF_jPuYQU,426
8
8
  shinestacker/algorithms/depth_map.py,sha256=FOR5M0brO5-9NnXDY7TWpc3OtKKSuzrOSoBMe0cP6Ho,6076
9
9
  shinestacker/algorithms/exif.py,sha256=gY9s6Cd4g4swo5qEjSbzuVIvl1GImCYu6ytOO9WrV0I,9435
10
- shinestacker/algorithms/multilayer.py,sha256=5JA6TW8oO_R3mu6cOvPno9by4md8q5sXUb8ZfsRRpmY,9259
10
+ shinestacker/algorithms/multilayer.py,sha256=MJqU_9LpcCi-0quJNszaFHOqna68ZqmImZQ50njOBio,9247
11
11
  shinestacker/algorithms/noise_detection.py,sha256=CDnN8pglxufY5Y-dT3mVooD4zPySdSq9CMgtDGMXBnA,8970
12
12
  shinestacker/algorithms/pyramid.py,sha256=_Pk19lRQ21b3W3aHQ6DgAe9VVOfbsi2a9jrynF0qFVw,8610
13
13
  shinestacker/algorithms/sharpen.py,sha256=h7PMJBYxucg194Usp_6pvItPUMFYbT-ebAc_-7XBFUw,949
14
14
  shinestacker/algorithms/stack.py,sha256=FCU89Of-s6C_DuMleG06c8V6fnIm9MFInvkkKtTsGBo,4906
15
- shinestacker/algorithms/stack_framework.py,sha256=frw7sbc9qOfVBYP3ZOFZEaIn9O27Wms8j_mxSW79uI0,12460
15
+ shinestacker/algorithms/stack_framework.py,sha256=peAlUUl7y8OcquhjQoXpiwsEhZw6zgZnzwt1IDpf4aU,12466
16
16
  shinestacker/algorithms/utils.py,sha256=2XFa16Q8JVq4C2iXZFOvv98GVKqxceFG73yFZNHJSqI,2475
17
17
  shinestacker/algorithms/vignetting.py,sha256=yW-1TF4tesLWfKQOS0XxRkOEN82U-YDmMaj09C9cH4M,9552
18
18
  shinestacker/algorithms/white_balance.py,sha256=PMKsBtxOSn5aRr_Gkx1StHS4eN6kBN2EhNnhg4UG24g,501
@@ -41,11 +41,11 @@ shinestacker/gui/base_form_dialog.py,sha256=yYqMee1mzw9VBx8siBS0jDk1qqsTIKJUgdjh
41
41
  shinestacker/gui/colors.py,sha256=m0pQQ-uvtIN1xmb_-N06BvC7pZYZZnq59ZSEJwutHuk,1432
42
42
  shinestacker/gui/gui_images.py,sha256=e0KAXSPruZoRHrajfdlmOKBYoRJJQBDan1jgs7YFltY,5678
43
43
  shinestacker/gui/gui_logging.py,sha256=kiZcrC2AFYCWgPZo0O5SKw-E5cFrezwf4anS3HjPuNw,8168
44
- shinestacker/gui/gui_run.py,sha256=jGrtXNT3Gn53qMPSU74aEY6PP7UQfc85SD3XIesWLuY,15147
45
- shinestacker/gui/main_window.py,sha256=6zGFZkgBh3_UNWjCfNzciPeiCvBsZnjJiPy62U4ldAw,23988
44
+ shinestacker/gui/gui_run.py,sha256=G9jKIMCEdrCwRvicRykY0r_x2Vya-9EMn4HpZL8ydRI,15141
45
+ shinestacker/gui/main_window.py,sha256=l5iMk5aIi5nXPccnibB1tswc0agatrYgXULVkXo7OV0,24254
46
46
  shinestacker/gui/menu_manager.py,sha256=_L6LOikB3impEYqilqwXc0WJuunishjz57ozZlrBn7Q,9616
47
47
  shinestacker/gui/new_project.py,sha256=zHmGrT27L7I6YHM1L8wjt7DzukLFPddFsbVyGVHfJoc,11004
48
- shinestacker/gui/project_controller.py,sha256=jjM8JuPlIsQohmiqzuV1EndGVvqO4tOEdoMEUJ37SNU,15049
48
+ shinestacker/gui/project_controller.py,sha256=QJSQlwEJeXJyJnkp42D9NSqWBb8q2kLf_GvLfe3pe_c,15076
49
49
  shinestacker/gui/project_converter.py,sha256=_AFfU2HYKPX78l6iX6bXJrlKpdjSl63pmKzrc6kQpn8,7348
50
50
  shinestacker/gui/project_editor.py,sha256=uouzmUkrqouQlq-dqPOgSO16r1WOnGNV2v8jTcZlRXU,23749
51
51
  shinestacker/gui/project_model.py,sha256=eRUmH3QmRzDtPtZoxgT6amKzN8_5XzwjHgEJeL-_JOE,4263
@@ -73,9 +73,9 @@ shinestacker/retouch/exif_data.py,sha256=giqoIaMlhN6H3x8BAd73ghVHODmWIcD_QbSoDym
73
73
  shinestacker/retouch/file_loader.py,sha256=x8lzKShlgElcJYLFiDoeszeVEToUUiUbUrozAeF5SMU,4812
74
74
  shinestacker/retouch/filter_manager.py,sha256=SdYIZkZBUvuB6wDG0moGWav5sfEvIcB9ioUJR5wJFts,388
75
75
  shinestacker/retouch/icon_container.py,sha256=6gw1HO1bC2FrdB4dc_iH81DQuLjzuvRGksZ2hKLT9yA,585
76
- shinestacker/retouch/image_editor_ui.py,sha256=GNozK_P7orgl8EioemJeyR4e_LLMbKVZi4xhYW9m38U,29893
76
+ shinestacker/retouch/image_editor_ui.py,sha256=cMGiqyPGqJmBaXMAc0WImDPf_hmxO4KiJtaaSpiW9EU,29869
77
77
  shinestacker/retouch/image_viewer.py,sha256=3ebrLHTDtGd_EbIT2nNFRUjH836rblmmK7jZ62YcJ2U,19564
78
- shinestacker/retouch/io_gui_handler.py,sha256=M9rlfqiIaP1wWCm6p-Ew15w0_pH8-DoBXJdEkTUeVCU,11525
78
+ shinestacker/retouch/io_gui_handler.py,sha256=52Wk19DjXtgCBcBWz9t0wUEpt8RS67FohdG44OOnu8c,11541
79
79
  shinestacker/retouch/io_manager.py,sha256=JUAA--AK0mVa1PTErJTnBFjaXIle5Qs7Ow0Wkd8at0o,2437
80
80
  shinestacker/retouch/layer_collection.py,sha256=Q7zoCYRn__jYkfrEC2lY1uKHWfOUbsJ27xaYHIoKVxo,5730
81
81
  shinestacker/retouch/shortcuts_help.py,sha256=SN4vNa_6yRAFaWxt5HpWn8FHgwmHrIs_wYwjl4iyDmg,3769
@@ -83,9 +83,9 @@ shinestacker/retouch/undo_manager.py,sha256=_ekbcOLcPbQLY7t-o8wf-b1uA6OPY9rRyLM-
83
83
  shinestacker/retouch/unsharp_mask_filter.py,sha256=uFnth8fpZFGhdIgJCnS8x5v6lBQgJ3hX0CBke9pFXeM,3510
84
84
  shinestacker/retouch/vignetting_filter.py,sha256=3WuoF38lQOIaU1MWmqviItuQn8NnbMN0nwV7pM9IJqU,3453
85
85
  shinestacker/retouch/white_balance_filter.py,sha256=glMBYlmrF-i_OrB3sGUpjZE6X4FQdyLC4GBy2bWtaFc,6056
86
- shinestacker-1.0.1.dist-info/licenses/LICENSE,sha256=pWgb-bBdsU2Gd2kwAXxketnm5W_2u8_fIeWEgojfrxs,7651
87
- shinestacker-1.0.1.dist-info/METADATA,sha256=txWeQBvdot0jMY-eCpwlZTqMataYiQn8MpSZECcxaUw,5902
88
- shinestacker-1.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
89
- shinestacker-1.0.1.dist-info/entry_points.txt,sha256=SY6g1LqtMmp23q1DGwLUDT_dhLX9iss8DvWkiWLyo_4,166
90
- shinestacker-1.0.1.dist-info/top_level.txt,sha256=MhijwnBVX5psfsyX8JZjqp3SYiWPsKe69f3Gnyze4Fw,13
91
- shinestacker-1.0.1.dist-info/RECORD,,
86
+ shinestacker-1.0.3.dist-info/licenses/LICENSE,sha256=pWgb-bBdsU2Gd2kwAXxketnm5W_2u8_fIeWEgojfrxs,7651
87
+ shinestacker-1.0.3.dist-info/METADATA,sha256=3iFJO-177VFRPs8m5UnV2LhmiwO9wI5Bf3_x_DzkVbk,5903
88
+ shinestacker-1.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
89
+ shinestacker-1.0.3.dist-info/entry_points.txt,sha256=SY6g1LqtMmp23q1DGwLUDT_dhLX9iss8DvWkiWLyo_4,166
90
+ shinestacker-1.0.3.dist-info/top_level.txt,sha256=MhijwnBVX5psfsyX8JZjqp3SYiWPsKe69f3Gnyze4Fw,13
91
+ shinestacker-1.0.3.dist-info/RECORD,,