mirror of
https://github.com/KeksPirates/SoftwareManager.git
synced 2026-08-03 17:39:42 +02:00
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.
This commit is contained in:
+205
-191
@@ -25,190 +25,198 @@ SVG_FOLDER = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path
|
||||
|
||||
|
||||
def settings_dialog(self):
|
||||
temp_image_width = state.image_width
|
||||
temp_image_offset = state.image_offset
|
||||
|
||||
def create_widget(widget_type, label_text, **kwargs):
|
||||
container = QWidget()
|
||||
layout = QHBoxLayout()
|
||||
container.setLayout(layout)
|
||||
layout.addWidget(QLabel(label_text))
|
||||
|
||||
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.setValue(state.image_width)
|
||||
|
||||
# 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)
|
||||
|
||||
# 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
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user