From 76eb7478f702b02fdf5e6251c55751a588f895dd Mon Sep 17 00:00:00 2001 From: RubenSocha <40490633+RubenSocha@users.noreply.github.com> Date: Mon, 3 Mar 2025 01:31:43 +0100 Subject: [PATCH 01/12] feat: add show file path option to settings menu (#4) --- src/tagstudio/core/enums.py | 1 + src/tagstudio/qt/modals/settings_panel.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/tagstudio/core/enums.py b/src/tagstudio/core/enums.py index 2a11a12fd..4d5cfe7c7 100644 --- a/src/tagstudio/core/enums.py +++ b/src/tagstudio/core/enums.py @@ -15,6 +15,7 @@ class SettingItems(str, enum.Enum): LIBS_LIST = "libs_list" WINDOW_SHOW_LIBS = "window_show_libs" SHOW_FILENAMES = "show_filenames" + SHOW_FILEPATH = "show_filepath" AUTOPLAY = "autoplay_videos" THUMB_CACHE_SIZE_LIMIT = "thumb_cache_size_limit" LANGUAGE = "language" diff --git a/src/tagstudio/qt/modals/settings_panel.py b/src/tagstudio/qt/modals/settings_panel.py index c400c4a08..2164a7bf2 100644 --- a/src/tagstudio/qt/modals/settings_panel.py +++ b/src/tagstudio/qt/modals/settings_panel.py @@ -63,6 +63,21 @@ def __init__(self, driver): ) self.form_layout.addRow(language_label, self.language_combobox) + self.filepath_options = ["show full path", "show relative path", "show only file name"] + self.filepath_combobox = QComboBox() + self.filepath_combobox.addItems(self.filepath_options) + show_filepath: str = str( + driver.settings.value( + SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str + ) + ) + show_filepath = ( + "show full path" if show_filepath not in self.filepath_options else show_filepath + ) + self.filepath_combobox.setCurrentIndex(self.filepath_options.index(show_filepath)) + self.filepath_combobox.currentIndexChanged.connect(lambda: self.save_filepath_setting()) + self.form_layout.addRow("Show file path", self.filepath_combobox) + self.root_layout.addWidget(self.form_container) self.root_layout.addStretch(1) self.root_layout.addWidget(self.restart_label) @@ -70,3 +85,7 @@ def __init__(self, driver): def get_language(self) -> str: values: list[str] = list(self.languages.values()) return values[self.language_combobox.currentIndex()] + + def save_filepath_setting(self): + selected_value = self.filepath_combobox.currentText() + self.driver.settings.setValue(SettingItems.SHOW_FILEPATH, selected_value) From 2b855cf469aa77e3fd59b081671a30e324146d39 Mon Sep 17 00:00:00 2001 From: ErzaDuNord <102242407+ErzaDuNord@users.noreply.github.com> Date: Mon, 3 Mar 2025 10:47:37 +0100 Subject: [PATCH 02/12] feat: implement file path option for file attributes (#10) * feat: implement file path option for file attributes --------- Co-authored-by: Zarko Sesto --- .../qt/widgets/preview/file_attributes.py | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/tagstudio/qt/widgets/preview/file_attributes.py b/src/tagstudio/qt/widgets/preview/file_attributes.py index c9e84c701..f0b4e0cc0 100644 --- a/src/tagstudio/qt/widgets/preview/file_attributes.py +++ b/src/tagstudio/qt/widgets/preview/file_attributes.py @@ -17,7 +17,7 @@ from PySide6.QtGui import QGuiApplication from PySide6.QtWidgets import QLabel, QVBoxLayout, QWidget -from tagstudio.core.enums import Theme +from tagstudio.core.enums import Theme, SettingItems from tagstudio.core.library.alchemy.library import Library from tagstudio.core.media_types import MediaCategories from tagstudio.qt.helpers.file_opener import FileOpenerHelper, FileOpenerLabel @@ -96,6 +96,8 @@ def __init__(self, library: Library, driver: "QtDriver"): root_layout.addWidget(self.file_label) root_layout.addWidget(self.date_container) root_layout.addWidget(self.dimensions_label) + self.library = library + self.driver = driver def update_date_label(self, filepath: Path | None = None) -> None: """Update the "Date Created" and "Date Modified" file property labels.""" @@ -142,6 +144,19 @@ def update_stats(self, filepath: Path | None = None, ext: str = ".", stats: dict self.dimensions_label.setText("") self.dimensions_label.setHidden(True) else: + filepath_option = self.driver.settings.value( + SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str + ) + + self.library_path = self.library.library_dir + display_path = filepath + if filepath_option == "show full path": + display_path = filepath + elif filepath_option == "show relative path": + display_path = Path(filepath).relative_to(self.library_path) + elif filepath_option == "show only file name": + display_path = Path(filepath.name) + self.layout().setSpacing(6) self.file_label.setAlignment(Qt.AlignmentFlag.AlignLeft) self.file_label.set_file_path(filepath) @@ -149,12 +164,21 @@ def update_stats(self, filepath: Path | None = None, ext: str = ".", stats: dict file_str: str = "" separator: str = f"{os.path.sep}" # Gray - for i, part in enumerate(filepath.parts): + for i, part in enumerate(display_path.parts): part_ = part.strip(os.path.sep) +<<<<<<< HEAD:src/tagstudio/qt/widgets/preview/file_attributes.py if i != len(filepath.parts) - 1: file_str += f"{'\u200b'.join(part_)}{separator}" else: file_str += f"
{'\u200b'.join(part_)}" +======= + if i != len(display_path.parts) - 1: + file_str += f"{"\u200b".join(part_)}{separator}" + else: + if file_str != "": + file_str += f"
" + file_str += f"{"\u200b".join(part_)}" +>>>>>>> 1e61888 (feat: implement file path option for file attributes (#10)):tagstudio/src/qt/widgets/preview/file_attributes.py self.file_label.setText(file_str) self.file_label.setCursor(Qt.CursorShape.PointingHandCursor) self.opener = FileOpenerHelper(filepath) From 6e0fc83ea7924ff7ac8def355a78d3c8c797f381 Mon Sep 17 00:00:00 2001 From: RubenSocha <40490633+RubenSocha@users.noreply.github.com> Date: Mon, 3 Mar 2025 10:51:58 +0100 Subject: [PATCH 03/12] feat: update ui after changing file path setting (#9) --- src/tagstudio/qt/modals/settings_panel.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tagstudio/qt/modals/settings_panel.py b/src/tagstudio/qt/modals/settings_panel.py index 2164a7bf2..457cdff63 100644 --- a/src/tagstudio/qt/modals/settings_panel.py +++ b/src/tagstudio/qt/modals/settings_panel.py @@ -75,7 +75,7 @@ def __init__(self, driver): "show full path" if show_filepath not in self.filepath_options else show_filepath ) self.filepath_combobox.setCurrentIndex(self.filepath_options.index(show_filepath)) - self.filepath_combobox.currentIndexChanged.connect(lambda: self.save_filepath_setting()) + self.filepath_combobox.currentIndexChanged.connect(lambda: self.apply_filepath_setting()) self.form_layout.addRow("Show file path", self.filepath_combobox) self.root_layout.addWidget(self.form_container) @@ -86,6 +86,7 @@ def get_language(self) -> str: values: list[str] = list(self.languages.values()) return values[self.language_combobox.currentIndex()] - def save_filepath_setting(self): + def apply_filepath_setting(self): selected_value = self.filepath_combobox.currentText() self.driver.settings.setValue(SettingItems.SHOW_FILEPATH, selected_value) + self.driver.update_recent_lib_menu() From a31f595eadfbc41df608c6bb395f0f5ca7705760 Mon Sep 17 00:00:00 2001 From: ErzaDuNord <102242407+ErzaDuNord@users.noreply.github.com> Date: Mon, 3 Mar 2025 10:52:43 +0100 Subject: [PATCH 04/12] feat: implement file path options for main window (#11) Co-authored-by: Zarko Sesto --- src/tagstudio/qt/ts_qt.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/tagstudio/qt/ts_qt.py b/src/tagstudio/qt/ts_qt.py index 33ba48e16..84f621d8c 100644 --- a/src/tagstudio/qt/ts_qt.py +++ b/src/tagstudio/qt/ts_qt.py @@ -1749,6 +1749,9 @@ def update_recent_lib_menu(self): """Updates the recent library menu from the latest values from the settings file.""" actions: list[QAction] = [] lib_items: dict[str, tuple[str, str]] = {} + filepath_option: str = str( + self.settings.value(SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str) + ) settings = self.settings settings.beginGroup(SettingItems.LIBS_LIST) @@ -1767,7 +1770,10 @@ def update_recent_lib_menu(self): for library_key in libs_sorted: path = Path(library_key[1][0]) action = QAction(self.open_recent_library_menu) - action.setText(str(path)) + if filepath_option == "show full path": + action.setText(str(path)) + else: + action.setText(str(Path(path).name)) action.triggered.connect(lambda checked=False, p=path: self.open_library(p)) actions.append(action) @@ -1825,6 +1831,14 @@ def open_library(self, path: Path) -> None: message = Translations.format("splash.opening_library", library_path=str(path)) self.main_window.landing_widget.set_status_label(message) self.main_window.statusbar.showMessage(message, 3) + filepath_option: str = str( + self.settings.value(SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str) + ) + library_dir_display = "show full path" + if filepath_option == "show full path": + library_dir_display = path + else: + library_dir_display = path.name self.main_window.repaint() if self.lib.library_dir: @@ -1867,12 +1881,21 @@ def init_library(self, path: Path, open_status: LibraryStatus): if self.lib.entries_count < 10000: self.add_new_files_callback() + library_dir_display = self.lib.library_dir + filepath_option: str = str( + self.settings.value(SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str) + ) + if filepath_option == "show full path": + library_dir_display = self.lib.library_dir + else: + library_dir_display = self.lib.library_dir.name + self.update_libs_list(path) self.main_window.setWindowTitle( Translations.format( "app.title", base_title=self.base_title, - library_dir=self.lib.library_dir, + library_dir=library_dir_display, ) ) self.main_window.setAcceptDrops(True) From d4c6362ca28425aa79648e9df9cc85d2659426e6 Mon Sep 17 00:00:00 2001 From: ErzaDuNord <102242407+ErzaDuNord@users.noreply.github.com> Date: Mon, 3 Mar 2025 11:25:05 +0100 Subject: [PATCH 05/12] feat: add realtime feedback for setting changes (#13) Co-authored-by: Zarko Sesto style: formatted code changes with ruff (#16) --- src/tagstudio/qt/modals/settings_panel.py | 12 ++++++++++++ src/tagstudio/qt/ts_qt.py | 6 +----- src/tagstudio/qt/widgets/preview/file_attributes.py | 11 ++--------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/tagstudio/qt/modals/settings_panel.py b/src/tagstudio/qt/modals/settings_panel.py index 457cdff63..18e0e1a97 100644 --- a/src/tagstudio/qt/modals/settings_panel.py +++ b/src/tagstudio/qt/modals/settings_panel.py @@ -90,3 +90,15 @@ def apply_filepath_setting(self): selected_value = self.filepath_combobox.currentText() self.driver.settings.setValue(SettingItems.SHOW_FILEPATH, selected_value) self.driver.update_recent_lib_menu() + self.driver.preview_panel.update_widgets() + library_directory = self.driver.lib.library_dir + if selected_value == "show full path": + display_path = library_directory + else: + display_path = library_directory.name + Translations.translate_with_setter( + self.driver.main_window.setWindowTitle, + "app.title", + base_title=self.driver.base_title, + library_dir=display_path, + ) diff --git a/src/tagstudio/qt/ts_qt.py b/src/tagstudio/qt/ts_qt.py index 84f621d8c..90a278f39 100644 --- a/src/tagstudio/qt/ts_qt.py +++ b/src/tagstudio/qt/ts_qt.py @@ -1834,11 +1834,7 @@ def open_library(self, path: Path) -> None: filepath_option: str = str( self.settings.value(SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str) ) - library_dir_display = "show full path" - if filepath_option == "show full path": - library_dir_display = path - else: - library_dir_display = path.name + library_dir_display = path if filepath_option == "show full path" else path.name self.main_window.repaint() if self.lib.library_dir: diff --git a/src/tagstudio/qt/widgets/preview/file_attributes.py b/src/tagstudio/qt/widgets/preview/file_attributes.py index f0b4e0cc0..2c4b8a7ee 100644 --- a/src/tagstudio/qt/widgets/preview/file_attributes.py +++ b/src/tagstudio/qt/widgets/preview/file_attributes.py @@ -17,7 +17,7 @@ from PySide6.QtGui import QGuiApplication from PySide6.QtWidgets import QLabel, QVBoxLayout, QWidget -from tagstudio.core.enums import Theme, SettingItems +from tagstudio.core.enums import SettingItems, Theme from tagstudio.core.library.alchemy.library import Library from tagstudio.core.media_types import MediaCategories from tagstudio.qt.helpers.file_opener import FileOpenerHelper, FileOpenerLabel @@ -166,19 +166,12 @@ def update_stats(self, filepath: Path | None = None, ext: str = ".", stats: dict separator: str = f"{os.path.sep}" # Gray for i, part in enumerate(display_path.parts): part_ = part.strip(os.path.sep) -<<<<<<< HEAD:src/tagstudio/qt/widgets/preview/file_attributes.py - if i != len(filepath.parts) - 1: - file_str += f"{'\u200b'.join(part_)}{separator}" - else: - file_str += f"
{'\u200b'.join(part_)}" -======= if i != len(display_path.parts) - 1: file_str += f"{"\u200b".join(part_)}{separator}" else: if file_str != "": - file_str += f"
" + file_str += "
" file_str += f"{"\u200b".join(part_)}" ->>>>>>> 1e61888 (feat: implement file path option for file attributes (#10)):tagstudio/src/qt/widgets/preview/file_attributes.py self.file_label.setText(file_str) self.file_label.setCursor(Qt.CursorShape.PointingHandCursor) self.opener = FileOpenerHelper(filepath) From 805a04cfd4c3dbe325f6b6342a643fec61a2e23e Mon Sep 17 00:00:00 2001 From: BitGatito Date: Mon, 3 Mar 2025 19:19:57 +0100 Subject: [PATCH 06/12] tests: Added tests to test file path display and settings menu enhancement: formated using RUFF test: addeded test to check title bar update --- tests/qt/test_file_path_options.py | 118 +++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 tests/qt/test_file_path_options.py diff --git a/tests/qt/test_file_path_options.py b/tests/qt/test_file_path_options.py new file mode 100644 index 000000000..b47763ad9 --- /dev/null +++ b/tests/qt/test_file_path_options.py @@ -0,0 +1,118 @@ +import os +import pathlib +from unittest.mock import patch + +import pytest +from PySide6.QtGui import ( + QAction, +) +from PySide6.QtWidgets import QMenu, QMenuBar +from src.core.enums import SettingItems +from src.core.library.alchemy.library import LibraryStatus +from src.qt.modals.settings_panel import SettingsPanel +from src.qt.widgets.preview_panel import PreviewPanel + + +# Tests to see if the file path setting is applied correctly +@pytest.mark.parametrize( + "filepath_option", ["show full path", "show relative path", "show only file name"] +) +def test_filepath_setting(qtbot, qt_driver, filepath_option): + settings_panel = SettingsPanel(qt_driver) + qtbot.addWidget(settings_panel) + + # Mock the update_recent_lib_menu method + with patch.object(qt_driver, "update_recent_lib_menu", return_value=None): + # Set the file path option + settings_panel.filepath_combobox.setCurrentText(filepath_option) + settings_panel.apply_filepath_setting() + + # Assert the setting is applied + assert qt_driver.settings.value(SettingItems.SHOW_FILEPATH) == filepath_option + + +# Tests to see if the file paths are being displayed correctly +@pytest.mark.parametrize( + "filepath_option, expected_path", + [ + ("show full path", lambda library: pathlib.Path(library.library_dir / "one/two/bar.md")), + ("show relative path", lambda library: pathlib.Path("one/two/bar.md")), + ("show only file name", lambda library: pathlib.Path("bar.md")), + ], +) +def test_file_path_display(qt_driver, library, filepath_option, expected_path): + panel = PreviewPanel(library, qt_driver) + + # Select 2 + qt_driver.toggle_item_selection(2, append=False, bridge=False) + panel.update_widgets() + + with patch.object(qt_driver.settings, "value", return_value=filepath_option): + # Apply the mock value + filename = library.get_entry(2).path + panel.file_attrs.update_stats(filepath=pathlib.Path(library.library_dir / filename)) + + # Generate the expected file string. + # This is copied directly from the file_attributes.py file + # can be imported as a function in the future + display_path = expected_path(library) + file_str: str = "" + separator: str = f"{os.path.sep}" # Gray + for i, part in enumerate(display_path.parts): + part_ = part.strip(os.path.sep) + if i != len(display_path.parts) - 1: + file_str += f"{"\u200b".join(part_)}{separator}" + else: + if file_str != "": + file_str += "
" + file_str += f"{"\u200b".join(part_)}" + + # Assert the file path is displayed correctly + assert panel.file_attrs.file_label.text() == file_str + + +@pytest.mark.parametrize( + "filepath_option, expected_title", + [ + ("show full path", lambda path, base_title: f"{base_title} - Library '{path}'"), + ( + "show relative path", + lambda path, base_title: f"{base_title} - Library '{path.name}'", + ), + ( + "show only file name", + lambda path, base_title: f"{base_title} - Library '{path.name}'", + ), + ], +) +def test_title_update(qtbot, qt_driver, filepath_option, expected_title): + base_title = qt_driver.base_title + test_path = pathlib.Path("/dev/null") + open_status = LibraryStatus( + success=True, + library_path=test_path, + message="", + msg_description="", + ) + # Set the file path option + qt_driver.settings.setValue(SettingItems.SHOW_FILEPATH, filepath_option) + menu_bar = QMenuBar() + + qt_driver.open_recent_library_menu = QMenu(menu_bar) + qt_driver.manage_file_ext_action = QAction(menu_bar) + qt_driver.save_library_backup_action = QAction(menu_bar) + qt_driver.close_library_action = QAction(menu_bar) + qt_driver.refresh_dir_action = QAction(menu_bar) + qt_driver.tag_manager_action = QAction(menu_bar) + qt_driver.color_manager_action = QAction(menu_bar) + qt_driver.new_tag_action = QAction(menu_bar) + qt_driver.fix_dupe_files_action = QAction(menu_bar) + qt_driver.fix_unlinked_entries_action = QAction(menu_bar) + qt_driver.clear_thumb_cache_action = QAction(menu_bar) + qt_driver.folders_to_tags_action = QAction(menu_bar) + + # Trigger the update + qt_driver.init_library(pathlib.Path(test_path), open_status) + + # Assert the title is updated correctly + qt_driver.main_window.setWindowTitle.assert_called_with(expected_title(test_path, base_title)) From 608c5e535913e24f751e02232945bf548cd905f7 Mon Sep 17 00:00:00 2001 From: HermanKassler <99051506+HermanKassler@users.noreply.github.com> Date: Fri, 7 Mar 2025 17:05:37 +0100 Subject: [PATCH 07/12] fix: move check for file option to correct spot in open_library (#17) --- src/tagstudio/qt/ts_qt.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tagstudio/qt/ts_qt.py b/src/tagstudio/qt/ts_qt.py index 90a278f39..d82743c7a 100644 --- a/src/tagstudio/qt/ts_qt.py +++ b/src/tagstudio/qt/ts_qt.py @@ -1828,13 +1828,13 @@ def update_language_settings(self, language: str): def open_library(self, path: Path) -> None: """Open a TagStudio library.""" - message = Translations.format("splash.opening_library", library_path=str(path)) - self.main_window.landing_widget.set_status_label(message) - self.main_window.statusbar.showMessage(message, 3) filepath_option: str = str( self.settings.value(SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str) ) library_dir_display = path if filepath_option == "show full path" else path.name + message = Translations["splash.opening_library"].format(library_path=library_dir_display) + self.main_window.landing_widget.set_status_label(message) + self.main_window.statusbar.showMessage(message, 3) self.main_window.repaint() if self.lib.library_dir: From 2810e4791182756b4d964d7563f98365eb41cd25 Mon Sep 17 00:00:00 2001 From: HermanKassler <99051506+HermanKassler@users.noreply.github.com> Date: Fri, 7 Mar 2025 17:06:07 +0100 Subject: [PATCH 08/12] fix: change translate_with_setter to new method (#18) --- src/tagstudio/qt/modals/settings_panel.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/tagstudio/qt/modals/settings_panel.py b/src/tagstudio/qt/modals/settings_panel.py index 18e0e1a97..115aefcfe 100644 --- a/src/tagstudio/qt/modals/settings_panel.py +++ b/src/tagstudio/qt/modals/settings_panel.py @@ -96,9 +96,8 @@ def apply_filepath_setting(self): display_path = library_directory else: display_path = library_directory.name - Translations.translate_with_setter( - self.driver.main_window.setWindowTitle, - "app.title", - base_title=self.driver.base_title, - library_dir=display_path, + self.driver.main_window.setWindowTitle( + Translations["app.title"].format( + base_title=self.driver.base_title, library_dir=display_path + ) ) From b0041a2f4e61d219bec2b32b66dca08867bb308b Mon Sep 17 00:00:00 2001 From: HermanKassler <99051506+HermanKassler@users.noreply.github.com> Date: Fri, 7 Mar 2025 17:30:44 +0100 Subject: [PATCH 09/12] fix: update call to translator to be inline with upstream (#19) --- src/tagstudio/qt/modals/settings_panel.py | 4 ++-- src/tagstudio/qt/ts_qt.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tagstudio/qt/modals/settings_panel.py b/src/tagstudio/qt/modals/settings_panel.py index 115aefcfe..f4e11e0a0 100644 --- a/src/tagstudio/qt/modals/settings_panel.py +++ b/src/tagstudio/qt/modals/settings_panel.py @@ -97,7 +97,7 @@ def apply_filepath_setting(self): else: display_path = library_directory.name self.driver.main_window.setWindowTitle( - Translations["app.title"].format( - base_title=self.driver.base_title, library_dir=display_path + Translations.format( + "app.title", base_title=self.driver.base_title, library_dir=display_path ) ) diff --git a/src/tagstudio/qt/ts_qt.py b/src/tagstudio/qt/ts_qt.py index d82743c7a..0d9dc7ab3 100644 --- a/src/tagstudio/qt/ts_qt.py +++ b/src/tagstudio/qt/ts_qt.py @@ -1832,7 +1832,7 @@ def open_library(self, path: Path) -> None: self.settings.value(SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str) ) library_dir_display = path if filepath_option == "show full path" else path.name - message = Translations["splash.opening_library"].format(library_path=library_dir_display) + message = Translations.format("splash.opening_library",library_path=library_dir_display) self.main_window.landing_widget.set_status_label(message) self.main_window.statusbar.showMessage(message, 3) self.main_window.repaint() From 17181319c9d29eb443fe2c013db9e224f6ff3266 Mon Sep 17 00:00:00 2001 From: HermanKassler <99051506+HermanKassler@users.noreply.github.com> Date: Mon, 10 Mar 2025 10:54:36 +0100 Subject: [PATCH 10/12] refactor: update some imports to reflect refactor on upstream (#20) * refactor: update import paths to reflect recent reformat * format: run ruff format --- src/tagstudio/qt/ts_qt.py | 2 +- tests/qt/test_file_path_options.py | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/tagstudio/qt/ts_qt.py b/src/tagstudio/qt/ts_qt.py index 0d9dc7ab3..43609746f 100644 --- a/src/tagstudio/qt/ts_qt.py +++ b/src/tagstudio/qt/ts_qt.py @@ -1832,7 +1832,7 @@ def open_library(self, path: Path) -> None: self.settings.value(SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str) ) library_dir_display = path if filepath_option == "show full path" else path.name - message = Translations.format("splash.opening_library",library_path=library_dir_display) + message = Translations.format("splash.opening_library", library_path=library_dir_display) self.main_window.landing_widget.set_status_label(message) self.main_window.statusbar.showMessage(message, 3) self.main_window.repaint() diff --git a/tests/qt/test_file_path_options.py b/tests/qt/test_file_path_options.py index b47763ad9..a44acb077 100644 --- a/tests/qt/test_file_path_options.py +++ b/tests/qt/test_file_path_options.py @@ -7,10 +7,11 @@ QAction, ) from PySide6.QtWidgets import QMenu, QMenuBar -from src.core.enums import SettingItems -from src.core.library.alchemy.library import LibraryStatus -from src.qt.modals.settings_panel import SettingsPanel -from src.qt.widgets.preview_panel import PreviewPanel + +from tagstudio.core.enums import SettingItems +from tagstudio.core.library.alchemy.library import LibraryStatus +from tagstudio.qt.modals.settings_panel import SettingsPanel +from tagstudio.qt.widgets.preview_panel import PreviewPanel # Tests to see if the file path setting is applied correctly From 37b43c5b9f1016414d5812e6d0192fa7b33011ea Mon Sep 17 00:00:00 2001 From: HermanKassler Date: Wed, 12 Mar 2025 20:36:07 +0100 Subject: [PATCH 11/12] translation: add translations for filepath setting --- src/tagstudio/resources/translations/en.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tagstudio/resources/translations/en.json b/src/tagstudio/resources/translations/en.json index d1dc2caa2..4bec8a99a 100644 --- a/src/tagstudio/resources/translations/en.json +++ b/src/tagstudio/resources/translations/en.json @@ -218,6 +218,10 @@ "edit.copy_fields": "Copy Fields", "edit.paste_fields": "Paste Fields", "settings.clear_thumb_cache.title": "Clear Thumbnail Cache", + "settings.filepath.label": "Filepath Visibility", + "settings.filepath.option.full": "Show Full Paths", + "settings.filepath.option.name": "Show Filenames Only", + "settings.filepath.option.relative": "Show Relative Paths", "settings.language": "Language", "settings.open_library_on_start": "Open Library on Start", "settings.restart_required": "Please restart TagStudio for changes to take effect.", From 4b4ea1ed75f28c1cb989f1afa9d29d729021e0f9 Mon Sep 17 00:00:00 2001 From: RubenSocha <40490633+RubenSocha@users.noreply.github.com> Date: Wed, 12 Mar 2025 21:45:12 +0100 Subject: [PATCH 12/12] refactor: store filepath options in integer enum --- src/tagstudio/core/enums.py | 9 ++++++ src/tagstudio/qt/modals/settings_panel.py | 30 +++++++++++-------- src/tagstudio/qt/ts_qt.py | 28 ++++++++++------- .../qt/widgets/preview/file_attributes.py | 11 ++++--- tests/qt/test_file_path_options.py | 29 ++++++++++++------ 5 files changed, 69 insertions(+), 38 deletions(-) diff --git a/src/tagstudio/core/enums.py b/src/tagstudio/core/enums.py index 4d5cfe7c7..31e383b6a 100644 --- a/src/tagstudio/core/enums.py +++ b/src/tagstudio/core/enums.py @@ -21,6 +21,15 @@ class SettingItems(str, enum.Enum): LANGUAGE = "language" +class ShowFilepathOption(int, enum.Enum): + """Values representing the options for the "show_filenames" setting.""" + + SHOW_FULL_PATHS = 0 + SHOW_RELATIVE_PATHS = 1 + SHOW_FILENAMES_ONLY = 2 + DEFAULT = SHOW_RELATIVE_PATHS + + class Theme(str, enum.Enum): COLOR_BG_DARK = "#65000000" COLOR_BG_LIGHT = "#22000000" diff --git a/src/tagstudio/qt/modals/settings_panel.py b/src/tagstudio/qt/modals/settings_panel.py index f4e11e0a0..378397892 100644 --- a/src/tagstudio/qt/modals/settings_panel.py +++ b/src/tagstudio/qt/modals/settings_panel.py @@ -6,7 +6,7 @@ from PySide6.QtCore import Qt from PySide6.QtWidgets import QComboBox, QFormLayout, QLabel, QVBoxLayout, QWidget -from tagstudio.core.enums import SettingItems +from tagstudio.core.enums import SettingItems, ShowFilepathOption from tagstudio.qt.translations import Translations from tagstudio.qt.widgets.panel import PanelWidget @@ -63,20 +63,24 @@ def __init__(self, driver): ) self.form_layout.addRow(language_label, self.language_combobox) - self.filepath_options = ["show full path", "show relative path", "show only file name"] + filepath_option_map: dict[int, str] = { + ShowFilepathOption.SHOW_FULL_PATHS: Translations["settings.filepath.option.full"], + ShowFilepathOption.SHOW_RELATIVE_PATHS: Translations[ + "settings.filepath.option.relative" + ], + ShowFilepathOption.SHOW_FILENAMES_ONLY: Translations["settings.filepath.option.name"], + } self.filepath_combobox = QComboBox() - self.filepath_combobox.addItems(self.filepath_options) - show_filepath: str = str( + self.filepath_combobox.addItems(list(filepath_option_map.values())) + filepath_option: int = int( driver.settings.value( - SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str + SettingItems.SHOW_FILEPATH, defaultValue=ShowFilepathOption.DEFAULT.value, type=int ) ) - show_filepath = ( - "show full path" if show_filepath not in self.filepath_options else show_filepath - ) - self.filepath_combobox.setCurrentIndex(self.filepath_options.index(show_filepath)) - self.filepath_combobox.currentIndexChanged.connect(lambda: self.apply_filepath_setting()) - self.form_layout.addRow("Show file path", self.filepath_combobox) + filepath_option = 0 if filepath_option not in filepath_option_map else filepath_option + self.filepath_combobox.setCurrentIndex(filepath_option) + self.filepath_combobox.currentIndexChanged.connect(self.apply_filepath_setting) + self.form_layout.addRow(Translations["settings.filepath.label"], self.filepath_combobox) self.root_layout.addWidget(self.form_container) self.root_layout.addStretch(1) @@ -87,12 +91,12 @@ def get_language(self) -> str: return values[self.language_combobox.currentIndex()] def apply_filepath_setting(self): - selected_value = self.filepath_combobox.currentText() + selected_value = self.filepath_combobox.currentIndex() self.driver.settings.setValue(SettingItems.SHOW_FILEPATH, selected_value) self.driver.update_recent_lib_menu() self.driver.preview_panel.update_widgets() library_directory = self.driver.lib.library_dir - if selected_value == "show full path": + if selected_value == ShowFilepathOption.SHOW_FULL_PATHS: display_path = library_directory else: display_path = library_directory.name diff --git a/src/tagstudio/qt/ts_qt.py b/src/tagstudio/qt/ts_qt.py index 43609746f..034fb3f03 100644 --- a/src/tagstudio/qt/ts_qt.py +++ b/src/tagstudio/qt/ts_qt.py @@ -54,7 +54,7 @@ import tagstudio.qt.resources_rc # noqa: F401 from tagstudio.core.constants import TAG_ARCHIVED, TAG_FAVORITE, VERSION, VERSION_BRANCH from tagstudio.core.driver import DriverMixin -from tagstudio.core.enums import LibraryPrefs, MacroID, SettingItems +from tagstudio.core.enums import LibraryPrefs, MacroID, SettingItems, ShowFilepathOption from tagstudio.core.library.alchemy.enums import ( FieldTypeEnum, FilterState, @@ -1749,8 +1749,10 @@ def update_recent_lib_menu(self): """Updates the recent library menu from the latest values from the settings file.""" actions: list[QAction] = [] lib_items: dict[str, tuple[str, str]] = {} - filepath_option: str = str( - self.settings.value(SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str) + filepath_option: int = int( + self.settings.value( + SettingItems.SHOW_FILEPATH, defaultValue=ShowFilepathOption.DEFAULT.value, type=int + ) ) settings = self.settings @@ -1770,7 +1772,7 @@ def update_recent_lib_menu(self): for library_key in libs_sorted: path = Path(library_key[1][0]) action = QAction(self.open_recent_library_menu) - if filepath_option == "show full path": + if filepath_option == ShowFilepathOption.SHOW_FULL_PATHS: action.setText(str(path)) else: action.setText(str(Path(path).name)) @@ -1828,10 +1830,14 @@ def update_language_settings(self, language: str): def open_library(self, path: Path) -> None: """Open a TagStudio library.""" - filepath_option: str = str( - self.settings.value(SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str) + filepath_option: int = int( + self.settings.value( + SettingItems.SHOW_FILEPATH, defaultValue=ShowFilepathOption.DEFAULT.value, type=int + ) + ) + library_dir_display = ( + path if filepath_option == ShowFilepathOption.SHOW_FULL_PATHS else path.name ) - library_dir_display = path if filepath_option == "show full path" else path.name message = Translations.format("splash.opening_library", library_path=library_dir_display) self.main_window.landing_widget.set_status_label(message) self.main_window.statusbar.showMessage(message, 3) @@ -1878,10 +1884,12 @@ def init_library(self, path: Path, open_status: LibraryStatus): self.add_new_files_callback() library_dir_display = self.lib.library_dir - filepath_option: str = str( - self.settings.value(SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str) + filepath_option: int = int( + self.settings.value( + SettingItems.SHOW_FILEPATH, defaultValue=ShowFilepathOption.DEFAULT.value, type=int + ) ) - if filepath_option == "show full path": + if filepath_option == ShowFilepathOption.SHOW_FULL_PATHS: library_dir_display = self.lib.library_dir else: library_dir_display = self.lib.library_dir.name diff --git a/src/tagstudio/qt/widgets/preview/file_attributes.py b/src/tagstudio/qt/widgets/preview/file_attributes.py index 2c4b8a7ee..c6f3c0b2c 100644 --- a/src/tagstudio/qt/widgets/preview/file_attributes.py +++ b/src/tagstudio/qt/widgets/preview/file_attributes.py @@ -17,7 +17,7 @@ from PySide6.QtGui import QGuiApplication from PySide6.QtWidgets import QLabel, QVBoxLayout, QWidget -from tagstudio.core.enums import SettingItems, Theme +from tagstudio.core.enums import SettingItems, ShowFilepathOption, Theme from tagstudio.core.library.alchemy.library import Library from tagstudio.core.media_types import MediaCategories from tagstudio.qt.helpers.file_opener import FileOpenerHelper, FileOpenerLabel @@ -145,16 +145,15 @@ def update_stats(self, filepath: Path | None = None, ext: str = ".", stats: dict self.dimensions_label.setHidden(True) else: filepath_option = self.driver.settings.value( - SettingItems.SHOW_FILEPATH, defaultValue="show full path", type=str + SettingItems.SHOW_FILEPATH, defaultValue=ShowFilepathOption.DEFAULT.value, type=int ) - self.library_path = self.library.library_dir display_path = filepath - if filepath_option == "show full path": + if filepath_option == ShowFilepathOption.SHOW_FULL_PATHS: display_path = filepath - elif filepath_option == "show relative path": + elif filepath_option == ShowFilepathOption.SHOW_RELATIVE_PATHS: display_path = Path(filepath).relative_to(self.library_path) - elif filepath_option == "show only file name": + elif filepath_option == ShowFilepathOption.SHOW_FILENAMES_ONLY: display_path = Path(filepath.name) self.layout().setSpacing(6) diff --git a/tests/qt/test_file_path_options.py b/tests/qt/test_file_path_options.py index a44acb077..642bcaa84 100644 --- a/tests/qt/test_file_path_options.py +++ b/tests/qt/test_file_path_options.py @@ -8,7 +8,7 @@ ) from PySide6.QtWidgets import QMenu, QMenuBar -from tagstudio.core.enums import SettingItems +from tagstudio.core.enums import SettingItems, ShowFilepathOption from tagstudio.core.library.alchemy.library import LibraryStatus from tagstudio.qt.modals.settings_panel import SettingsPanel from tagstudio.qt.widgets.preview_panel import PreviewPanel @@ -16,7 +16,12 @@ # Tests to see if the file path setting is applied correctly @pytest.mark.parametrize( - "filepath_option", ["show full path", "show relative path", "show only file name"] + "filepath_option", + [ + ShowFilepathOption.SHOW_FULL_PATHS.value, + ShowFilepathOption.SHOW_RELATIVE_PATHS.value, + ShowFilepathOption.SHOW_FILENAMES_ONLY.value, + ], ) def test_filepath_setting(qtbot, qt_driver, filepath_option): settings_panel = SettingsPanel(qt_driver) @@ -25,7 +30,7 @@ def test_filepath_setting(qtbot, qt_driver, filepath_option): # Mock the update_recent_lib_menu method with patch.object(qt_driver, "update_recent_lib_menu", return_value=None): # Set the file path option - settings_panel.filepath_combobox.setCurrentText(filepath_option) + settings_panel.filepath_combobox.setCurrentIndex(filepath_option) settings_panel.apply_filepath_setting() # Assert the setting is applied @@ -36,9 +41,12 @@ def test_filepath_setting(qtbot, qt_driver, filepath_option): @pytest.mark.parametrize( "filepath_option, expected_path", [ - ("show full path", lambda library: pathlib.Path(library.library_dir / "one/two/bar.md")), - ("show relative path", lambda library: pathlib.Path("one/two/bar.md")), - ("show only file name", lambda library: pathlib.Path("bar.md")), + ( + ShowFilepathOption.SHOW_FULL_PATHS, + lambda library: pathlib.Path(library.library_dir / "one/two/bar.md"), + ), + (ShowFilepathOption.SHOW_RELATIVE_PATHS, lambda library: pathlib.Path("one/two/bar.md")), + (ShowFilepathOption.SHOW_FILENAMES_ONLY, lambda library: pathlib.Path("bar.md")), ], ) def test_file_path_display(qt_driver, library, filepath_option, expected_path): @@ -75,13 +83,16 @@ def test_file_path_display(qt_driver, library, filepath_option, expected_path): @pytest.mark.parametrize( "filepath_option, expected_title", [ - ("show full path", lambda path, base_title: f"{base_title} - Library '{path}'"), ( - "show relative path", + ShowFilepathOption.SHOW_FULL_PATHS.value, + lambda path, base_title: f"{base_title} - Library '{path}'", + ), + ( + ShowFilepathOption.SHOW_RELATIVE_PATHS.value, lambda path, base_title: f"{base_title} - Library '{path.name}'", ), ( - "show only file name", + ShowFilepathOption.SHOW_FILENAMES_ONLY.value, lambda path, base_title: f"{base_title} - Library '{path.name}'", ), ],