from pathlib import Path from PySide6.QtCore import QSettings, Signal from PySide6.QtWidgets import QDialog, QFileDialog, QFormLayout, QGroupBox, QSpinBox from bedit.core.libraries import default_library_paths from bedit.gui.preferences import application_settings from bedit.gui.generated.ui_settings_dialog import Ui_SettingsDialog class SettingsDialog(QDialog): """Edit application preferences defined in the Designer form.""" settingsChanged = Signal() def __init__(self, parent=None) -> None: super().__init__(parent) self.ui = Ui_SettingsDialog() self.ui.setupUi(self) self.grid_group = QGroupBox("Editor grids", self.ui.generalTab) grid_form = QFormLayout(self.grid_group) self.graph_grid_spin = QSpinBox() self.graph_grid_spin.setRange(8, 512) self.graph_grid_spin.setSuffix(" units") self.graph_snap_spin = QSpinBox() self.graph_snap_spin.setRange(1, 128) self.graph_snap_spin.setSuffix(" units") self.graph_grid_spin.valueChanged.connect(self.graph_snap_spin.setMaximum) self.icon_grid_spin = QSpinBox() self.icon_grid_spin.setRange(1, 64) self.icon_grid_spin.setSuffix(" units") grid_form.addRow("Workspace grid size:", self.graph_grid_spin) grid_form.addRow("Workspace snapping size:", self.graph_snap_spin) grid_form.addRow("Icon grid size:", self.icon_grid_spin) self.ui.generalLayout.insertWidget(1, self.grid_group) self.settings = application_settings() self.ui.addLibraryFileButton.clicked.connect(self._add_library_file) self.ui.addLibraryFolderButton.clicked.connect(self._add_library_folder) self.ui.removeLibraryPathButton.clicked.connect(self._remove_library_path) self.ui.libraryPathsList.itemSelectionChanged.connect(self._update_remove_button) self._load_settings() def _load_settings(self) -> None: enabled = self.settings.value("autosave/enabled", None) if enabled is None: enabled = self.settings.value("General/autosaveEnabled", False) interval = self.settings.value("autosave/intervalMinutes", None) if interval is None: interval = self.settings.value("General/autosaveInterval", 5) self.ui.autosaveGroupBox.setChecked( self._as_bool(enabled) ) self.ui.autosaveIntervalSpinBox.setValue(int(interval)) self.ui.libraryPathsList.clear() self.ui.libraryPathsList.addItems(self.library_paths(self.settings)) self.graph_grid_spin.setValue(self.graph_grid_size(self.settings)) self.graph_snap_spin.setValue(self.graph_snap_size(self.settings)) self.icon_grid_spin.setValue(self.icon_grid_size(self.settings)) self._update_remove_button() @staticmethod def _as_bool(value) -> bool: if isinstance(value, str): return value.strip().lower() in {"1", "true", "yes", "on"} return bool(value) @staticmethod def library_paths(settings: QSettings | None = None) -> list[str]: settings = settings if settings is not None else application_settings() value = settings.value("libraries/paths", default_library_paths()) if isinstance(value, str): return [value] return [str(path) for path in value] @staticmethod def graph_grid_size(settings: QSettings | None = None) -> int: settings = settings if settings is not None else application_settings() return settings.value("grid/graphSize", 64, type=int) @staticmethod def graph_snap_size(settings: QSettings | None = None) -> int: settings = settings if settings is not None else application_settings() return settings.value("grid/graphSnapSize", 8, type=int) @staticmethod def icon_grid_size(settings: QSettings | None = None) -> int: settings = settings if settings is not None else application_settings() return settings.value("grid/iconSize", 8, type=int) def _add_library_file(self) -> None: path, _ = QFileDialog.getOpenFileName( self, "Add library", "", "BEdit libraries (*.json);;All files (*)", ) if path: self._append_unique_path(path) def _add_library_folder(self) -> None: path = QFileDialog.getExistingDirectory(self, "Add library folder") if path: self._append_unique_path(path) def _append_unique_path(self, path: str) -> None: normalized = str(Path(path).expanduser().resolve()) existing = { self.ui.libraryPathsList.item(row).text() for row in range(self.ui.libraryPathsList.count()) } if normalized not in existing: self.ui.libraryPathsList.addItem(normalized) def _remove_library_path(self) -> None: for item in self.ui.libraryPathsList.selectedItems(): self.ui.libraryPathsList.takeItem(self.ui.libraryPathsList.row(item)) def _update_remove_button(self) -> None: self.ui.removeLibraryPathButton.setEnabled(bool(self.ui.libraryPathsList.selectedItems())) def accept(self) -> None: self.settings.setValue("autosave/enabled", self.ui.autosaveGroupBox.isChecked()) self.settings.setValue( "autosave/intervalMinutes", self.ui.autosaveIntervalSpinBox.value() ) self.settings.remove("General/autosaveEnabled") self.settings.remove("General/autosaveInterval") paths = [ self.ui.libraryPathsList.item(row).text() for row in range(self.ui.libraryPathsList.count()) ] self.settings.setValue("libraries/paths", paths) self.settings.setValue("grid/graphSize", self.graph_grid_spin.value()) self.settings.setValue("grid/graphSnapSize", self.graph_snap_spin.value()) self.settings.setValue("grid/iconSize", self.icon_grid_spin.value()) self.settings.sync() self.settingsChanged.emit() super().accept()