Skip to content

Commit

Permalink
Use Tool item's root directory in setting program files if available
Browse files Browse the repository at this point in the history
  • Loading branch information
ptsavol committed Dec 11, 2024
1 parent aa3558a commit 3cd01c1
Showing 1 changed file with 51 additions and 18 deletions.
69 changes: 51 additions & 18 deletions spine_items/tool/widgets/tool_specification_editor_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ def __init__(self, toolbox, specification=None, item=None):
inputfiles_opt = list(specification.inputfiles_opt) if specification else []
outputfiles = list(specification.outputfiles) if specification else []
self.includes_main_path = specification.path if specification else None
if self.has_root_directory():
self.includes_main_path = self.item.root_dir

Check warning on line 112 in spine_items/tool/widgets/tool_specification_editor_window.py

View check run for this annotation

Codecov / codecov/patch

spine_items/tool/widgets/tool_specification_editor_window.py#L112

Added line #L112 was not covered by tests
# Populate lists (this will also create headers)
self.init_programfile_list()
self.init_io_file_list()
Expand All @@ -116,7 +118,10 @@ def __init__(self, toolbox, specification=None, item=None):
self.populate_inputfiles_opt_list(inputfiles_opt)
self.populate_outputfiles_list(outputfiles)
if main_program_file:
self._set_main_program_file(os.path.join(self.includes_main_path, main_program_file))
if self.has_root_directory():
self._set_main_program_file(os.path.abspath(os.path.join(self.item.root_dir, main_program_file)))

Check warning on line 122 in spine_items/tool/widgets/tool_specification_editor_window.py

View check run for this annotation

Codecov / codecov/patch

spine_items/tool/widgets/tool_specification_editor_window.py#L122

Added line #L122 was not covered by tests
else:
self._set_main_program_file(os.path.join(self.includes_main_path, main_program_file))
else:
self._label_main_path.setText(self.includes_main_path)
self._clear_program_text_edit()
Expand All @@ -136,6 +141,11 @@ def _make_ui(self):

return Ui_MainWindow()

def has_root_directory(self):
if self.item is not None and self.item.root_dir != "":
return True

Check warning on line 146 in spine_items/tool/widgets/tool_specification_editor_window.py

View check run for this annotation

Codecov / codecov/patch

spine_items/tool/widgets/tool_specification_editor_window.py#L146

Added line #L146 was not covered by tests
return False

@property
def settings_group(self):
return "toolSpecificationEditorWindow"
Expand Down Expand Up @@ -242,10 +252,14 @@ def _make_new_specification(self, spec_name):
self.show_error("Please add a main program file")
return None
new_spec_dict = {"name": spec_name, "description": self._spec_toolbar.description(), "tooltype": toolspectype}
main_prgm_dir, main_prgm_file_name = os.path.split(main_program_file) if main_program_file else ("", "")
if not main_prgm_dir:
if not main_program_file:
main_prgm_file_name = ""

Check warning on line 256 in spine_items/tool/widgets/tool_specification_editor_window.py

View check run for this annotation

Codecov / codecov/patch

spine_items/tool/widgets/tool_specification_editor_window.py#L256

Added line #L256 was not covered by tests
self.includes_main_path = None
elif self.has_root_directory():
main_prgm_file_name = os.path.relpath(main_program_file, self.item.root_dir)
self.includes_main_path = self.item.root_dir

Check warning on line 260 in spine_items/tool/widgets/tool_specification_editor_window.py

View check run for this annotation

Codecov / codecov/patch

spine_items/tool/widgets/tool_specification_editor_window.py#L259-L260

Added lines #L259 - L260 were not covered by tests
else:
main_prgm_dir, main_prgm_file_name = os.path.split(main_program_file)
self.includes_main_path = os.path.abspath(main_prgm_dir)
self._label_main_path.setText(self.includes_main_path)
new_spec_dict["includes"] = [main_prgm_file_name] if main_prgm_file_name else []
Expand Down Expand Up @@ -371,16 +385,22 @@ def populate_main_programfile(self, file_path):
"""Adds the main program item into the program files model.
Args:
file_path (str): *absolute* path to main program file
file_path (str): Absolute path to main program file
"""
index = self.programfiles_model.index(0, 0)
root_item = self.programfiles_model.itemFromIndex(index)
root_item.removeRows(0, root_item.rowCount())
if file_path: # Do only if the spec has a main program (Executable Tool specs may not have one)
item = QStandardItem(os.path.basename(file_path))
if self.has_root_directory():
rel = os.path.relpath(file_path, self.item.root_dir)
item = QStandardItem(rel)
full_path = os.path.abspath(os.path.join(self.item.root_dir, file_path))
item.setData(full_path, Qt.ItemDataRole.UserRole)

Check warning on line 398 in spine_items/tool/widgets/tool_specification_editor_window.py

