From e29122f3b152c1bfbb871ea7f5d3241019f6a01e Mon Sep 17 00:00:00 2001 From: purpletennisball <212221402+purpletennisball@users.noreply.github.com> Date: Sat, 4 Jul 2026 13:04:41 -0400 Subject: [PATCH 1/4] feat(ui): organize settings into new panels --- src/tagstudio/qt/mixed/settings_panel.py | 168 +++++++++++++---------- 1 file changed, 96 insertions(+), 72 deletions(-) diff --git a/src/tagstudio/qt/mixed/settings_panel.py b/src/tagstudio/qt/mixed/settings_panel.py index 0a82c12e9..db63bc0f0 100644 --- a/src/tagstudio/qt/mixed/settings_panel.py +++ b/src/tagstudio/qt/mixed/settings_panel.py @@ -98,6 +98,9 @@ def __init__(self, driver: "QtDriver"): self.root_layout.setContentsMargins(0, 6, 0, 0) self.library_settings_container = QWidget() + self.appearence_settings_container = QWidget() + self.localization_settings_container = QWidget() + self.media_settings_container = QWidget() # Tabs self.tab_widget = QTabWidget() @@ -105,6 +108,15 @@ def __init__(self, driver: "QtDriver"): self.__build_global_settings() self.tab_widget.addTab(self.global_settings_container, Translations["settings.global"]) + self.__build_appearence_settings() + self.tab_widget.addTab(self.appearence_settings_container, "Appearence") + + self.__build_localization_settings() + self.tab_widget.addTab(self.localization_settings_container, "Localization") + + self.__build_media_settings() + self.tab_widget.addTab(self.media_settings_container, "Media") + # self.__build_library_settings() # self.tab_widget.addTab(self.library_settings_container, Translations["settings.library"]) @@ -153,54 +165,6 @@ def __build_global_settings(self): Translations["settings.open_library_on_start"], self.open_last_lib_checkbox ) - # Generate Thumbnails - self.generate_thumbs = QCheckBox() - self.generate_thumbs.setChecked(self.driver.settings.generate_thumbs) - form_layout.addRow(Translations["settings.generate_thumbs"], self.generate_thumbs) - - # Thumbnail Cache Size - self.thumb_cache_size_container = QWidget() - self.thumb_cache_size_layout = QHBoxLayout(self.thumb_cache_size_container) - self.thumb_cache_size_layout.setContentsMargins(0, 0, 0, 0) - self.thumb_cache_size_layout.setSpacing(6) - self.thumb_cache_size = QLineEdit() - self.thumb_cache_size.setAlignment(Qt.AlignmentFlag.AlignRight) - self.thumb_cache_size_validator = QDoubleValidator( - MIN_THUMB_CACHE_SIZE, 1_000_000_000, 2 - ) # High limit - self.thumb_cache_size.setValidator(self.thumb_cache_size_validator) - self.thumb_cache_size.setText( - str(max(self.driver.settings.thumb_cache_size, MIN_THUMB_CACHE_SIZE)).removesuffix(".0") - ) - self.thumb_cache_size_layout.addWidget(self.thumb_cache_size) - self.thumb_cache_size_layout.setStretch(1, 2) - self.thumb_cache_size_layout.addWidget(QLabel("MiB")) - form_layout.addRow( - Translations["settings.thumb_cache_size.label"], self.thumb_cache_size_container - ) - - # Cached Thumbnail Resolution - self.cached_thumb_res_container = QWidget() - self.cached_thumb_res_layout = QHBoxLayout(self.cached_thumb_res_container) - self.cached_thumb_res_layout.setContentsMargins(0, 0, 0, 0) - self.cached_thumb_res_layout.setSpacing(6) - self.cached_thumb_res = QLineEdit() - self.cached_thumb_res.setAlignment(Qt.AlignmentFlag.AlignRight) - self.cached_thumb_res_validator = QIntValidator(MIN_CACHED_THUMB_RES, MAX_CACHED_THUMB_RES) - self.cached_thumb_res.setValidator(self.cached_thumb_res_validator) - self.cached_thumb_res.setText(str(self.driver.settings.cached_thumb_resolution)) - self.cached_thumb_res_layout.addWidget(self.cached_thumb_res) - self.cached_thumb_res_layout.setStretch(1, 2) - self.cached_thumb_res_layout.addWidget(QLabel("px")) - form_layout.addRow( - Translations["settings.cached_thumb_resolution.label"], self.cached_thumb_res_container - ) - - # Autoplay - self.autoplay_checkbox = QCheckBox() - self.autoplay_checkbox.setChecked(self.driver.settings.autoplay) - form_layout.addRow(Translations["media_player.autoplay"], self.autoplay_checkbox) - # Scan for new files when a library is opened self.scan_files_on_open_checkbox = QCheckBox() self.scan_files_on_open_checkbox.setChecked(self.driver.settings.scan_files_on_open) @@ -262,26 +226,69 @@ def on_page_size_changed(): Translations["settings.tag_click_action.label"], self.tag_click_action_combobox ) - # Dark Mode - self.theme_combobox = QComboBox() - for k in SettingsPanel.theme_map: - self.theme_combobox.addItem(SettingsPanel.theme_map[k], k) - theme = self.driver.settings.theme - if theme not in SettingsPanel.theme_map: - theme = Theme.DEFAULT - self.theme_combobox.setCurrentIndex(list(SettingsPanel.theme_map.keys()).index(theme)) - self.theme_combobox.currentIndexChanged.connect(self.__update_restart_label) - form_layout.addRow(Translations["settings.theme.label"], self.theme_combobox) + # TODO: Implement Library Settings + def __build_library_settings(self): # pyright: ignore[reportUnusedFunction] + form_layout = QFormLayout(self.library_settings_container) + form_layout.setContentsMargins(6, 6, 6, 6) - # Splash Screen - self.splash_combobox = QComboBox() - for k in SettingsPanel.splash_map: - self.splash_combobox.addItem(SettingsPanel.splash_map[k], k) - splash = self.driver.settings.splash - if splash not in SettingsPanel.splash_map: - splash = Splash.DEFAULT - self.splash_combobox.setCurrentIndex(list(SettingsPanel.splash_map.keys()).index(splash)) - form_layout.addRow(Translations["settings.splash.label"], self.splash_combobox) + todo_label = QLabel("TODO") + form_layout.addRow(todo_label) + + def __build_media_settings(self): + form_layout = QFormLayout(self.media_settings_container) + form_layout.setContentsMargins(6, 6, 6, 6) + + # Autoplay + self.autoplay_checkbox = QCheckBox() + self.autoplay_checkbox.setChecked(self.driver.settings.autoplay) + form_layout.addRow(Translations["media_player.autoplay"], self.autoplay_checkbox) + + # Generate Thumbnails + self.generate_thumbs = QCheckBox() + self.generate_thumbs.setChecked(self.driver.settings.generate_thumbs) + form_layout.addRow(Translations["settings.generate_thumbs"], self.generate_thumbs) + + # Thumbnail Cache Size + self.thumb_cache_size_container = QWidget() + self.thumb_cache_size_layout = QHBoxLayout(self.thumb_cache_size_container) + self.thumb_cache_size_layout.setContentsMargins(0, 0, 0, 0) + self.thumb_cache_size_layout.setSpacing(6) + self.thumb_cache_size = QLineEdit() + self.thumb_cache_size.setAlignment(Qt.AlignmentFlag.AlignRight) + self.thumb_cache_size_validator = QDoubleValidator( + MIN_THUMB_CACHE_SIZE, 1_000_000_000, 2 + ) # High limit + self.thumb_cache_size.setValidator(self.thumb_cache_size_validator) + self.thumb_cache_size.setText( + str(max(self.driver.settings.thumb_cache_size, MIN_THUMB_CACHE_SIZE)).removesuffix(".0") + ) + self.thumb_cache_size_layout.addWidget(self.thumb_cache_size) + self.thumb_cache_size_layout.setStretch(1, 2) + self.thumb_cache_size_layout.addWidget(QLabel("MiB")) + form_layout.addRow( + Translations["settings.thumb_cache_size.label"], self.thumb_cache_size_container + ) + + # Cached Thumbnail Resolution + self.cached_thumb_res_container = QWidget() + self.cached_thumb_res_layout = QHBoxLayout(self.cached_thumb_res_container) + self.cached_thumb_res_layout.setContentsMargins(0, 0, 0, 0) + self.cached_thumb_res_layout.setSpacing(6) + self.cached_thumb_res = QLineEdit() + self.cached_thumb_res.setAlignment(Qt.AlignmentFlag.AlignRight) + self.cached_thumb_res_validator = QIntValidator(MIN_CACHED_THUMB_RES, MAX_CACHED_THUMB_RES) + self.cached_thumb_res.setValidator(self.cached_thumb_res_validator) + self.cached_thumb_res.setText(str(self.driver.settings.cached_thumb_resolution)) + self.cached_thumb_res_layout.addWidget(self.cached_thumb_res) + self.cached_thumb_res_layout.setStretch(1, 2) + self.cached_thumb_res_layout.addWidget(QLabel("px")) + form_layout.addRow( + Translations["settings.cached_thumb_resolution.label"], self.cached_thumb_res_container + ) + + def __build_localization_settings(self): + form_layout = QFormLayout(self.localization_settings_container) + form_layout.setContentsMargins(6, 6, 6, 6) # Date Format self.dateformat_combobox = QComboBox() @@ -306,13 +313,30 @@ def on_page_size_changed(): self.zeropadding_checkbox.setChecked(self.driver.settings.zero_padding) form_layout.addRow(Translations["settings.zeropadding.label"], self.zeropadding_checkbox) - # TODO: Implement Library Settings - def __build_library_settings(self): # pyright: ignore[reportUnusedFunction] - form_layout = QFormLayout(self.library_settings_container) + def __build_appearence_settings(self): + form_layout = QFormLayout(self.appearence_settings_container) form_layout.setContentsMargins(6, 6, 6, 6) - todo_label = QLabel("TODO") - form_layout.addRow(todo_label) + # Dark Mode + self.theme_combobox = QComboBox() + for k in SettingsPanel.theme_map: + self.theme_combobox.addItem(SettingsPanel.theme_map[k], k) + theme = self.driver.settings.theme + if theme not in SettingsPanel.theme_map: + theme = Theme.DEFAULT + self.theme_combobox.setCurrentIndex(list(SettingsPanel.theme_map.keys()).index(theme)) + self.theme_combobox.currentIndexChanged.connect(self.__update_restart_label) + form_layout.addRow(Translations["settings.theme.label"], self.theme_combobox) + + # Splash Screen + self.splash_combobox = QComboBox() + for k in SettingsPanel.splash_map: + self.splash_combobox.addItem(SettingsPanel.splash_map[k], k) + splash = self.driver.settings.splash + if splash not in SettingsPanel.splash_map: + splash = Splash.DEFAULT + self.splash_combobox.setCurrentIndex(list(SettingsPanel.splash_map.keys()).index(splash)) + form_layout.addRow(Translations["settings.splash.label"], self.splash_combobox) def get_settings(self) -> dict[str, Any]: # pyright: ignore[reportExplicitAny] return { From 09914287260ca981d560eae4c9e21e8102dd2650 Mon Sep 17 00:00:00 2001 From: purpletennisball <212221402+purpletennisball@users.noreply.github.com> Date: Sat, 4 Jul 2026 16:30:09 -0400 Subject: [PATCH 2/4] fix: typo --- src/tagstudio/qt/mixed/settings_panel.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tagstudio/qt/mixed/settings_panel.py b/src/tagstudio/qt/mixed/settings_panel.py index db63bc0f0..988d5ba19 100644 --- a/src/tagstudio/qt/mixed/settings_panel.py +++ b/src/tagstudio/qt/mixed/settings_panel.py @@ -98,7 +98,7 @@ def __init__(self, driver: "QtDriver"): self.root_layout.setContentsMargins(0, 6, 0, 0) self.library_settings_container = QWidget() - self.appearence_settings_container = QWidget() + self.appearance_settings_container = QWidget() self.localization_settings_container = QWidget() self.media_settings_container = QWidget() @@ -108,8 +108,8 @@ def __init__(self, driver: "QtDriver"): self.__build_global_settings() self.tab_widget.addTab(self.global_settings_container, Translations["settings.global"]) - self.__build_appearence_settings() - self.tab_widget.addTab(self.appearence_settings_container, "Appearence") + self.__build_appearance_settings() + self.tab_widget.addTab(self.appearance_settings_container, "Appearance") self.__build_localization_settings() self.tab_widget.addTab(self.localization_settings_container, "Localization") @@ -313,8 +313,8 @@ def __build_localization_settings(self): self.zeropadding_checkbox.setChecked(self.driver.settings.zero_padding) form_layout.addRow(Translations["settings.zeropadding.label"], self.zeropadding_checkbox) - def __build_appearence_settings(self): - form_layout = QFormLayout(self.appearence_settings_container) + def __build_appearance_settings(self): + form_layout = QFormLayout(self.appearance_settings_container) form_layout.setContentsMargins(6, 6, 6, 6) # Dark Mode From bbeb4a305a302e8de6ce61af253e1ace1bdadb5e Mon Sep 17 00:00:00 2001 From: purpletennisball <212221402+purpletennisball@users.noreply.github.com> Date: Sat, 4 Jul 2026 16:35:41 -0400 Subject: [PATCH 3/4] fix(ui): add localization for setting panels --- src/tagstudio/qt/mixed/settings_panel.py | 10 +++++++--- src/tagstudio/resources/translations/en.json | 3 +++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/tagstudio/qt/mixed/settings_panel.py b/src/tagstudio/qt/mixed/settings_panel.py index 988d5ba19..025fc92b5 100644 --- a/src/tagstudio/qt/mixed/settings_panel.py +++ b/src/tagstudio/qt/mixed/settings_panel.py @@ -109,13 +109,17 @@ def __init__(self, driver: "QtDriver"): self.tab_widget.addTab(self.global_settings_container, Translations["settings.global"]) self.__build_appearance_settings() - self.tab_widget.addTab(self.appearance_settings_container, "Appearance") + self.tab_widget.addTab( + self.appearance_settings_container, Translations["settings.appearance"] + ) self.__build_localization_settings() - self.tab_widget.addTab(self.localization_settings_container, "Localization") + self.tab_widget.addTab( + self.localization_settings_container, Translations["settings.localization"] + ) self.__build_media_settings() - self.tab_widget.addTab(self.media_settings_container, "Media") + self.tab_widget.addTab(self.media_settings_container, Translations["settings.media"]) # self.__build_library_settings() # self.tab_widget.addTab(self.library_settings_container, Translations["settings.library"]) diff --git a/src/tagstudio/resources/translations/en.json b/src/tagstudio/resources/translations/en.json index 51e37e2a6..84fd27410 100644 --- a/src/tagstudio/resources/translations/en.json +++ b/src/tagstudio/resources/translations/en.json @@ -307,6 +307,7 @@ "select.all": "Select All", "select.clear": "Clear Selection", "select.inverse": "Invert Selection", + "settings.appearance": "Appearance", "settings.cached_thumb_resolution.label": "Cached Thumbnail Resolution", "settings.clear_thumb_cache.title": "Clear Thumbnail Cache", "settings.dateformat.english": "English", @@ -323,6 +324,8 @@ "settings.infinite_scroll": "Infinite Scrolling", "settings.language": "Language", "settings.library": "Library Settings", + "settings.localization": "Localization", + "settings.media": "Media", "settings.open_library_on_start": "Open Library on Start", "settings.page_size": "Page Size", "settings.restart_required": "Please restart TagStudio for changes to take effect.", From 950f0aed9a5d1511f5e3840cb738186034c092a5 Mon Sep 17 00:00:00 2001 From: purpletennisball <212221402+purpletennisball@users.noreply.github.com> Date: Sat, 4 Jul 2026 16:38:24 -0400 Subject: [PATCH 4/4] fix(ui): move language to localization panel --- src/tagstudio/qt/mixed/settings_panel.py | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/tagstudio/qt/mixed/settings_panel.py b/src/tagstudio/qt/mixed/settings_panel.py index 025fc92b5..61bd93a79 100644 --- a/src/tagstudio/qt/mixed/settings_panel.py +++ b/src/tagstudio/qt/mixed/settings_panel.py @@ -148,20 +148,6 @@ def __build_global_settings(self): form_layout = QFormLayout(self.global_settings_container) form_layout.setContentsMargins(6, 6, 6, 6) - # Language - self.language_combobox = QComboBox() - translated_langs = [(Translations[f"language.{lang}"], lang) for lang in LANGUAGES] - translated_langs.sort(key=lambda x: x[0]) - - for lang in translated_langs: - self.language_combobox.addItem(lang[0], lang[1]) - current_lang: str = self.driver.settings.language - if current_lang not in LANGUAGES: - current_lang = DEFAULT_TRANSLATION - self.language_combobox.setCurrentIndex([x[1] for x in translated_langs].index(current_lang)) - self.language_combobox.currentIndexChanged.connect(self.__update_restart_label) - form_layout.addRow(Translations["settings.language"], self.language_combobox) - # Open Last Library on Start self.open_last_lib_checkbox = QCheckBox() self.open_last_lib_checkbox.setChecked(self.driver.settings.open_last_loaded_on_startup) @@ -294,6 +280,20 @@ def __build_localization_settings(self): form_layout = QFormLayout(self.localization_settings_container) form_layout.setContentsMargins(6, 6, 6, 6) + # Language + self.language_combobox = QComboBox() + translated_langs = [(Translations[f"language.{lang}"], lang) for lang in LANGUAGES] + translated_langs.sort(key=lambda x: x[0]) + + for lang in translated_langs: + self.language_combobox.addItem(lang[0], lang[1]) + current_lang: str = self.driver.settings.language + if current_lang not in LANGUAGES: + current_lang = DEFAULT_TRANSLATION + self.language_combobox.setCurrentIndex([x[1] for x in translated_langs].index(current_lang)) + self.language_combobox.currentIndexChanged.connect(self.__update_restart_label) + form_layout.addRow(Translations["settings.language"], self.language_combobox) + # Date Format self.dateformat_combobox = QComboBox() for k in SettingsPanel.date_format_map: