From 642b5e368168bb31f928d9935512ed3339edd9bb Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 11 Feb 2024 20:57:27 +0100 Subject: [PATCH] Add a formatting function for file extension filters for file dialogs --- novelwriter/common.py | 15 ++++++++++++++- novelwriter/constants.py | 6 ++++++ tests/test_base/test_base_common.py | 22 +++++++++++++++++----- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/novelwriter/common.py b/novelwriter/common.py index b658cf6d..0c160fe9 100644 --- a/novelwriter/common.py +++ b/novelwriter/common.py @@ -41,7 +41,7 @@ from PyQt5.QtCore import QCoreApplication, QUrl from novelwriter.enum import nwItemClass, nwItemType, nwItemLayout from novelwriter.error import logException -from novelwriter.constants import nwConst, nwUnicode +from novelwriter.constants import nwConst, nwLabels, nwUnicode, trConst if TYPE_CHECKING: # pragma: no cover from typing import TypeGuard # Requires Python 3.10 @@ -248,6 +248,19 @@ def formatVersion(value: str) -> str: return value.lower().replace("a", " Alpha ").replace("b", " Beta ").replace("rc", " RC ") +def formatFileFilter(extensions: list[str | tuple[str, str]]) -> str: + """Format a list of extensions, or extension + label pairs into a + QFileDialog extensions filter. + """ + result = [] + for ext in extensions: + if isinstance(ext, str): + result.append(f"{trConst(nwLabels.FILE_FILTERS.get(ext))} ({ext})") + elif isinstance(ext, tuple) and len(ext) == 2: + result.append(f"{ext[0]} ({ext[1]})") + return ";;".join(result) + + ## # String Functions ## diff --git a/novelwriter/constants.py b/novelwriter/constants.py index e2599512..bd8d366d 100644 --- a/novelwriter/constants.py +++ b/novelwriter/constants.py @@ -270,6 +270,12 @@ class nwLabels: nwBuildFmt.J_HTML: ".json", nwBuildFmt.J_NWD: ".json", } + FILE_FILTERS = { + "*.txt": QT_TRANSLATE_NOOP("Constant", "Text files"), + "*.md": QT_TRANSLATE_NOOP("Constant", "Markdown files"), + "*.nwd": QT_TRANSLATE_NOOP("Constant", "novelWriter files"), + "*": QT_TRANSLATE_NOOP("Constant", "All files"), + } UNIT_NAME = { "mm": QT_TRANSLATE_NOOP("Constant", "Millimetres"), "cm": QT_TRANSLATE_NOOP("Constant", "Centimetres"), diff --git a/tests/test_base/test_base_common.py b/tests/test_base/test_base_common.py index 0aa96456..7cadfe9e 100644 --- a/tests/test_base/test_base_common.py +++ b/tests/test_base/test_base_common.py @@ -34,11 +34,11 @@ from PyQt5.QtCore import QUrl from novelwriter.common import ( checkBool, checkFloat, checkInt, checkIntTuple, checkPath, checkString, - checkStringNone, checkUuid, formatInt, formatTime, formatTimeStamp, - formatVersion, fuzzyTime, getFileSize, hexToInt, isHandle, isItemClass, - isItemLayout, isItemType, isTitleTag, jsonEncode, makeFileNameSafe, minmax, - numberToRoman, NWConfigParser, openExternalPath, readTextFile, simplified, - transferCase, xmlIndent, yesNo + checkStringNone, checkUuid, formatFileFilter, formatInt, formatTime, + formatTimeStamp, formatVersion, fuzzyTime, getFileSize, hexToInt, isHandle, + isItemClass, isItemLayout, isItemType, isTitleTag, jsonEncode, + makeFileNameSafe, minmax, numberToRoman, NWConfigParser, openExternalPath, + readTextFile, simplified, transferCase, xmlIndent, yesNo ) @@ -346,6 +346,18 @@ def testBaseCommon_formatVersion(): # END Test testBaseCommon_formatVersion +@pytest.mark.base +def testBaseCommon_formatFileFilter(): + """Test the formatFileFilter function.""" + assert formatFileFilter(["*.txt"]) == "Text files (*.txt)" + assert formatFileFilter(["*.txt", "*"]) == "Text files (*.txt);;All files (*)" + assert formatFileFilter([("Stuff", "*.stuff"), "*.txt", "*"]) == ( + "Stuff (*.stuff);;Text files (*.txt);;All files (*)" + ) + +# END Test testBaseCommon_formatFileFilter + + @pytest.mark.base def testBaseCommon_simplified(): """Test the simplified function."""