View check run for this annotation

Codecov / codecov/patch

spine_items/tool/widgets/tool_specification_editor_window.py#L395-L398

Added lines #L395 - L398 were not covered by tests
else:
item = QStandardItem(os.path.basename(file_path))
item.setData(file_path, Qt.ItemDataRole.UserRole)
item.setFlags(item.flags() & ~Qt.ItemFlag.ItemIsEditable)
item.setData(QFileIconProvider().icon(QFileInfo(file_path)), Qt.ItemDataRole.DecorationRole)
item.setData(file_path, Qt.ItemDataRole.UserRole)
root_item.appendRow(item)
tool_tip = f"<p>{self._current_main_program_file()}</p>"
self.programfiles_model.setData(root_item.child(0).index(), tool_tip, role=Qt.ItemDataRole.ToolTipRole)
Expand Down Expand Up @@ -435,17 +455,22 @@ def populate_programfile_list(self, names):
self._set_program_file_dirty(index, doc.isModified())

def _set_program_file_dirty(self, index, dirty):
"""
Appends a * to the file name in program files tree view if dirty.
"""Appends a * to the file name in program files tree view if dirty.
Args:
index (QModelIndex): index in program files model
dirty (bool)
index (QModelIndex): Index in program files model
dirty (bool): True or False
"""
basename = os.path.basename(index.data(Qt.ItemDataRole.UserRole))
file_path = index.data(Qt.ItemDataRole.UserRole)
# Main program file items have their full path as UserRole data, additional
# program file items have only their file name as UserRole data
if self.has_root_directory() and os.path.exists(file_path) and os.path.samefile(self._current_main_program_file(), file_path):
name = os.path.relpath(file_path, self.item.root_dir)

Check warning on line 468 in spine_items/tool/widgets/tool_specification_editor_window.py

View check run for this annotation

Codecov / codecov/patch

spine_items/tool/widgets/tool_specification_editor_window.py#L468

Added line #L468 was not covered by tests
else:
name = os.path.basename(file_path)
if dirty:
basename += "*"
self.programfiles_model.setData(index, basename, role=Qt.ItemDataRole.DisplayRole)
name += "*"
self.programfiles_model.setData(index, name, role=Qt.ItemDataRole.DisplayRole)

def init_io_file_list(self):
for name in ("Input files", "Optional input files", "Output files"):
Expand Down Expand Up @@ -785,20 +810,26 @@ def _set_program_files(self, program_files):
"""Sets program files.
Args:
program_files (list of str): List of *absolute* paths
program_files (list of str): List of paths. First item is the absolute path to main program file,
the remaining items are path stubs relative to the item root directory or to includes main path.
"""
main_program_file = program_files[0] if program_files else ""
self.includes_main_path = os.path.dirname(next(iter(f for f in program_files if f), ""))
additional_program_files = [os.path.relpath(file, self.includes_main_path) for file in program_files[1:]]
if self.has_root_directory():
additional_program_files = [os.path.relpath(file, self.includes_main_path) for file in program_files[1:]]
main_program_path = os.path.relpath(main_program_file, self.item.root_dir) if main_program_file else ""

Check warning on line 819 in spine_items/tool/widgets/tool_specification_editor_window.py

View check run for this annotation

Codecov / codecov/patch

spine_items/tool/widgets/tool_specification_editor_window.py#L818-L819

Added lines #L818 - L819 were not covered by tests
else:
self.includes_main_path = os.path.dirname(next(iter(f for f in program_files if f), ""))
additional_program_files = [os.path.relpath(file, self.includes_main_path) for file in program_files[1:]]
main_program_path = os.path.basename(main_program_file)
self._set_main_program_file(main_program_file)
self.populate_programfile_list(additional_program_files)
self.spec_dict["includes"] = [os.path.basename(main_program_file), *additional_program_files]
self.spec_dict["includes"] = [main_program_path, *additional_program_files]

def _set_main_program_file(self, file_path):
"""Sets main program file and dumps its contents into the text edit.
Args:
file_path (str): absolute path
file_path (str): Absolute path
"""
self.populate_main_programfile(file_path)
self._label_main_path.setText(self.includes_main_path)
Expand Down Expand Up @@ -1078,6 +1109,8 @@ def remove_program_files(self, _=False):
return
removed_files = {os.path.join(*_path_components_from_index(ind)) for ind in indexes}
old_program_files = self.spec_dict.get("includes", [])
old_program_files = [f.replace(os.sep, "/") for f in old_program_files]
removed_files = [f.replace(os.sep, "/") for f in removed_files]
new_program_files = [f for f in old_program_files if f not in removed_files]
if self.includes_main_path is not None:
old_program_files = [os.path.join(self.includes_main_path, f) for f in old_program_files]
Expand Down

0 comments on commit 3cd01c1

Please sign in to comment.