diff --git a/src/ui/settings_window.py b/src/ui/settings_window.py index 4d34261..0bfdbff 100644 --- a/src/ui/settings_window.py +++ b/src/ui/settings_window.py @@ -6,7 +6,7 @@ import socket from datetime import datetime from PyQt6 import QtCore -from PyQt6.QtCore import Qt, QSettings +from PyQt6.QtCore import Qt, QSettings, pyqtSignal as Signal from PyQt6.QtGui import QIcon from PyQt6.QtWidgets import QApplication, QMainWindow, QListWidget, QListWidgetItem, QStackedWidget, QVBoxLayout, \ QWidget, QLabel, QCheckBox, QLineEdit, \ @@ -26,8 +26,12 @@ class SettingsWindow(QMainWindow): def __init__(self): super().__init__() + if not EngineManager.engines_path: # fix issue where sometimes path was not set + EngineManager.engines_path = system_safe_path( + os.path.join(os.path.join(os.path.expanduser(Config.upload_folder), + 'engines'))) + # declare objects we need to store settings - self.check_for_engine_updates_checkbox = None # todo: add all here self.installed_engines_table = None @@ -182,22 +186,29 @@ class SettingsWindow(QMainWindow): # Installed Engines Group installed_group = QGroupBox("Installed Engines") installed_layout = QVBoxLayout() + + # Setup table self.installed_engines_table = EngineTableWidget() + self.installed_engines_table.row_selected.connect(self.engine_table_selected) installed_layout.addWidget(self.installed_engines_table) + # Ignore system installs engine_ignore_system_installs_checkbox = QCheckBox("Ignore system installs") engine_ignore_system_installs_checkbox.setChecked(settings.value("engines_ignore_system_installs", False)) engine_ignore_system_installs_checkbox.stateChanged.connect(self.change_ignore_system_installs) installed_layout.addWidget(engine_ignore_system_installs_checkbox) + # Engine Launch / Delete buttons installed_buttons_layout = QHBoxLayout() - launch_engine_button = QPushButton("Launch") - launch_engine_button.clicked.connect(self.launch_selected_engine) - delete_engine_button = QPushButton("Delete") - delete_engine_button.clicked.connect(self.delete_selected_engine) + self.launch_engine_button = QPushButton("Launch") + self.launch_engine_button.setEnabled(False) + self.launch_engine_button.clicked.connect(self.launch_selected_engine) + self.delete_engine_button = QPushButton("Delete") + self.delete_engine_button.setEnabled(False) + self.delete_engine_button.clicked.connect(self.delete_selected_engine) - installed_buttons_layout.addWidget(launch_engine_button) - installed_buttons_layout.addWidget(delete_engine_button) + installed_buttons_layout.addWidget(self.launch_engine_button) + installed_buttons_layout.addWidget(self.delete_engine_button) installed_layout.addLayout(installed_buttons_layout) installed_group.setLayout(installed_layout) @@ -222,12 +233,12 @@ class SettingsWindow(QMainWindow): engine_updates_layout.addLayout(engine_download_layout) - self.check_for_engine_updates_checkbox = QCheckBox("Check for new versions on launch") - self.check_for_engine_updates_checkbox.setChecked(settings.value('check_for_engine_updates_on_launch', True)) - self.check_for_engine_updates_checkbox.setEnabled(at_least_one_downloadable) - self.check_for_engine_updates_checkbox.stateChanged.connect( + check_for_engine_updates_checkbox = QCheckBox("Check for new versions on launch") + check_for_engine_updates_checkbox.setChecked(settings.value('check_for_engine_updates_on_launch', True)) + check_for_engine_updates_checkbox.setEnabled(at_least_one_downloadable) + check_for_engine_updates_checkbox.stateChanged.connect( lambda state: settings.setValue("check_for_engine_updates_on_launch", bool(state))) - engine_updates_layout.addWidget(self.check_for_engine_updates_checkbox) + engine_updates_layout.addWidget(check_for_engine_updates_checkbox) self.engines_last_update_label = QLabel() self.update_last_checked_label() self.engines_last_update_label.setEnabled(at_least_one_downloadable) @@ -272,19 +283,47 @@ class SettingsWindow(QMainWindow): self.engines_last_update_label.setEnabled(at_least_one_downloadable) def delete_selected_engine(self): - pass + engine_info = self.installed_engines_table.selected_engine_data() + reply = QMessageBox.question(self, f"Delete {engine_info['engine']} {engine_info['version']}?", + f"Do you want to delete {engine_info['engine']} {engine_info['version']}?", + QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No) + + if reply is not QMessageBox.StandardButton.Yes: + return + + delete_result = EngineManager.delete_engine_download(engine_info.get('engine'), + engine_info.get('version'), + engine_info.get('system_os'), + engine_info.get('cpu')) + + if delete_result: + QMessageBox.information(self, f"{engine_info['engine']} {engine_info['version']} Deleted", + f"{engine_info['engine']} {engine_info['version']} deleted successfully", + QMessageBox.StandardButton.Ok) + else: + QMessageBox.warning(self, f"Unknown Error", + f"Unknown error while deleting {engine_info['engine']} {engine_info['version']}.", + QMessageBox.StandardButton.Ok) + + self.installed_engines_table.update_table(use_cached=False) def launch_selected_engine(self): engine_info = self.installed_engines_table.selected_engine_data() if engine_info: launch_url(engine_info['path']) - def check_for_new_engines(self): + def engine_table_selected(self): + engine_data = self.installed_engines_table.selected_engine_data() + if engine_data: + self.launch_engine_button.setEnabled(bool(engine_data.get('path') or True)) + self.delete_engine_button.setEnabled(engine_data.get('type') == 'managed') + else: + self.launch_engine_button.setEnabled(False) + self.delete_engine_button.setEnabled(False) - if not EngineManager.engines_path: # fix issue where sometimes path was not set - EngineManager.engines_path = system_safe_path( - os.path.join(os.path.join(os.path.expanduser(Config.upload_folder), - 'engines'))) + + + def check_for_new_engines(self): ignore_system = settings.value("engines_ignore_system_installs", False) messagebox_shown = False @@ -297,7 +336,7 @@ class SettingsWindow(QMainWindow): msg_box.setWindowTitle(f"{result['name']} ({result['version']}) Available") msg_box.setText(f"A new version of {result['name']} is available ({result['version']}).\n\n" f"Would you like to download it now?") - msg_box.setIcon(QMessageBox.Icon.Information) + msg_box.setIcon(QMessageBox.Icon.Question) msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No) msg_result = msg_box.exec() messagebox_shown = True @@ -327,6 +366,8 @@ class SettingsWindow(QMainWindow): class EngineTableWidget(QWidget): + row_selected = Signal() + def __init__(self): super().__init__() @@ -336,6 +377,7 @@ class EngineTableWidget(QWidget): self.table.verticalHeader().setVisible(False) # self.table_widget.itemSelectionChanged.connect(self.engine_picked) self.table.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers) + self.table.selectionModel().selectionChanged.connect(self.on_selection_changed) layout = QVBoxLayout(self) layout.addWidget(self.table) @@ -382,7 +424,7 @@ class EngineTableWidget(QWidget): """Returns the data from the selected row as a dictionary.""" row = self.table.currentRow() # Get the selected row index - if row < 0: # No row selected + if row < 0 or not len(self.table.selectedItems()): # No row selected return None data = { @@ -394,6 +436,9 @@ class EngineTableWidget(QWidget): return data + def on_selection_changed(self): + self.row_selected.emit() + if __name__ == "__main__":