From 121dbb788d051c76375261cd18fa8dca0f23b935 Mon Sep 17 00:00:00 2001 From: Warry Date: Sun, 30 Nov 2025 15:37:32 +0100 Subject: feat: refactor settings UI with category navigation and add Delimiters page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #640 ## Changes ### UI Refactoring - Replace monolithic settings dialog with category-based navigation - Add QListWidget (lw_categories) for category selection on the left - Add QStackedWidget (sw_categories) for content pages on the right - Organize settings into 5 distinct pages: - Flags (14 checkboxes) - Quality (3 combo boxes) - Numbers (2 spin boxes) - Paths & Formats (7 line edits + 2 browse buttons) - Delimiters (4 line edits) — NEW ### New Feature: Delimiters Category - Add customizable separators for artists in metadata and filenames: - metadata_delimiter_artist - metadata_delimiter_album_artist - filename_delimiter_artist - filename_delimiter_album_artist - Auto-integration with DialogPreferences via parameters_line_edit - Line edits with max width 100px for compact display ### Styling - Apply dark theme to settings dialog: - Category list: #2b2b2b background, #3d5a80 selection, #3a3a3a hover - Settings area: #333333 background, styled GroupBoxes (#3a3a3a) - Light text (#e0e0e0) for better contrast - Add spacing property (6px) to category list for better readability - Style QListWidget items with padding (4px 3px) and margin (2px 0px) ### Testing - Add comprehensive test suite (61 tests total): - test_settings_ui.py: UI and basic integration (14 tests) - test_settings_dialog_structure.py: detailed structure validation (20 tests) - test_dialog_preferences_integration.py: DialogPreferences integration (14 tests) - test_delimiters_category.py: new Delimiters page validation (13 tests) - Fix ruff issues (F841, S108) in test files - All tests passing with 100% success rate ### Documentation - Add docs/refactor_settings_ui.md: comprehensive refactor overview - Add docs/delimiters_category.md: Delimiters feature documentation - Add docs/ui_styles.md: dark theme style guide - Add docs/testing_summary.md: testing overview and commands ### Code Quality - Apply ruff/black/pyupgrade via pre-commit hooks - Fix F841 (unused variable) in test_dialog_preferences_integration.py - Fix S108 (insecure temp path) using Path.home() in test_settings_ui.py - End-of-file fixes applied automatically ## Files Modified - tidal_dl_ng/ui/dialog_settings.ui (complete restructure) - tidal_dl_ng/ui/dialog_settings.py (auto-generated from .ui) - tidal_dl_ng/dialog.py (add 4 delimiter params + Delimiters category) - tests/* (4 new test files with 61 tests) - docs/* (4 new documentation files) ## Impact - Improved UX: intuitive category navigation, better visual organization - Extensibility: easy to add new settings pages/categories - Quality: comprehensive test coverage ensures robustness - User flexibility: customizable separators for metadata and filenames ## Technical Notes - QStackedWidget pages indexed 0-4 matching category list order - Navigation via QListWidget::currentRowChanged signal - Automatic save/load through existing DialogPreferences methods - No breaking changes to existing settings or configuration ## Testing Commands ```powershell poetry run pre-commit run -a poetry run pytest -q --- tidal_dl_ng/dialog.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'tidal_dl_ng/dialog.py') diff --git a/tidal_dl_ng/dialog.py b/tidal_dl_ng/dialog.py index 8cb93f6..7d6a93f 100644 --- a/tidal_dl_ng/dialog.py +++ b/tidal_dl_ng/dialog.py @@ -144,6 +144,10 @@ class DialogPreferences(QtWidgets.QDialog): # Run the .setupUi() method to show the GUI self.ui.setupUi(self) + + # Initialize categories + self._init_categories() + # Set data. self.gui_populate() # Post setup @@ -159,6 +163,10 @@ class DialogPreferences(QtWidgets.QDialog): "format_track", "format_video", "path_binary_ffmpeg", + "metadata_delimiter_artist", + "metadata_delimiter_album_artist", + "filename_delimiter_artist", + "filename_delimiter_album_artist", ] def _init_spin_box(self): @@ -189,6 +197,25 @@ class DialogPreferences(QtWidgets.QDialog): "playlist_create", ] + def _init_categories(self): + """Initialize the categories list and connect to page switching.""" + # Add categories to the list + self.ui.lw_categories.addItem("Flags") + self.ui.lw_categories.addItem("Quality") + self.ui.lw_categories.addItem("Numbers") + self.ui.lw_categories.addItem("Paths & Formats") + self.ui.lw_categories.addItem("Delimiters") + + # Set the first category as selected + self.ui.lw_categories.setCurrentRow(0) + + # Connect category selection to page switching + self.ui.lw_categories.currentRowChanged.connect(self._on_category_changed) + + def _on_category_changed(self, index: int): + """Handle category change to switch pages.""" + self.ui.sw_categories.setCurrentIndex(index) + def gui_populate(self): self.populate_checkboxes() self.populate_combo() -- cgit v1.3.1