Enhanced specification for implementing the Application Settings Dialog that integrates with the centralized SettingsService (#100). The dialog shall provide a user-friendly interface for configuring dependency table visualization preferences, using Qt's Model/View architecture and standard configuration patterns.
Motivation
Users need a consistent, discoverable way to customize how dependency relationships are visualized in the BN Modeller. This dialog will:
- Provide runtime configuration of the dependency selection table (
dep_table)
- Persist user preferences using the centralized
SettingsService
- Follow Qt best practices for maintainability and extensibility
- Enable future expansion to other settings categories (visualization, analysis, etc.)
Technical Requirements
Dialog Architecture
Settings Dialog Structure
Page: "Dependency Table" (dep_table section)
| Setting Key |
UI Control |
Type |
Default |
Description |
depTable/colormap |
QComboBox (dropdown) |
str |
"viridis" |
Colormap for correlation strength visualization. Options: viridis, plasma, inferno, magma, coolwarm, RdYlGn |
UI Implementation Notes:
# Example: Colormap selector binding
colormap_combo = QComboBox()
colormap_combo.addItems(COLORMAP_OPTIONS)
# Bind to SettingsService via mapper or direct signal connection
settings = SettingsService.instance()
current = settings.get_value("depTable/colormap", "viridis")
colormap_combo.setCurrentText(current)
colormap_combo.currentTextChanged.connect(
lambda val: settings.set_value("depTable/colormap", val)
)
Extensibility Hooks
Integration with SettingsService (#100)
Acceptance Criteria
Implementation Plan
Suggested File Structure
bn_modeller/
├── dialogs/
│ ├── settings/
│ │ ├── __init__.py
│ │ ├── settings_dialog.py # Main ConfigDialog adaptation
│ │ ├── pages/
│ │ │ ├── __init__.py
│ │ │ ├── dep_table_page.py # Dependency table settings page
│ │ │ └── base_page.py # Abstract page interface
│ │ └── widgets/
│ │ ├── colormap_selector.py # Reusable colormap dropdown widget
│ │ └── preview_label.py # Optional: live colormap preview
│ └── __init__.py
├── utils/
│ └── settings_service.py # From issue #100 (dependency)
└── widgets/
└── dep_table.py # Existing: receives settingChanged signals
Key Code Snippets
# settings_dialog.py - Skeleton
class SettingsDialog(QDialog):
settingApplied = Signal() # Emitted on Apply/OK
def __init__(self, parent=None):
super().__init__(parent)
self._settings = SettingsService.instance()
self._setup_ui()
self._load_values()
def _setup_ui(self):
# Left: QListWidget for categories
# Right: QStackedWidget for pages
# Buttons: QDialogButtonBox with Apply/OK/Cancel/Reset
pass
def _load_values(self):
# Populate widgets from SettingsService
pass
def accept(self):
self._settings.sync() # Force write to disk [[1]]
self.settingApplied.emit()
super().accept()
Testing Strategy
def test_colormap_persistence(qtbot, tmp_path):
# Mock settings path
monkeypatch.setenv("QT_SETTINGS_PATH", str(tmp_path))
dialog = SettingsDialog()
dialog.show()
combo = dialog.findChild(QComboBox, "colormap_combo")
# Change value
qtbot.keyClicks(combo, "plasma")
qtbot.mouseClick(dialog.button_box.button(QDialogButtonBox.Apply), Qt.LeftButton)
# Verify persistence
settings = SettingsService.instance()
assert settings.get_value("depTable/colormap") == "plasma"
def test_live_update_signal(qtbot):
dep_table = DependencyTable() # Mock widget
dialog = SettingsDialog()
# Connect signal
settings = SettingsService.instance()
settings.settingChanged.connect(dep_table.update_colormap)
with qtbot.waitSignal(settings.settingChanged):
dialog._pages["dep_table"].colormap_combo.setCurrentText("coolwarm")
assert dep_table.colormap == "coolwarm"
References
Enhanced specification for implementing the Application Settings Dialog that integrates with the centralized
SettingsService(#100). The dialog shall provide a user-friendly interface for configuring dependency table visualization preferences, using Qt's Model/View architecture and standard configuration patterns.Motivation
Users need a consistent, discoverable way to customize how dependency relationships are visualized in the BN Modeller. This dialog will:
dep_table)SettingsServiceTechnical Requirements
Dialog Architecture
QStackedWidgetdisplaying category-specific configuration pagesAccept/Reject/ApplybuttonsSettingsService(QAbstractItemModel subclass from [FEATURE REQUEST] Implement Centralized Settings Service with Qt Integration #100) viaQDataWidgetMapperor custom delegates [[17]]QSettingsaccess in UI code — all persistence viaSettingsService.instance()settingChanged→ updatedep_tablecolormap without dialog restartQSettings::UserScopefor storage location (handled bySettingsService) [[1]]Settings Dialog Structure
Page: "Dependency Table" (
dep_tablesection)depTable/colormapQComboBox(dropdown)str"viridis"viridis,plasma,inferno,magma,coolwarm,RdYlGnUI Implementation Notes:
Extensibility Hooks
Integration with SettingsService (#100)
SettingsService.get_value(key)SettingsService.set_value(key, value)→ triggerssettingChangedsignalApplybutton: callsSettingsService.sync()to force disk writeResetbutton: usesSettingsService.reset_to_defaults(group="depTable")Acceptance Criteria
Edit → Settingsor toolbar gear icondepTable/colormapselection persists across application restartsdep_tablevisualization in real-time (via signal/slot)QSettingspath)Implementation Plan
Suggested File Structure
Key Code Snippets
Testing Strategy
References