"""Application Preferences dialog.""" from PyQt6.QtWidgets import ( QDialog, QVBoxLayout, QFormLayout, QGroupBox, QComboBox, QSpinBox, QCheckBox, QDialogButtonBox, QLabel, ) from PyQt6.QtCore import pyqtSignal from app.config.settings import get_settings _FONT_FAMILIES = ["Consolas", "JetBrains Mono", "Fira Code", "Cascadia Code", "Courier New"] _PAGE_SIZES = [50, 100, 500, 1000, 0] # 0 → All _PAGE_LABELS = ["50", "100", "500", "1 000", "All"] class PreferencesDialog(QDialog): settings_applied = pyqtSignal() def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("Preferences") self.setMinimumWidth(400) self.resize(420, 380) self._build_ui() self._load() def _build_ui(self): root = QVBoxLayout(self) root.setSpacing(12) root.setContentsMargins(16, 16, 16, 16) # ── SQL Editor ──────────────────────────────────────────────────────── editor_box = QGroupBox("SQL Editor") ef = QFormLayout(editor_box) ef.setSpacing(8) self._font_family = QComboBox() self._font_family.addItems(_FONT_FAMILIES) ef.addRow("Font family:", self._font_family) self._font_size = QSpinBox() self._font_size.setRange(8, 28) self._font_size.setSuffix(" pt") ef.addRow("Font size:", self._font_size) self._word_wrap = QCheckBox("Word wrap") ef.addRow("", self._word_wrap) root.addWidget(editor_box) # ── Results ─────────────────────────────────────────────────────────── results_box = QGroupBox("Results") rf = QFormLayout(results_box) rf.setSpacing(8) self._page_size = QComboBox() for lbl in _PAGE_LABELS: self._page_size.addItem(lbl) rf.addRow("Default page size:", self._page_size) self._timeout = QSpinBox() self._timeout.setRange(5, 600) self._timeout.setSuffix(" s") rf.addRow("Query timeout:", self._timeout) root.addWidget(results_box) # ── General ─────────────────────────────────────────────────────────── general_box = QGroupBox("General") gf = QFormLayout(general_box) gf.setSpacing(8) self._max_history = QSpinBox() self._max_history.setRange(50, 10_000) self._max_history.setSingleStep(100) gf.addRow("Max history entries:", self._max_history) self._auto_commit = QCheckBox("Auto-commit queries") gf.addRow("", self._auto_commit) root.addWidget(general_box) root.addStretch() # ── Buttons ─────────────────────────────────────────────────────────── note = QLabel("Font changes take effect immediately in open editors.") note.setObjectName("statusLabel") root.addWidget(note) bb = QDialogButtonBox( QDialogButtonBox.StandardButton.Cancel | QDialogButtonBox.StandardButton.Apply | QDialogButtonBox.StandardButton.Ok ) bb.rejected.connect(self.reject) bb.button(QDialogButtonBox.StandardButton.Apply).clicked.connect(self._apply) bb.accepted.connect(self._ok) root.addWidget(bb) # ── Load / save ─────────────────────────────────────────────────────────── def _load(self): s = get_settings() family = s.get("font_family", "Consolas") idx = self._font_family.findText(family) self._font_family.setCurrentIndex(max(idx, 0)) self._font_size.setValue(s.get("font_size", 13)) self._word_wrap.setChecked(s.get("word_wrap", False)) page = s.get("result_page_size", 100) pi = _PAGE_SIZES.index(page) if page in _PAGE_SIZES else 1 self._page_size.setCurrentIndex(pi) self._timeout.setValue(s.get("query_timeout", 60)) self._max_history.setValue(s.get("max_history", 500)) self._auto_commit.setChecked(s.get("auto_commit", True)) def _apply(self): s = get_settings() s.set("font_family", self._font_family.currentText()) s.set("font_size", self._font_size.value()) s.set("word_wrap", self._word_wrap.isChecked()) s.set("result_page_size", _PAGE_SIZES[self._page_size.currentIndex()]) s.set("query_timeout", self._timeout.value()) s.set("max_history", self._max_history.value()) s.set("auto_commit", self._auto_commit.isChecked()) s.save() self.settings_applied.emit() def _ok(self): self._apply() self.accept()