From f770614c4e842b7095256e77b53a5a8381634512 Mon Sep 17 00:00:00 2001 From: JCC1998 <57444325+JCC1998@users.noreply.github.com> Date: Sun, 4 May 2025 19:46:26 +0200 Subject: [PATCH] feat: add date_format and hour_format settings (#904) * feat: add date_format and hour_format settings * fix: fix ruff validation errors * fix: use ruff format command * fix: Refactor code and improve some logic * fix: remove unused import * Added zero padding setting and implement some comments * Add test assert property * fix: Unclutter selector and clarify zero-padding literal * fix: Use static strings Co-authored-by: Tony <1414927+zfbx@users.noreply.github.com> --------- Co-authored-by: Tony <1414927+zfbx@users.noreply.github.com> --- src/tagstudio/core/global_settings.py | 3 ++ src/tagstudio/qt/modals/settings_panel.py | 46 +++++++++++++++++++ .../qt/widgets/preview/file_attributes.py | 22 ++++++++- src/tagstudio/resources/translations/en.json | 6 +++ src/tagstudio/resources/translations/es.json | 6 +++ tests/qt/test_global_settings.py | 6 +++ 6 files changed, 87 insertions(+), 2 deletions(-) diff --git a/src/tagstudio/core/global_settings.py b/src/tagstudio/core/global_settings.py index 70b4144c..a2e1b1c2 100644 --- a/src/tagstudio/core/global_settings.py +++ b/src/tagstudio/core/global_settings.py @@ -49,6 +49,9 @@ class GlobalSettings(BaseModel): page_size: int = Field(default=100) show_filepath: ShowFilepathOption = Field(default=ShowFilepathOption.DEFAULT) theme: Theme = Field(default=Theme.SYSTEM) + date_format: str = Field(default="%x") + hour_format: bool = Field(default=True) + zero_padding: bool = Field(default=True) @staticmethod def read_settings(path: Path = DEFAULT_GLOBAL_SETTINGS_PATH) -> "GlobalSettings": diff --git a/src/tagstudio/qt/modals/settings_panel.py b/src/tagstudio/qt/modals/settings_panel.py index 905c65d8..e7ec82c8 100644 --- a/src/tagstudio/qt/modals/settings_panel.py +++ b/src/tagstudio/qt/modals/settings_panel.py @@ -3,6 +3,7 @@ # Created for TagStudio: https://github.com/CyanVoxel/TagStudio +from datetime import datetime as dt from typing import TYPE_CHECKING from PySide6.QtCore import Qt @@ -37,6 +38,24 @@ THEME_MAP: dict[Theme, str] = { Theme.SYSTEM: Translations["settings.theme.system"], } +DATE_FORMAT_MAP: dict[str, str] = { + "%d/%m/%y": "21/08/24", + "%d/%m/%Y": "21/08/2024", + "%d.%m.%y": "21.08.24", + "%d.%m.%Y": "21.08.2024", + "%d-%m-%y": "21-08-24", + "%d-%m-%Y": "21-08-2024", + "%x": "08/21/24", + "%m/%d/%Y": "08/21/2024", + "%m-%d-%y": "08-21-24", + "%m-%d-%Y": "08-21-2024", + "%m.%d.%y": "08.21.24", + "%m.%d.%Y": "08.21.2024", + "%Y/%m/%d": "2024/08/21", + "%Y-%m-%d": "2024-08-21", + "%Y.%m.%d": "2024.08.21", +} + class SettingsPanel(PanelWidget): driver: "QtDriver" @@ -147,6 +166,27 @@ class SettingsPanel(PanelWidget): self.theme_combobox.currentIndexChanged.connect(self.__update_restart_label) form_layout.addRow(Translations["settings.theme.label"], self.theme_combobox) + # Date Format + self.dateformat_combobox = QComboBox() + for k in DATE_FORMAT_MAP: + self.dateformat_combobox.addItem(DATE_FORMAT_MAP[k], k) + dateformat: str = self.driver.settings.date_format + if dateformat not in DATE_FORMAT_MAP: + dateformat = "%x" + self.dateformat_combobox.setCurrentIndex(list(DATE_FORMAT_MAP.keys()).index(dateformat)) + self.dateformat_combobox.currentIndexChanged.connect(self.__update_restart_label) + form_layout.addRow(Translations["settings.dateformat.label"], self.dateformat_combobox) + + # 24-Hour Format + self.hourformat_checkbox = QCheckBox() + self.hourformat_checkbox.setChecked(self.driver.settings.hour_format) + form_layout.addRow(Translations["settings.hourformat.label"], self.hourformat_checkbox) + + # Zero-padding + self.zeropadding_checkbox = QCheckBox() + self.zeropadding_checkbox.setChecked(self.driver.settings.zero_padding) + form_layout.addRow(Translations["settings.zeropadding.label"], self.zeropadding_checkbox) + def __build_library_settings(self): self.library_settings_container = QWidget() form_layout = QFormLayout(self.library_settings_container) @@ -167,6 +207,9 @@ class SettingsPanel(PanelWidget): "page_size": int(self.page_size_line_edit.text()), "show_filepath": self.filepath_combobox.currentData(), "theme": self.theme_combobox.currentData(), + "date_format": self.dateformat_combobox.currentData(), + "hour_format": self.hourformat_checkbox.isChecked(), + "zero_padding": self.zeropadding_checkbox.isChecked(), } def update_settings(self, driver: "QtDriver"): @@ -179,6 +222,9 @@ class SettingsPanel(PanelWidget): driver.settings.page_size = settings["page_size"] driver.settings.show_filepath = settings["show_filepath"] driver.settings.theme = settings["theme"] + driver.settings.date_format = settings["date_format"] + driver.settings.hour_format = settings["hour_format"] + driver.settings.zero_padding = settings["zero_padding"] driver.settings.save() diff --git a/src/tagstudio/qt/widgets/preview/file_attributes.py b/src/tagstudio/qt/widgets/preview/file_attributes.py index d894af18..49098d5f 100644 --- a/src/tagstudio/qt/widgets/preview/file_attributes.py +++ b/src/tagstudio/qt/widgets/preview/file_attributes.py @@ -109,11 +109,11 @@ class FileAttributes(QWidget): created = dt.fromtimestamp(filepath.stat().st_ctime) modified: dt = dt.fromtimestamp(filepath.stat().st_mtime) self.date_created_label.setText( - f"{Translations['file.date_created']}: {dt.strftime(created, '%a, %x, %X')}" + f"{Translations['file.date_created']}: {self.get_date_with_format(created)}" ) self.date_modified_label.setText( f"{Translations['file.date_modified']}: " - f"{dt.strftime(modified, '%a, %x, %X')}" + f"{self.get_date_with_format(modified)}" ) self.date_created_label.setHidden(False) self.date_modified_label.setHidden(False) @@ -246,3 +246,21 @@ class FileAttributes(QWidget): self.file_label.set_file_path("") self.dimensions_label.setText("") self.dimensions_label.setHidden(True) + + def get_date_with_format(self, date: dt) -> str: + date_format = self.driver.settings.date_format + is_24h = self.driver.settings.hour_format + hour_format = "%H:%M:%S" if is_24h else "%I:%M:%S %p" + zero_padding = self.driver.settings.zero_padding + zero_padding_symbol = "" + + if not zero_padding: + zero_padding_symbol = "#" if platform.system() == "Windows" else "-" + date_format = date_format.replace("%d", f"%{zero_padding_symbol}d").replace( + "%m", f"%{zero_padding_symbol}m" + ) + hour_format = hour_format.replace("%H", f"%{zero_padding_symbol}H").replace( + "%I", f"%{zero_padding_symbol}I" + ) + + return dt.strftime(date, f"{date_format}, {hour_format}") diff --git a/src/tagstudio/resources/translations/en.json b/src/tagstudio/resources/translations/en.json index 2d0b029b..281f69c7 100644 --- a/src/tagstudio/resources/translations/en.json +++ b/src/tagstudio/resources/translations/en.json @@ -247,6 +247,12 @@ "settings.theme.label": "Theme:", "settings.theme.light": "Light", "settings.theme.system": "System", + "settings.dateformat.label": "Date Format", + "settings.dateformat.system": "System", + "settings.dateformat.english": "English", + "settings.dateformat.international": "International", + "settings.hourformat.label": "24-Hour Time", + "settings.zeropadding.label": "Date Zero-Padding", "settings.title": "Settings", "sorting.direction.ascending": "Ascending", "sorting.direction.descending": "Descending", diff --git a/src/tagstudio/resources/translations/es.json b/src/tagstudio/resources/translations/es.json index 7eccc3c0..aa1fc05e 100644 --- a/src/tagstudio/resources/translations/es.json +++ b/src/tagstudio/resources/translations/es.json @@ -236,6 +236,12 @@ "settings.restart_required": "Por favor, reinicia TagStudio para que se los cambios surtan efecto.", "settings.show_filenames_in_grid": "Mostrar el nombre de archivo en la cuadrícula", "settings.show_recent_libraries": "Mostrar bibliotecas recientes", + "settings.dateformat.label": "Formato fecha", + "settings.dateformat.system": "Sistema", + "settings.dateformat.english": "Inglés", + "settings.dateformat.international": "Internacional", + "settings.hourformat.label": "Formato 24-horas", + "settings.zeropadding.label": "Rellenar ceros en fechas", "settings.title": "Ajustes", "sorting.direction.ascending": "Ascendiente", "sorting.direction.descending": "Descendiente", diff --git a/tests/qt/test_global_settings.py b/tests/qt/test_global_settings.py index 21953e96..25d78086 100644 --- a/tests/qt/test_global_settings.py +++ b/tests/qt/test_global_settings.py @@ -16,6 +16,9 @@ def test_read_settings(): page_size = 1337 show_filepath = 0 dark_mode = 2 + date_format = "%x" + hour_format = true + zero_padding = true """) settings = GlobalSettings.read_settings(settings_path) @@ -26,3 +29,6 @@ def test_read_settings(): assert settings.page_size == 1337 assert settings.show_filepath == 0 assert settings.theme == Theme.SYSTEM + assert settings.date_format == "%x" + assert settings.hour_format + assert settings.zero_padding