preparation for 1.5.1
This commit is contained in:
@@ -43,7 +43,7 @@ from src.window.updateoptodes import UpdateOptodesWindow
|
||||
from src.window.userguide import UserGuideWindow
|
||||
from src.window.viewerlauncher import ViewerLauncherWidget
|
||||
from src.window.welcome import WelcomeDialog
|
||||
from src.shared.flaresbasewidget import ParamSection
|
||||
from src.shared.flaresbasewidget import FilePickerWidget, ParamSection
|
||||
from src.shared.shareddata import API_URL, API_URL_SECONDARY, APP_NAME, CURRENT_VERSION, PIPELINE_STAGES, PLATFORM_NAME
|
||||
from updater import finish_update_if_needed, UpdateManager, LocalPendingUpdateCheckThread
|
||||
|
||||
@@ -91,7 +91,7 @@ SECTIONS = [
|
||||
"title": "Trimming",
|
||||
"params": [
|
||||
{"name": "TRIM", "default": True, "type": bool, "help": "Should the start of the files be trimmed?"},
|
||||
{"name": "SECONDS_TO_KEEP", "default": 5, "type": float, "depends_on": "TRIM", "help": "Seconds to keep at the beginning of all loaded snirf files before the first annotation/event occurs. Calculation is done seperatly on all loaded snirf files. Setting this to 0 will have the first annotation/event be at time point 0. Only used if TRIM is set to True."},
|
||||
{"name": "SECONDS_TO_KEEP", "default": 5.0, "type": float, "depends_on": "TRIM", "help": "Seconds to keep at the beginning of all loaded snirf files before the first annotation/event occurs. Calculation is done seperatly on all loaded snirf files. Setting this to 0 will have the first annotation/event be at time point 0. Only used if TRIM is set to True."},
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -257,7 +257,8 @@ SECTIONS = [
|
||||
{"name": "FIR_DELAYS", "default": 15, "type": range, "depends_on": "HRF_MODEL", "depends_value": "fir", "help": "In case of FIR design, yields the array of delays used in the FIR model (in scans)."},
|
||||
{"name": "MIN_ONSET", "default": -24, "type": int, "help": "Minimal onset relative to frame times (in seconds)"},
|
||||
{"name": "OVERSAMPLING", "default": 50, "type": int, "help": "Oversampling factor used in temporal convolutions."},
|
||||
{"name": "REMOVE_EVENTS", "default": "None", "type": list, "help": "Remove events matching the names provided before generating the Design Matrix"},
|
||||
# TODO: Re-implement this without causing a memory leak
|
||||
# {"name": "REMOVE_EVENTS", "default": "None", "type": list, "help": "Remove events matching the names provided before generating the Design Matrix"},
|
||||
{"name": "SHORT_CHANNEL_REGRESSION", "default": True, "type": bool, "depends_on": "SHORT_CHANNEL", "help": "Should short channel regression be used to create the design matrix? This will use the 'signal' from the short channel and regress it out of all other channels."},
|
||||
]
|
||||
},
|
||||
@@ -272,7 +273,7 @@ SECTIONS = [
|
||||
{
|
||||
"title": "Region of Interest",
|
||||
"params": [
|
||||
{"name": "JSON_LOCATION", "default": "", "type": str, "help": "Location of the JSON file containing region of interest results for significance calculations."},
|
||||
{"name": "JSON_LOCATION", "default": "", "type": "json_file", "help": "Location of the JSON file containing region of interest results for significance calculations."},
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -505,7 +506,7 @@ class MainApplication(QMainWindow):
|
||||
self.missing_events_bypass = False
|
||||
self.analysis_clearing_bypass = False
|
||||
self.folding_bypass = False
|
||||
self.json_location = r"C:\Users\tyler\Desktop\research\flares\regions.json"
|
||||
self.json_location = ""
|
||||
|
||||
|
||||
# Initialization to ensure that saving can occur
|
||||
@@ -525,15 +526,13 @@ class MainApplication(QMainWindow):
|
||||
self.files_failed = set() # set of failed file paths
|
||||
self.files_results = {} # dict for successful results (if needed)
|
||||
|
||||
self.platform_suffix = "-" + PLATFORM_NAME
|
||||
|
||||
self.updater = UpdateManager(
|
||||
main_window=self,
|
||||
api_url=API_URL,
|
||||
api_url_sec=API_URL_SECONDARY,
|
||||
current_version=CURRENT_VERSION,
|
||||
platform_name=PLATFORM_NAME,
|
||||
platform_suffix=self.platform_suffix,
|
||||
platform_suffix="-" + PLATFORM_NAME,
|
||||
app_name=APP_NAME
|
||||
)
|
||||
|
||||
@@ -546,7 +545,7 @@ class MainApplication(QMainWindow):
|
||||
self.installEventFilter(self)
|
||||
|
||||
# Start local pending update check thread
|
||||
self.local_check_thread = LocalPendingUpdateCheckThread(CURRENT_VERSION, self.platform_suffix, PLATFORM_NAME, APP_NAME)
|
||||
self.local_check_thread = LocalPendingUpdateCheckThread(CURRENT_VERSION, "-" + PLATFORM_NAME, PLATFORM_NAME, APP_NAME)
|
||||
self.local_check_thread.pending_update_found.connect(self.updater.on_pending_update_found)
|
||||
self.local_check_thread.no_pending_update.connect(self.updater.on_no_pending_update)
|
||||
self.local_check_thread.start()
|
||||
@@ -617,7 +616,7 @@ class MainApplication(QMainWindow):
|
||||
|
||||
label_desc = QLabel('<a href="#">Why are these useful?</a>')
|
||||
label_desc.setTextInteractionFlags(Qt.TextInteractionFlag.TextBrowserInteraction)
|
||||
label_desc.linkActivated.connect(lambda: QMessageBox.information(None, "Info", "Parameter Info..."))
|
||||
label_desc.linkActivated.connect(lambda: QMessageBox.information(None, f"Info - {APP_NAME.upper()} ", "Age: Used in determing the participants PPF.\nGender: Not currently used or implemented.\nGroup: Used to split participants into groups for comparisons between them."))
|
||||
right_column_layout.addWidget(label_desc)
|
||||
right_column_layout.addStretch()
|
||||
self.right_column_widget.hide()
|
||||
@@ -835,6 +834,23 @@ class MainApplication(QMainWindow):
|
||||
and resets the memory heap.
|
||||
"""
|
||||
|
||||
if hasattr(self, "result_process") and self.result_process and self.result_process.is_alive():
|
||||
msg = QMessageBox(self)
|
||||
msg.setWindowTitle(f"Confirm Clear - {APP_NAME.upper()}")
|
||||
msg.setText("Data processing is currently active in the background. "
|
||||
"Clearing now will forcefully kill all tasks and lose current progress.\n\n"
|
||||
"Are you sure you want to proceed?")
|
||||
|
||||
msg.setStandardButtons(QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel)
|
||||
msg.setDefaultButton(QMessageBox.StandardButton.Cancel)
|
||||
|
||||
response = msg.exec()
|
||||
|
||||
if response == QMessageBox.StandardButton.Ok:
|
||||
self.cancel_task()
|
||||
else:
|
||||
return
|
||||
|
||||
self.top_left_widget.clear()
|
||||
|
||||
if hasattr(self, "last_clicked_bubble"):
|
||||
@@ -898,6 +914,16 @@ class MainApplication(QMainWindow):
|
||||
|
||||
self.metadata_cache = {}
|
||||
|
||||
self.file_metadata = {}
|
||||
|
||||
if hasattr(self, "meta_fields"):
|
||||
for field in self.meta_fields.values():
|
||||
field.blockSignals(True)
|
||||
field.clear()
|
||||
field.blockSignals(False)
|
||||
|
||||
self.current_file = None
|
||||
|
||||
if hasattr(self, "selected_paths"): self.selected_paths = []
|
||||
if hasattr(self, "selected_path"): self.selected_path = None
|
||||
|
||||
@@ -1176,9 +1202,20 @@ class MainApplication(QMainWindow):
|
||||
file_cfg.read_string(DEFAULT_CONFIG)
|
||||
|
||||
self.sync_app_with_config()
|
||||
self.update_sections(0)
|
||||
|
||||
QTimer.singleShot(100, self._show_reset_success_dialog)
|
||||
|
||||
|
||||
def _show_reset_success_dialog(self):
|
||||
"""Helper method triggered after the UI has completely finished redrawing."""
|
||||
QMessageBox.information(
|
||||
self,
|
||||
"Reset Successful",
|
||||
"All application settings have been successfully restored to their default values."
|
||||
)
|
||||
self.statusbar.showMessage("All settings have been reset to their default values.", 5000)
|
||||
|
||||
self.statusbar.showMessage("All settings have been reset to their default values.", 5000)
|
||||
|
||||
|
||||
def sync_app_with_config(self):
|
||||
"""Reads values from file_cfg and updates both internal variables and UI checkmarks."""
|
||||
@@ -1418,6 +1455,8 @@ class MainApplication(QMainWindow):
|
||||
|
||||
project_data = sanitize(project_data)
|
||||
|
||||
self.add_to_recent_projects(os.path.normpath(filename))
|
||||
|
||||
self.saving_overlay = SavingOverlay(self)
|
||||
self.saving_overlay.resize(self.size()) # Cover the main window
|
||||
self.saving_overlay.show()
|
||||
@@ -1582,6 +1621,12 @@ class MainApplication(QMainWindow):
|
||||
widget.blockSignals(False)
|
||||
widget.update()
|
||||
|
||||
elif isinstance(widget, FilePickerWidget):
|
||||
widget.blockSignals(True)
|
||||
widget.setText(str(value)) # Updates the internal QLineEdit text safely
|
||||
widget.blockSignals(False)
|
||||
widget.update()
|
||||
|
||||
# QComboBox (bool, list)
|
||||
elif isinstance(widget, QComboBox):
|
||||
widget.blockSignals(True)
|
||||
@@ -1599,10 +1644,19 @@ class MainApplication(QMainWindow):
|
||||
widget.blockSignals(False)
|
||||
widget.update()
|
||||
|
||||
if hasattr(section_widget, 'check_if_changed'):
|
||||
if isinstance(widget, (QLineEdit, FilePickerWidget)):
|
||||
section_widget.check_if_changed(name, widget.text())
|
||||
elif isinstance(widget, QComboBox):
|
||||
section_widget.check_if_changed(name, widget.currentText())
|
||||
elif isinstance(widget, QSpinBox):
|
||||
section_widget.check_if_changed(name, widget.value())
|
||||
|
||||
# After restoring, make sure dependencies are updated
|
||||
if hasattr(section_widget, 'update_dependencies'):
|
||||
section_widget.update_dependencies()
|
||||
|
||||
#TODO: Update blue bold text too
|
||||
|
||||
# def show_files_as_bubbles(self, folder_paths):
|
||||
|
||||
@@ -1659,7 +1713,6 @@ class MainApplication(QMainWindow):
|
||||
current_ui_config = {}
|
||||
try:
|
||||
for section in self.param_sections:
|
||||
# This calls the get_param_values() method you shared earlier
|
||||
section_values = section.get_param_values()
|
||||
current_ui_config.update(section_values)
|
||||
return current_ui_config
|
||||
@@ -1839,6 +1892,19 @@ class MainApplication(QMainWindow):
|
||||
self.top_left_widget.clear()
|
||||
self.right_column_widget.hide()
|
||||
|
||||
target_path = bubble.file_path
|
||||
|
||||
if hasattr(self, 'file_metadata'):
|
||||
self.file_metadata.pop(target_path, None)
|
||||
|
||||
if getattr(self, 'current_file', None) == target_path:
|
||||
self.current_file = None
|
||||
if hasattr(self, 'meta_fields'):
|
||||
for field in self.meta_fields.values():
|
||||
field.blockSignals(True)
|
||||
field.clear()
|
||||
field.blockSignals(False)
|
||||
|
||||
parent_layout = bubble.parent().layout()
|
||||
if parent_layout is not None:
|
||||
parent_layout.removeWidget(bubble)
|
||||
@@ -2055,11 +2121,14 @@ class MainApplication(QMainWindow):
|
||||
if self.folding_bypass:
|
||||
all_params['FOLDING_BYP'] = True
|
||||
|
||||
self.json_location = all_params['JSON_LOCATION']
|
||||
|
||||
collected_data = {
|
||||
"SNIRF_FILES": snirf_files,
|
||||
"PARAMS": all_params, # add this line
|
||||
"METADATA": self.get_all_metadata(), # optionally add metadata if needed
|
||||
}
|
||||
|
||||
# Start processing
|
||||
if current_process().name == 'MainProcess':
|
||||
self.result_queue = Queue()
|
||||
|
||||
Reference in New Issue
Block a user