From a3ff23147f163f1d6be22a477f137fe1f4973f2c Mon Sep 17 00:00:00 2001 From: Vxrtrauter <101264710+Vxrtrauter@users.noreply.github.com> Date: Sat, 4 Apr 2026 05:36:16 +0200 Subject: [PATCH] Restore image settings on cancel; live sync Save original image_width/image_offset when opening Settings and restore them if the dialog is cancelled. Add valueChanged handlers to immediately update state.image_width and state.image_offset, enforce an image width maximum of 2500, and refactor Save wiring to a dedicated handler that calls save_settings(dialog.accept, ...). Connect dialog.finished to restore temp values on rejection and clean up dialog layout/logic. --- src/interface/dialogs/settings.py | 396 ++++++++++++++++-------------- 1 file changed, 205 insertions(+), 191 deletions(-) diff --git a/src/interface/dialogs/settings.py b/src/interface/dialogs/settings.py index b0992a2..047fdb2 100644 --- a/src/interface/dialogs/settings.py +++ b/src/interface/dialogs/settings.py @@ -25,190 +25,198 @@ SVG_FOLDER = '= 0: - interface_select.setCurrentIndex(index) - else: - interface_select.setCurrentIndex(0) - - interface_select.setFixedWidth(180) - interface_select.setFixedHeight(30) - interface_layout.addWidget(interface_select) - interface_container.setLayout(interface_layout) - - - # Save / Cancel buttons + def create_widget(widget_type, label_text, **kwargs): + container = QWidget() layout = QHBoxLayout() + container.setLayout(layout) + layout.addWidget(QLabel(label_text)) - save_btn = QPushButton("Save") - cancel_btn = QPushButton("Cancel") - save_btn.clicked.connect(lambda: save_settings( - close_settings, + widget = widget_type() + + if widget_type in (QSpinBox,): + layout.addWidget(widget) + widget.setMinimum(kwargs.get("minimum", 0)) + widget.setMaximum(kwargs.get("maximum", 10000000)) + widget.setFixedWidth(kwargs.get("width", 180)) + widget.setFixedHeight(kwargs.get("height", 30)) + elif widget_type in (QCheckBox,): + layout.addStretch() + layout.addWidget(widget) + elif widget_type in (QLineEdit,): + layout.addWidget(widget) + container.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed) + if "width" in kwargs: + widget.setFixedWidth(kwargs["width"]) + if "height" in kwargs: + widget.setFixedHeight(kwargs["height"]) + elif widget_type in (QComboBox,): + layout.addWidget(widget) + widget.setFixedWidth(kwargs.get("width", 180)) + widget.setFixedHeight(kwargs.get("height", 30)) + + return container, widget + + consoleLog("Settings dialog opened") + dialog = QDialog(self) + dialog.setWindowTitle("Settings") + dialog.setFixedSize(580, 400) + + dialog_layout = QVBoxLayout() + dialog.setLayout(dialog_layout) + + if state.window_transparency and platform.system() != "Windows" and dialog: + dialog.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) + + def close_settings(): + dialog.reject() + + # Ignore Updates checkbox + update_checkbox_container, update_checkbox = create_widget(QCheckBox, "Ignore Updates: ") + if platform.system() == "Windows": + update_checkbox.setChecked(state.ignore_updates) + update_checkbox.toggled.connect(lambda checked: setattr(state, 'ignore_updates', checked)) + + # Autoresume Container Checkbox + autoresume_container, autoresume_checkbox = create_widget(QCheckBox, "Auto-Resume Downloads: ") + autoresume_checkbox.setChecked(state.autoresume) + autoresume_checkbox.toggled.connect(lambda checked: setattr(state, 'autoresume', checked)) + + # Transparent Window Checkbox + transparent_window_container, transparent_window_checkbox = create_widget(QCheckBox, "Window Transparency (requires restart) (Linux/MacOS only): ") + transparent_window_checkbox.setChecked(state.window_transparency) + transparent_window_checkbox.toggled.connect(lambda checked: setattr(state, 'window_transparency', checked)) + + # API URL Widget + api_url_container, api_url = create_widget(QLineEdit, "API Server URL: ", width=180, height=30) + api_url.setText(state.api_url) + + # Download Path Widget + download_path_container, download_path = create_widget(QLineEdit, "Download Path: ") + download_path.setText(state.download_path) + download_path_layout = download_path_container.layout() + + def browse_download_path(): + dir_path = QFileDialog.getExistingDirectory(dialog, "Select Download Directory", state.download_path) + if dir_path: + download_path.setText(dir_path) + + browse_button = create_widget(QPushButton, "", width=36, height=36)[1] + browse_button.setIconSize(QSize(24, 24)) + browse_button.setIcon(svg_icon(SVG_FOLDER, 24)) + browse_button.setCursor(Qt.CursorShape.PointingHandCursor) + browse_button.setStyleSheet(""" + QPushButton { + border: none; + background: transparent; + padding: 0px; + } + """) + + download_path_layout.addWidget(browse_button) + browse_button.clicked.connect(browse_download_path) + + + # Image Path + image_path_container, image_path = create_widget(QLineEdit, "Image Path: ") + image_path.setText(state.image_path) + image_path_layout = image_path_container.layout() + + def browse_image_path(): + file_path = QFileDialog.getOpenFileName(dialog, "Select Image File", state.image_path, "Image Files (*.png *.jpg)")[0] + if file_path: + image_path.setText(file_path) + + browse_button = create_widget(QPushButton, "", width=36, height=36)[1] + browse_button.setIconSize(QSize(24, 24)) + browse_button.setIcon(svg_icon(SVG_FOLDER, 24)) + browse_button.setCursor(Qt.CursorShape.PointingHandCursor) + browse_button.setStyleSheet(""" + QPushButton { + border: none; + background: transparent; + padding: 0px; + } + """) + image_path_layout.addWidget(browse_button) + browse_button.clicked.connect(browse_image_path) + + # Enable Image Checkbox + enable_image_container, enable_image_checkbox = create_widget(QCheckBox, "Enable Image (needs Image Path): ", width=180, height=30) + enable_image_checkbox.setChecked(state.image_enabled) + enable_image_checkbox.toggled.connect(lambda checked: setattr(state, 'image_enabled', checked)) + + # Image Width SpinBox + image_width_container, image_width = create_widget(QSpinBox, "Image Width: ", width=180, height=30) + image_width.setMinimum(0) + image_width.setMaximum(2500) + image_width.setValue(state.image_width) + image_width.valueChanged.connect(lambda val: setattr(state, 'image_width', val)) + + # Image Offset SpinBox + image_offset_container, image_offset = create_widget(QSpinBox, "Corner Image Offset: ", width=180, height=30) + image_offset.setMinimum(0) + image_offset.setValue(state.image_offset) + image_offset.valueChanged.connect(lambda val: setattr(state, 'image_offset', val)) + + # Speed Limiting + down_speed_limit_container, down_speed_limit = create_widget(QSpinBox, "Max Download Speed (KiB, 0 for unlimited): ", width=180, height=30) + down_speed_limit.setMinimum(0) + down_speed_limit.setValue(state.down_speed_limit) + + up_speed_limit_container, up_speed_limit = create_widget(QSpinBox, "Max Upload Speed (KiB, 0 for unlimited): ", width=180, height=30) + up_speed_limit.setMinimum(0) + up_speed_limit.setValue(state.up_speed_limit) + + # Connection Configs + max_connections_container, max_connections = create_widget(QSpinBox, "Max Connections: ", width=180, height=30) + max_connections.setMinimum(0) + max_connections.setValue(state.max_connections) + + + # Download Configs + max_downloads_container, max_downloads = create_widget(QSpinBox, "Max Downloads: ", width=180, height=30) + max_downloads.setMinimum(0) + max_downloads.setValue(state.max_downloads) + + # Interface Binding + interface_container = QWidget() + interface_layout = QHBoxLayout() + + interface_label = QLabel("Network Interface:") + interface_layout.addWidget(interface_label) + interface_select = QComboBox() + interface_select.addItems(["None"] + state.interfaces) + + target = state.bound_interface if state.bound_interface else "None" + + index = interface_select.findText(target) + if index >= 0: + interface_select.setCurrentIndex(index) + else: + interface_select.setCurrentIndex(0) + + interface_select.setFixedWidth(180) + interface_select.setFixedHeight(30) + interface_layout.addWidget(interface_select) + interface_container.setLayout(interface_layout) + + + # Save / Cancel buttons + layout = QHBoxLayout() + + save_btn = QPushButton("Save") + cancel_btn = QPushButton("Cancel") + save_btn.clicked.connect(lambda: handle_save()) + + def handle_save(): + save_settings( + dialog.accept, api_url.text(), download_path.text(), - down_speed_limit.value(), + down_speed_limit.value(), up_speed_limit.value(), image_path.text(), autoresume_checkbox.isChecked(), @@ -217,20 +225,26 @@ def settings_dialog(self): interface_select.currentText(), image_width.value(), image_offset.value() - )) + ) - cancel_btn.clicked.connect(dialog.reject) - layout.addWidget(cancel_btn) - layout.addWidget(save_btn) + cancel_btn.clicked.connect(dialog.reject) + layout.addWidget(cancel_btn) + layout.addWidget(save_btn) - tabs = QtWidgets.QTabWidget() - create_tab("General", [autoresume_container, update_checkbox_container, transparent_window_container], tabs=tabs, stretch=True) - create_tab("Image", [enable_image_container, image_width_container, image_offset_container], tabs=tabs, stretch=True) - create_tab("Paths", [download_path_container, image_path_container], tabs=tabs, stretch=True) - create_tab("Network", [interface_container, max_connections_container, max_downloads_container, up_speed_limit_container, down_speed_limit_container, api_url_container], tabs=tabs, stretch=True) + tabs = QtWidgets.QTabWidget() + create_tab("General", [autoresume_container, update_checkbox_container, transparent_window_container], tabs=tabs, stretch=True) + create_tab("Image", [enable_image_container, image_width_container, image_offset_container], tabs=tabs, stretch=True) + create_tab("Paths", [download_path_container, image_path_container], tabs=tabs, stretch=True) + create_tab("Network", [interface_container, max_connections_container, max_downloads_container, up_speed_limit_container, down_speed_limit_container, api_url_container], tabs=tabs, stretch=True) - dialog_layout.addWidget(tabs) - dialog_layout.addLayout(layout) + dialog_layout.addWidget(tabs) + dialog_layout.addLayout(layout) - dialog.exec() + def on_dialog_finished(result): + if result == QtWidgets.QDialog.DialogCode.Rejected: + state.image_width = temp_image_width + state.image_offset = temp_image_offset + + dialog.finished.connect(on_dialog_finished) + dialog.exec()