further issue fixes
This commit is contained in:
93
main.py
93
main.py
@@ -46,7 +46,7 @@ from PySide6.QtGui import QAction, QKeySequence, QIcon, QIntValidator, QDoubleVa
|
||||
from PySide6.QtSvgWidgets import QSvgWidget # needed to show svgs when app is not frozen
|
||||
|
||||
|
||||
CURRENT_VERSION = "1.2.0"
|
||||
CURRENT_VERSION = "1.2.1"
|
||||
|
||||
API_URL = "https://git.research.dezeeuw.ca/api/v1/repos/tyler/flares/releases"
|
||||
API_URL_SECONDARY = "https://git.research2.dezeeuw.ca/api/v1/repos/tyler/flares/releases"
|
||||
@@ -1480,11 +1480,11 @@ class ParamSection(QWidget):
|
||||
}
|
||||
"""
|
||||
|
||||
def __init__(self, section_data):
|
||||
def __init__(self, section_data, global_widgets):
|
||||
super().__init__()
|
||||
layout = QVBoxLayout()
|
||||
self.setLayout(layout)
|
||||
self.widgets = {}
|
||||
self.widgets = global_widgets
|
||||
self.dependencies = []
|
||||
self.selected_path = None
|
||||
|
||||
@@ -1527,7 +1527,7 @@ class ParamSection(QWidget):
|
||||
widget = QComboBox()
|
||||
widget.addItems(["True", "False"])
|
||||
widget.setCurrentText(str(param["default"]))
|
||||
widget.currentTextChanged.connect(self.update_dependencies)
|
||||
widget.currentTextChanged.connect(self.notify_global_update)
|
||||
elif param["type"] == int:
|
||||
widget = QLineEdit()
|
||||
widget.setValidator(QIntValidator())
|
||||
@@ -1541,7 +1541,7 @@ class ParamSection(QWidget):
|
||||
widget = QComboBox()
|
||||
widget.addItems(param.get("options", []))
|
||||
widget.setCurrentText(str(param.get("default", "<None Selected>")))
|
||||
widget.currentTextChanged.connect(self.update_dependencies)
|
||||
widget.currentTextChanged.connect(self.notify_global_update)
|
||||
else:
|
||||
widget = self._create_multiselect_dropdown(None)
|
||||
elif param["type"] == range:
|
||||
@@ -1580,6 +1580,16 @@ class ParamSection(QWidget):
|
||||
|
||||
self.update_dependencies()
|
||||
|
||||
def notify_global_update(self):
|
||||
"""
|
||||
Since dependencies can cross sections, we need to tell
|
||||
all sections to refresh their enabled/disabled states.
|
||||
"""
|
||||
# If you have a reference to the parent container, call its update.
|
||||
# Otherwise, you can iterate through the known param_sections:
|
||||
for section in self.parent().findChildren(ParamSection):
|
||||
section.update_dependencies()
|
||||
|
||||
def update_dependencies(self):
|
||||
"""Disables/Enables widgets based on parent selection values."""
|
||||
for dep in self.dependencies:
|
||||
@@ -1691,6 +1701,12 @@ class ParamSection(QWidget):
|
||||
widget = info["widget"]
|
||||
expected_type = info["type"]
|
||||
|
||||
if name == "SHORT_CHANNEL_REGRESSION":
|
||||
# If the widget is disabled (greyed out), force False
|
||||
if not widget.isEnabled():
|
||||
values[name] = False
|
||||
continue
|
||||
|
||||
if expected_type == bool:
|
||||
values[name] = widget.currentText() == "True"
|
||||
elif expected_type == list:
|
||||
@@ -4061,6 +4077,7 @@ class MainApplication(QMainWindow):
|
||||
self.is_2d_bypass = False
|
||||
self.incompatible_save_bypass = False
|
||||
self.missing_events_bypass = False
|
||||
self.analysis_clearing_bypass = False
|
||||
|
||||
self.files_total = 0 # total number of files to process
|
||||
self.files_done = set() # set of file paths done (success or fail)
|
||||
@@ -4313,7 +4330,8 @@ class MainApplication(QMainWindow):
|
||||
preferences_actions = [
|
||||
("2D Data Bypass", "", self.is_2d_bypass_func, resource_path("icons/info_24dp_1F1F1F.svg")),
|
||||
("Incompatible Save Bypass", "", self.incompatable_save_bypass_func, resource_path("icons/info_24dp_1F1F1F.svg")),
|
||||
("Missing Events Bypass", "", self.missing_events_bypass_func, resource_path("icons/info_24dp_1F1F1F.svg"))
|
||||
("Missing Events Bypass", "", self.missing_events_bypass_func, resource_path("icons/info_24dp_1F1F1F.svg")),
|
||||
("Analysis Clearing Bypass", "", self.analysis_clearing_bypass_func, resource_path("icons/info_24dp_1F1F1F.svg"))
|
||||
]
|
||||
for name, shortcut, slot, icon in preferences_actions:
|
||||
preferences_menu.addAction(make_action(name, shortcut, slot, icon=icon, checkable=True, checked=False))
|
||||
@@ -4337,13 +4355,18 @@ class MainApplication(QMainWindow):
|
||||
widget.deleteLater()
|
||||
self.param_sections.clear()
|
||||
|
||||
self.global_param_widgets = {}
|
||||
|
||||
# Add ParamSection widgets from SECTIONS
|
||||
for section in SECTIONS:
|
||||
self.section_widget = ParamSection(section)
|
||||
self.section_widget = ParamSection(section, self.global_param_widgets)
|
||||
self.rows_layout.addWidget(self.section_widget)
|
||||
|
||||
self.param_sections.append(self.section_widget)
|
||||
|
||||
for sec in self.param_sections:
|
||||
sec.update_dependencies()
|
||||
|
||||
|
||||
def clear_all(self):
|
||||
|
||||
@@ -4358,6 +4381,11 @@ class MainApplication(QMainWindow):
|
||||
if widget:
|
||||
widget.deleteLater()
|
||||
|
||||
if hasattr(self, "selected_paths"):
|
||||
self.selected_paths = []
|
||||
if hasattr(self, "selected_path"):
|
||||
self.selected_path = None
|
||||
|
||||
# Clear file data
|
||||
self.bubble_widgets.clear()
|
||||
self.statusBar().clearMessage()
|
||||
@@ -4405,6 +4433,9 @@ class MainApplication(QMainWindow):
|
||||
def missing_events_bypass_func(self, checked):
|
||||
self.missing_events_bypass = checked
|
||||
|
||||
def analysis_clearing_bypass_func(self, checked):
|
||||
self.analysis_clearing_bypass = checked
|
||||
|
||||
def about_window(self):
|
||||
if self.about is None or not self.about.isVisible():
|
||||
self.about = AboutWindow(self)
|
||||
@@ -4533,6 +4564,15 @@ class MainApplication(QMainWindow):
|
||||
|
||||
def save_project(self, onCrash=False):
|
||||
|
||||
if not getattr(self, 'raw_haemo_dict', None):
|
||||
if not onCrash: # Don't show popups during a crash/autosave
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"Save Project",
|
||||
"There is no processed data to save. Please process some data before saving."
|
||||
)
|
||||
return
|
||||
|
||||
if not onCrash:
|
||||
filename, _ = QFileDialog.getSaveFileName(
|
||||
self, "Save Project", "", "FLARE Project (*.flare)"
|
||||
@@ -4554,12 +4594,12 @@ class MainApplication(QMainWindow):
|
||||
project_dir = project_path.parent
|
||||
|
||||
file_list = [
|
||||
str(PurePosixPath(Path(bubble.file_path).resolve().relative_to(project_dir)))
|
||||
str(PurePosixPath(os.path.relpath(Path(bubble.file_path).resolve(), project_dir)))
|
||||
for bubble in self.bubble_widgets.values()
|
||||
]
|
||||
|
||||
progress_states = {
|
||||
str(PurePosixPath(Path(bubble.file_path).resolve().relative_to(project_dir))): bubble.current_step
|
||||
str(PurePosixPath(os.path.relpath(Path(bubble.file_path).resolve(), project_dir))): bubble.current_step
|
||||
for bubble in self.bubble_widgets.values()
|
||||
}
|
||||
|
||||
@@ -5060,7 +5100,40 @@ class MainApplication(QMainWindow):
|
||||
|
||||
'''MODULE FILE'''
|
||||
def on_run_task(self):
|
||||
|
||||
|
||||
#do the check
|
||||
if not self.analysis_clearing_bypass:
|
||||
if self.button3.isVisible():
|
||||
msg = QMessageBox(self)
|
||||
msg.setWindowTitle("Confirm - FLARES")
|
||||
msg.setText("Processing new data will clear the current analysis. Continue? (If you do not want this dialog box to appear, toggle 'Analysis Clearing Bypass' from the Preferences menu.)")
|
||||
|
||||
# Add the OK and Cancel buttons
|
||||
msg.setStandardButtons(QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel)
|
||||
|
||||
# Set the default button (highlighted)
|
||||
msg.setDefaultButton(QMessageBox.StandardButton.Cancel)
|
||||
|
||||
# Capture the result
|
||||
response = msg.exec()
|
||||
|
||||
if response == QMessageBox.StandardButton.Ok:
|
||||
print("User clicked OK")
|
||||
else:
|
||||
return
|
||||
|
||||
self.button3.setVisible(False)
|
||||
|
||||
self.raw_haemo_dict = {}
|
||||
self.config_dict = {}
|
||||
self.epochs_dict = {}
|
||||
self.fig_bytes_dict = {}
|
||||
self.cha_dict = {}
|
||||
self.contrast_results_dict = {}
|
||||
self.df_ind_dict = {}
|
||||
self.design_matrix_dict = {}
|
||||
self.valid_dict = {}
|
||||
|
||||
self.button1.clicked.disconnect(self.on_run_task)
|
||||
self.button1.setText("Cancel")
|
||||
self.button1.clicked.connect(self.cancel_task)
|
||||
|
||||
Reference in New Issue
Block a user