dark mode toggle + enhancements

This commit is contained in:
2026-08-27 17:50:23 -07:00
parent 83ab73a05a
commit a9ea0efcb4
5 changed files with 211 additions and 53 deletions
+74 -28
View File
@@ -34,7 +34,9 @@ class UpdateOptodesWindow(QWidget):
self.setWindowTitle(f"Update optode positions - {APP_NAME.upper()}")
self.resize(760, 200)
self.label_file_a = QLabel("SNIRF file:")
self.selected_snirf_files: list[str] = []
self.label_file_a = QLabel("SNIRF files:")
self.line_edit_file_a = QLineEdit()
self.line_edit_file_a.setReadOnly(True)
self.btn_browse_a = QPushButton("Browse .snirf")
@@ -171,9 +173,16 @@ class UpdateOptodesWindow(QWidget):
msg.exec()
def browse_file_a(self) -> None:
file_path, _ = QFileDialog.getOpenFileName(self, "Select SNIRF File", "", "SNIRF Files (*.snirf)")
if file_path:
self.line_edit_file_a.setText(file_path)
file_paths, _ = QFileDialog.getOpenFileNames(
self,
"Select SNIRF Files",
"",
"SNIRF Files (*.snirf)"
)
if file_paths:
self.selected_snirf_files = file_paths
self.line_edit_file_a.setText("; ".join(Path(p).name for p in file_paths))
def browse_file_b(self) -> None:
file_path, _ = QFileDialog.getOpenFileName(self, "Select File", "", "Supported Files (*.txt *.xlsx)")
@@ -181,6 +190,7 @@ class UpdateOptodesWindow(QWidget):
self.line_edit_file_b.setText(file_path)
def clear_files(self) -> None:
self.selected_snirf_files.clear()
self.line_edit_file_a.clear()
self.line_edit_file_b.clear()
@@ -189,40 +199,76 @@ class UpdateOptodesWindow(QWidget):
file_b = self.line_edit_file_b.text()
suffix = self.line_edit_suffix.text().strip() or "flare"
if not file_a:
QMessageBox.critical(self, "Missing File", "Please select a SNIRF file.")
if not self.selected_snirf_files:
QMessageBox.critical(self, "Missing File", "Please select at least one SNIRF file.")
return
if not file_b:
QMessageBox.critical(self, "Missing File", "Please select a TXT file.")
QMessageBox.critical(self, "Missing File", "Please select a TXT or XLSX digitization file.")
return
# Get original filename without extension
base_name = os.path.splitext(os.path.basename(file_a))[0]
suggested_name = f"{base_name}_{suffix}.snirf"
# Open save dialog with default name
save_path, _ = QFileDialog.getSaveFileName(
output_dir = QFileDialog.getExistingDirectory(
self,
"Save SNIRF File As",
suggested_name,
"SNIRF Files (*.snirf)"
"Select Output Directory"
)
if not save_path:
if not output_dir:
print("Save cancelled.")
return
# Ensure .snirf extension
if not save_path.lower().endswith(".snirf"):
save_path += ".snirf"
output_path = Path(output_dir)
try:
self.update_optode_positions(file_a=file_a, file_b=file_b, save_path=save_path)
except Exception as e:
QMessageBox.critical(self, "Error", f"Failed to write file:\n{e}")
return
QMessageBox.information(self, "File Saved", f"File was saved to:\n{save_path}")
successful_files: list[str] = []
failed_files: list[str] = []
for file_a in self.selected_snirf_files:
input_path = Path(file_a)
# Keep original filename and independently add suffix
save_path = output_path / f"{input_path.stem}_{suffix}.snirf"
try:
self.update_optode_positions(
file_a=file_a,
file_b=file_b,
save_path=save_path
)
successful_files.append(save_path.name)
except Exception as e:
failed_files.append(
f"{input_path.name}: {e}"
)
# Build summary
message_parts: list[str] = []
if successful_files:
message_parts.append(
f"Successfully processed {len(successful_files)} "
f"SNIRF file(s):\n\n"
+ "\n".join(successful_files)
)
if failed_files:
message_parts.append(
f"Failed to process {len(failed_files)} "
f"SNIRF file(s):\n\n"
+ "\n".join(failed_files)
)
if failed_files:
QMessageBox.warning(
self,
"Processing Complete",
"\n\n".join(message_parts)
)
else:
QMessageBox.information(
self,
"Files Saved",
"\n\n".join(message_parts)
)
def update_optode_positions(
self,
@@ -306,6 +352,6 @@ class UpdateOptodesWindow(QWidget):
initial_montage = make_dig_montage(ch_pos=ch_positions, nasion=fiducials.get('nz'), lpa=fiducials.get('lpa'), rpa=fiducials.get('rpa'), coord_frame='head') # type: ignore
# Read the SNIRF file, set the montage, and write it back
raw = read_raw_snirf(file_a, preload=True)
raw = read_raw_snirf(str(file_a), preload=True)
raw.set_montage(initial_montage) # type: ignore
write_raw_snirf(raw, save_path)