From 2a99cafbf23cc84ffc0632de148a0d371beec844 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 16 Jun 2024 00:21:54 +0200 Subject: [PATCH 1/9] Add a class to store last used paths --- novelwriter/config.py | 78 ++++++++++++++++++++++++++++++++++------ novelwriter/constants.py | 1 + 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/novelwriter/config.py b/novelwriter/config.py index 148e75d4..d651908d 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -103,7 +103,8 @@ class Config: # User Settings # ============= - self._recentObj = RecentProjects(self) + self._recentProjects = RecentProjects(self) + self._recentPaths = RecentPaths(self) # General GUI Settings self.guiLocale = self._qLocale.name() @@ -253,7 +254,7 @@ class Config: @property def recentProjects(self) -> RecentProjects: - return self._recentObj + return self._recentProjects @property def mainWinSize(self) -> list[int]: @@ -343,7 +344,7 @@ class Config: self._outlnPanePos = [int(x/self.guiScale) for x in pos] return - def setLastPath(self, path: str | Path) -> None: + def setLastPath(self, path: str | Path, key: str | None = None) -> None: """Set the last used path. Only the folder is saved, so if the path is not a folder, the parent of the path is used instead. """ @@ -352,8 +353,8 @@ class Config: if not path.is_dir(): path = path.parent if path.is_dir(): - self._lastPath = path - logger.debug("Last path updated: %s" % self._lastPath) + self._recentPaths.setPath(key or "default", path) + self._recentPaths.saveCache() return def setBackupPath(self, path: Path | str) -> None: @@ -438,11 +439,12 @@ class Config: return self._appPath / "assets" / target return self._appPath / "assets" - def lastPath(self) -> Path: + def lastPath(self, key: str | None = None) -> Path: """Return the last path used by the user, if it exists.""" - if isinstance(self._lastPath, Path): - if self._lastPath.is_dir(): - return self._lastPath + if path := self._recentPaths.getPath(key or "default"): + asPath = Path(path) + if asPath.is_dir(): + return asPath return self._homePath def backupPath(self) -> Path: @@ -531,7 +533,8 @@ class Config: (self._dataPath / "syntax").mkdir(exist_ok=True) (self._dataPath / "themes").mkdir(exist_ok=True) - self._recentObj.loadCache() + self._recentPaths.loadCache() + self._recentProjects.loadCache() self._checkOptionalPackages() logger.debug("Config instance initialised") @@ -811,7 +814,7 @@ class Config: """Pack a list of items into a comma-separated string for saving to the config file. """ - return ", ".join([str(inVal) for inVal in data]) + return ", ".join(str(inVal) for inVal in data) def _checkOptionalPackages(self) -> None: """Check optional packages used by some features.""" @@ -893,3 +896,56 @@ class RecentProjects: logger.debug("Removed recent: %s", path) self.saveCache() return + + +class RecentPaths: + + KEYS = ["default", "project", "import", "outline", "stats"] + + def __init__(self, config: Config) -> None: + self._conf = config + self._data = {} + return + + def setPath(self, key: str, path: Path | str) -> None: + """Set a path for a given key.""" + if key in self.KEYS: + self._data[key] = str(path) + + def getPath(self, key: str) -> str | None: + """Get a path for a given key, or return None.""" + return self._data.get(key) + + def loadCache(self) -> bool: + """Load the cache file for recent projects.""" + self._data = {} + + cacheFile = self._conf.dataPath(nwFiles.RECENT_PATH) + if cacheFile.is_file(): + try: + with open(cacheFile, mode="r", encoding="utf-8") as inFile: + data = json.load(inFile) + for key, path in data.items(): + if isinstance(path, str) and key in self.KEYS: + data[key] = path + except Exception: + logger.error("Could not load recent paths cache") + logException() + return False + + return True + + def saveCache(self) -> bool: + """Save the cache dictionary of recent projects.""" + cacheFile = self._conf.dataPath(nwFiles.RECENT_PATH) + cacheTemp = cacheFile.with_suffix(".tmp") + try: + with open(cacheTemp, mode="w+", encoding="utf-8") as outFile: + json.dump(self._data, outFile, indent=2) + cacheTemp.replace(cacheFile) + except Exception: + logger.error("Could not save recent paths cache") + logException() + return False + + return True diff --git a/novelwriter/constants.py b/novelwriter/constants.py index bf62caeb..5186a5d1 100644 --- a/novelwriter/constants.py +++ b/novelwriter/constants.py @@ -104,6 +104,7 @@ class nwFiles: # Config Files CONF_FILE = "novelwriter.conf" RECENT_FILE = "recentProjects.json" + RECENT_PATH = "recentPaths.json" # Project Root Files PROJ_FILE = "nwProject.nwx" From 928a1166661c2f0d720fe36d83913bf9200c3b1e Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 16 Jun 2024 00:22:38 +0200 Subject: [PATCH 2/9] Update current usage of last path --- novelwriter/config.py | 4 ++-- novelwriter/gui/outline.py | 4 ++-- novelwriter/guimain.py | 4 ++-- novelwriter/tools/welcome.py | 4 ++-- novelwriter/tools/writingstats.py | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/novelwriter/config.py b/novelwriter/config.py index d651908d..f9cd6a08 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -344,7 +344,7 @@ class Config: self._outlnPanePos = [int(x/self.guiScale) for x in pos] return - def setLastPath(self, path: str | Path, key: str | None = None) -> None: + def setLastPath(self, key: str, path: str | Path) -> None: """Set the last used path. Only the folder is saved, so if the path is not a folder, the parent of the path is used instead. """ @@ -353,7 +353,7 @@ class Config: if not path.is_dir(): path = path.parent if path.is_dir(): - self._recentPaths.setPath(key or "default", path) + self._recentPaths.setPath(key, path) self._recentPaths.saveCache() return diff --git a/novelwriter/gui/outline.py b/novelwriter/gui/outline.py index d404794a..aa3d756d 100644 --- a/novelwriter/gui/outline.py +++ b/novelwriter/gui/outline.py @@ -523,12 +523,12 @@ class GuiOutlineTree(QTreeWidget): @pyqtSlot() def exportOutline(self) -> None: """Export the outline as a CSV file.""" - path = CONFIG.lastPath() / f"{makeFileNameSafe(SHARED.project.data.name)}.csv" + path = CONFIG.lastPath("outline") / f"{makeFileNameSafe(SHARED.project.data.name)}.csv" path, _ = QFileDialog.getSaveFileName( self, self.tr("Save Outline As"), str(path), formatFileFilter(["*.csv", "*"]) ) if path: - CONFIG.setLastPath(path) + CONFIG.setLastPath("outline", path) logger.info("Writing CSV file: %s", path) cols = [col for col in self._treeOrder if not self._colHidden[col]] order = [self._colIdx[col] for col in cols] diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index 6fd1e1be..ed4b1650 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -652,7 +652,7 @@ class GuiMain(QMainWindow): logger.error("No project open") return False - lastPath = CONFIG.lastPath() + lastPath = CONFIG.lastPath("import") ffilter = formatFileFilter(["*.txt", "*.md", "*.nwd", "*"]) loadFile, _ = QFileDialog.getOpenFileName( self, self.tr("Import File"), str(lastPath), filter=ffilter @@ -667,7 +667,7 @@ class GuiMain(QMainWindow): try: with open(loadFile, mode="rt", encoding="utf-8") as inFile: text = inFile.read() - CONFIG.setLastPath(loadFile) + CONFIG.setLastPath("import", loadFile) except Exception as exc: SHARED.error(self.tr( "Could not read file. The file must be an existing text file." diff --git a/novelwriter/tools/welcome.py b/novelwriter/tools/welcome.py index 3f47b707..a4405d1b 100644 --- a/novelwriter/tools/welcome.py +++ b/novelwriter/tools/welcome.py @@ -220,8 +220,8 @@ class GuiWelcome(NDialog): @pyqtSlot() def _browseForProject(self) -> None: """Browse for a project to open.""" - if path := SHARED.getProjectPath(self, path=CONFIG.lastPath(), allowZip=False): - CONFIG.setLastPath(path) + if path := SHARED.getProjectPath(self, path=CONFIG.lastPath("project"), allowZip=False): + CONFIG.setLastPath("project", path) self._openProjectPath(path) return diff --git a/novelwriter/tools/writingstats.py b/novelwriter/tools/writingstats.py index 8e42a0c0..864ad177 100644 --- a/novelwriter/tools/writingstats.py +++ b/novelwriter/tools/writingstats.py @@ -384,14 +384,14 @@ class GuiWritingStats(NToolDialog): return False # Generate the file name - savePath = CONFIG.lastPath() / f"sessionStats.{fileExt}" + savePath = CONFIG.lastPath("stats") / f"sessionStats.{fileExt}" savePath, _ = QFileDialog.getSaveFileName( self, self.tr("Save Data As"), str(savePath), f"{textFmt} (*.{fileExt})" ) if not savePath: return False - CONFIG.setLastPath(savePath) + CONFIG.setLastPath("stats", savePath) # Do the actual writing wSuccess = False From ea247c581435dece9dcb8b3296b0ca1536f8516f Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 16 Jun 2024 00:31:02 +0200 Subject: [PATCH 3/9] Remember new project folder last used path (#1930) --- novelwriter/config.py | 8 ++++---- novelwriter/tools/welcome.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/novelwriter/config.py b/novelwriter/config.py index f9cd6a08..cd456428 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -919,15 +919,15 @@ class RecentPaths: def loadCache(self) -> bool: """Load the cache file for recent projects.""" self._data = {} - cacheFile = self._conf.dataPath(nwFiles.RECENT_PATH) if cacheFile.is_file(): try: with open(cacheFile, mode="r", encoding="utf-8") as inFile: data = json.load(inFile) - for key, path in data.items(): - if isinstance(path, str) and key in self.KEYS: - data[key] = path + if isinstance(data, dict): + for key, path in data.items(): + if key in self.KEYS and isinstance(path, str): + self._data[key] = path except Exception: logger.error("Could not load recent paths cache") logException() diff --git a/novelwriter/tools/welcome.py b/novelwriter/tools/welcome.py index a4405d1b..c2c516bf 100644 --- a/novelwriter/tools/welcome.py +++ b/novelwriter/tools/welcome.py @@ -221,7 +221,6 @@ class GuiWelcome(NDialog): def _browseForProject(self) -> None: """Browse for a project to open.""" if path := SHARED.getProjectPath(self, path=CONFIG.lastPath("project"), allowZip=False): - CONFIG.setLastPath("project", path) self._openProjectPath(path) return @@ -550,7 +549,7 @@ class _NewProjectForm(QWidget): def __init__(self, parent: QWidget) -> None: super().__init__(parent=parent) - self._basePath = CONFIG.homePath() + self._basePath = CONFIG.lastPath("project") self._fillMode = self.FILL_BLANK self._copyPath = None @@ -726,12 +725,13 @@ class _NewProjectForm(QWidget): @pyqtSlot() def _doBrowse(self) -> None: """Select a project folder.""" - if projDir := QFileDialog.getExistingDirectory( + if path := QFileDialog.getExistingDirectory( self, self.tr("Select Project Folder"), str(self._basePath), options=QFileDialog.Option.ShowDirsOnly ): - self._basePath = Path(projDir) + self._basePath = Path(path) self._updateProjPath() + CONFIG.setLastPath("project", path) return @pyqtSlot() From 35632abea32a5b0ea2423a5a5921acd97354b0b5 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 16 Jun 2024 00:37:21 +0200 Subject: [PATCH 4/9] Update current tests --- novelwriter/config.py | 4 ---- tests/conftest.py | 2 +- tests/reference/baseConfig_novelwriter.conf | 3 +-- tests/test_base/test_base_config.py | 12 ++++++------ 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/novelwriter/config.py b/novelwriter/config.py index cd456428..7eed2ed6 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -181,7 +181,6 @@ class Config: self.fmtPadThin = False # User Paths - self._lastPath = self._homePath # The user's last used path self._backupPath = self._backPath # Backup path to use, can be none # Spell Checking Settings @@ -518,7 +517,6 @@ class Config: logger.debug("Data Path: %s", self._dataPath) logger.debug("App Root: %s", self._appRoot) logger.debug("App Path: %s", self._appPath) - logger.debug("Last Path: %s", self._lastPath) logger.debug("PDF Manual: %s", self.pdfDocs) # If the config and data folders don't exist, create them @@ -603,7 +601,6 @@ class Config: self.hideHScroll = conf.rdBool(sec, "hidehscroll", self.hideHScroll) self.lastNotes = conf.rdStr(sec, "lastnotes", self.lastNotes) self.nativeFont = conf.rdBool(sec, "nativefont", self.nativeFont) - self._lastPath = conf.rdPath(sec, "lastpath", self._lastPath) # Sizes sec = "Sizes" @@ -713,7 +710,6 @@ class Config: "hidehscroll": str(self.hideHScroll), "lastnotes": str(self.lastNotes), "nativefont": str(self.nativeFont), - "lastpath": str(self._lastPath), } conf["Sizes"] = { diff --git a/tests/conftest.py b/tests/conftest.py index 5ea7cbb2..a4bc9ce9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -50,7 +50,7 @@ def resetConfigVars(): """Reset the CONFIG object and set various values for testing to prevent interfering with local OS. """ - CONFIG.setLastPath(_TMP_ROOT) + # CONFIG.setLastPath(_TMP_ROOT) CONFIG.setBackupPath(_TMP_ROOT) CONFIG.setGuiFont(None) CONFIG.setTextFont(None) diff --git a/tests/reference/baseConfig_novelwriter.conf b/tests/reference/baseConfig_novelwriter.conf index 0554bd6d..b9d485a2 100644 --- a/tests/reference/baseConfig_novelwriter.conf +++ b/tests/reference/baseConfig_novelwriter.conf @@ -1,5 +1,5 @@ [Meta] -timestamp = 2024-05-20 16:48:20 +timestamp = 2024-06-16 00:36:27 [Main] font = @@ -10,7 +10,6 @@ hidevscroll = False hidehscroll = False lastnotes = 0x0 nativefont = True -lastpath = [Sizes] mainwindow = 1200, 650 diff --git a/tests/test_base/test_base_config.py b/tests/test_base/test_base_config.py index 93a09a75..bb2ec406 100644 --- a/tests/test_base/test_base_config.py +++ b/tests/test_base/test_base_config.py @@ -213,21 +213,21 @@ def testBaseConfig_Methods(fncPath): assert tstConf.assetPath("stuff") == appPath / "assets" / "stuff" # Last Path - assert tstConf.lastPath() == Path.home().absolute() + assert tstConf.lastPath("project") == Path.home().absolute() tmpStuff = fncPath / "stuff" tmpStuff.mkdir() - tstConf.setLastPath(tmpStuff) - assert tstConf.lastPath() == tmpStuff + tstConf.setLastPath("project", tmpStuff) + assert tstConf.lastPath("project") == tmpStuff fileStuff = tmpStuff / "more_stuff.txt" fileStuff.write_text("Stuff") - tstConf.setLastPath(fileStuff) - assert tstConf.lastPath() == tmpStuff + tstConf.setLastPath("project", fileStuff) + assert tstConf.lastPath("project") == tmpStuff fileStuff.unlink() tmpStuff.rmdir() - assert tstConf.lastPath() == Path.home().absolute() + assert tstConf.lastPath("project") == Path.home().absolute() # Backup Path assert tstConf.backupPath() == tstConf._backPath From fe27acc3ef6ff9898619ebe5f68d32e966bd3ca5 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 16 Jun 2024 00:49:24 +0200 Subject: [PATCH 5/9] Add full test coverage --- novelwriter/config.py | 5 +-- tests/test_base/test_base_config.py | 58 ++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/novelwriter/config.py b/novelwriter/config.py index 7eed2ed6..1e8be1aa 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -353,7 +353,6 @@ class Config: path = path.parent if path.is_dir(): self._recentPaths.setPath(key, path) - self._recentPaths.saveCache() return def setBackupPath(self, path: Path | str) -> None: @@ -907,6 +906,8 @@ class RecentPaths: """Set a path for a given key.""" if key in self.KEYS: self._data[key] = str(path) + self.saveCache() + return def getPath(self, key: str) -> str | None: """Get a path for a given key, or return None.""" @@ -928,7 +929,6 @@ class RecentPaths: logger.error("Could not load recent paths cache") logException() return False - return True def saveCache(self) -> bool: @@ -943,5 +943,4 @@ class RecentPaths: logger.error("Could not save recent paths cache") logException() return False - return True diff --git a/tests/test_base/test_base_config.py b/tests/test_base/test_base_config.py index bb2ec406..c5ca9b72 100644 --- a/tests/test_base/test_base_config.py +++ b/tests/test_base/test_base_config.py @@ -20,6 +20,7 @@ along with this program. If not, see . """ from __future__ import annotations +import json import sys from pathlib import Path @@ -28,7 +29,7 @@ from shutil import copyfile import pytest from novelwriter import CONFIG -from novelwriter.config import Config, RecentProjects +from novelwriter.config import Config, RecentPaths, RecentProjects from novelwriter.constants import nwFiles from tests.mocked import MockApp, causeOSError @@ -440,3 +441,58 @@ def testBaseConfig_RecentCache(monkeypatch, tstPaths): assert recent.listEntries() == [ (str(pathOne), "Proj One", 100, 1600002000), ] + + +@pytest.mark.base +def testBaseConfig_RecentPaths(monkeypatch, tstPaths): + """Test recent paths file.""" + cacheFile = tstPaths.cnfDir / nwFiles.RECENT_PATH + recent = RecentPaths(CONFIG) + + # Load when there is no file should pass, but load nothing + assert not cacheFile.exists() + assert recent.loadCache() is True + assert recent._data == {} + + # Set valid paths + recent.setPath("default", tstPaths.cnfDir / "default") + recent.setPath("project", tstPaths.cnfDir / "project") + recent.setPath("import", tstPaths.cnfDir / "import") + recent.setPath("outline", tstPaths.cnfDir / "outline") + recent.setPath("stats", tstPaths.cnfDir / "stats") + + # Set invalid path + recent.setPath("foobar", tstPaths.cnfDir / "foobar") + + # Check valid paths + assert recent.getPath("default") == str(tstPaths.cnfDir / "default") + assert recent.getPath("project") == str(tstPaths.cnfDir / "project") + assert recent.getPath("import") == str(tstPaths.cnfDir / "import") + assert recent.getPath("outline") == str(tstPaths.cnfDir / "outline") + assert recent.getPath("stats") == str(tstPaths.cnfDir / "stats") + + # Check invalid path + assert recent.getPath("foobar") is None + + # Check file + expected = { + "default": str(tstPaths.cnfDir / "default"), + "project": str(tstPaths.cnfDir / "project"), + "import": str(tstPaths.cnfDir / "import"), + "outline": str(tstPaths.cnfDir / "outline"), + "stats": str(tstPaths.cnfDir / "stats"), + } + + assert cacheFile.exists() + assert json.loads(cacheFile.read_text()) == expected + + # Clear and reload + recent._data = {} + recent.loadCache() + assert recent._data == expected + + # Check error handling + with monkeypatch.context() as mp: + mp.setattr("builtins.open", causeOSError) + assert recent.saveCache() is False + assert recent.loadCache() is False From df34293e7488452586abf1c0dc5bf50edf9bac78 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 16 Jun 2024 00:54:48 +0200 Subject: [PATCH 6/9] Update docstring --- novelwriter/config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/novelwriter/config.py b/novelwriter/config.py index 1e8be1aa..38ae7d52 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -5,6 +5,7 @@ novelWriter – Config Class File History: Created: 2018-09-22 [0.0.1] Config Created: 2022-11-09 [2.0rc2] RecentProjects +Created: 2024-06-16 [2.5rc1] RecentPaths This file is a part of novelWriter Copyright 2018–2024, Veronica Berglyd Olsen From 1b7d331e41a98b2fbff36a9a54825d4596fa3483 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 16 Jun 2024 00:55:33 +0200 Subject: [PATCH 7/9] Update more docstring --- novelwriter/config.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/novelwriter/config.py b/novelwriter/config.py index 38ae7d52..fa12ac07 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -904,7 +904,7 @@ class RecentPaths: return def setPath(self, key: str, path: Path | str) -> None: - """Set a path for a given key.""" + """Set a path for a given key, and save the cache.""" if key in self.KEYS: self._data[key] = str(path) self.saveCache() @@ -915,7 +915,7 @@ class RecentPaths: return self._data.get(key) def loadCache(self) -> bool: - """Load the cache file for recent projects.""" + """Load the cache file for recent paths.""" self._data = {} cacheFile = self._conf.dataPath(nwFiles.RECENT_PATH) if cacheFile.is_file(): @@ -933,7 +933,7 @@ class RecentPaths: return True def saveCache(self) -> bool: - """Save the cache dictionary of recent projects.""" + """Save the cache dictionary of recent paths.""" cacheFile = self._conf.dataPath(nwFiles.RECENT_PATH) cacheTemp = cacheFile.with_suffix(".tmp") try: From a3381f1f796951193e4c251d07060937b20a767d Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 16 Jun 2024 11:23:42 +0200 Subject: [PATCH 8/9] Remove fallback parameter for lastPath and remove commented out code --- novelwriter/config.py | 4 ++-- novelwriter/tools/welcome.py | 2 +- tests/conftest.py | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/novelwriter/config.py b/novelwriter/config.py index fa12ac07..d122a0b1 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -438,9 +438,9 @@ class Config: return self._appPath / "assets" / target return self._appPath / "assets" - def lastPath(self, key: str | None = None) -> Path: + def lastPath(self, key: str) -> Path: """Return the last path used by the user, if it exists.""" - if path := self._recentPaths.getPath(key or "default"): + if path := self._recentPaths.getPath(key): asPath = Path(path) if asPath.is_dir(): return asPath diff --git a/novelwriter/tools/welcome.py b/novelwriter/tools/welcome.py index c2c516bf..b962e98c 100644 --- a/novelwriter/tools/welcome.py +++ b/novelwriter/tools/welcome.py @@ -220,7 +220,7 @@ class GuiWelcome(NDialog): @pyqtSlot() def _browseForProject(self) -> None: """Browse for a project to open.""" - if path := SHARED.getProjectPath(self, path=CONFIG.lastPath("project"), allowZip=False): + if path := SHARED.getProjectPath(self, path=CONFIG.homePath(), allowZip=False): self._openProjectPath(path) return diff --git a/tests/conftest.py b/tests/conftest.py index a4bc9ce9..c8abbfda 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -50,7 +50,6 @@ def resetConfigVars(): """Reset the CONFIG object and set various values for testing to prevent interfering with local OS. """ - # CONFIG.setLastPath(_TMP_ROOT) CONFIG.setBackupPath(_TMP_ROOT) CONFIG.setGuiFont(None) CONFIG.setTextFont(None) From 14f16974281009552106333d4689bb0978d076c6 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sun, 16 Jun 2024 11:23:59 +0200 Subject: [PATCH 9/9] Rename lastPath in build settings --- novelwriter/core/buildsettings.py | 6 ++--- novelwriter/tools/manusbuild.py | 6 ++--- tests/test_core/test_core_buildsettings.py | 28 +++++++++++----------- tests/test_tools/test_tools_manusbuild.py | 4 ++-- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/novelwriter/core/buildsettings.py b/novelwriter/core/buildsettings.py index 72fd395b..3ceee536 100644 --- a/novelwriter/core/buildsettings.py +++ b/novelwriter/core/buildsettings.py @@ -219,7 +219,7 @@ class BuildSettings: return self._order @property - def lastPath(self) -> Path: + def lastBuildPath(self) -> Path: """The last used build path.""" if self._path.is_dir(): return self._path @@ -293,7 +293,7 @@ class BuildSettings: self._order = value return - def setLastPath(self, path: Path | str | None) -> None: + def setLastBuildPath(self, path: Path | str | None) -> None: """Set the last used build path.""" if isinstance(path, str): path = Path(path) @@ -461,7 +461,7 @@ class BuildSettings: self.setName(data.get("name", "")) self.setBuildID(data.get("uuid", "")) self.setOrder(data.get("order", 0)) - self.setLastPath(data.get("path", None)) + self.setLastBuildPath(data.get("path", None)) self.setLastBuildName(data.get("build", "")) buildFmt = str(data.get("format", "")) diff --git a/novelwriter/tools/manusbuild.py b/novelwriter/tools/manusbuild.py index a8f2f7c2..d87b9be2 100644 --- a/novelwriter/tools/manusbuild.py +++ b/novelwriter/tools/manusbuild.py @@ -220,7 +220,7 @@ class GuiManuscriptBuild(NDialog): self.btnBuild.setFocus() self._populateContentList() - self.buildPath.setText(str(self._build.lastPath)) + self.buildPath.setText(str(self._build.lastBuildPath)) if self._build.lastBuildName: self.buildName.setText(self._build.lastBuildName) else: @@ -274,7 +274,7 @@ class GuiManuscriptBuild(NDialog): def _doSelectPath(self) -> None: """Select a folder for output.""" bPath = Path(self.buildPath.text()) - bPath = bPath if bPath.is_dir() else self._build.lastPath + bPath = bPath if bPath.is_dir() else self._build.lastBuildPath savePath = QFileDialog.getExistingDirectory( self, self.tr("Select Folder"), str(bPath) ) @@ -336,7 +336,7 @@ class GuiManuscriptBuild(NDialog): for i, _ in docBuild.iterBuild(buildPath, bFormat): self.buildProgress.setValue(i+1) - self._build.setLastPath(bPath) + self._build.setLastBuildPath(bPath) self._build.setLastBuildName(bName) self._build.setLastFormat(bFormat) diff --git a/tests/test_core/test_core_buildsettings.py b/tests/test_core/test_core_buildsettings.py index d08bd6c4..b1308ea7 100644 --- a/tests/test_core/test_core_buildsettings.py +++ b/tests/test_core/test_core_buildsettings.py @@ -73,29 +73,29 @@ def testCoreBuildSettings_ClassAttributes(fncPath: Path): assert isUUID(build.buildID) # Last path must be valid, if not it defaults to $HOME - build.setLastPath("/path/to/nowhere") - assert build.lastPath == CONFIG.homePath() + build.setLastBuildPath("/path/to/nowhere") + assert build.lastBuildPath == CONFIG.homePath() - build.setLastPath(None) - assert build.lastPath == CONFIG.homePath() + build.setLastBuildPath(None) + assert build.lastBuildPath == CONFIG.homePath() (fncPath / "test.txt").write_text("foobar") - build.setLastPath(fncPath / "test.txt") # Can't be a file - assert build.lastPath == CONFIG.homePath() + build.setLastBuildPath(fncPath / "test.txt") # Can't be a file + assert build.lastBuildPath == CONFIG.homePath() - build.setLastPath(fncPath) - assert build.lastPath == fncPath + build.setLastBuildPath(fncPath) + assert build.lastBuildPath == fncPath - build.setLastPath(str(fncPath)) # String paths are also ok - assert build.lastPath == fncPath + build.setLastBuildPath(str(fncPath)) # String paths are also ok + assert build.lastBuildPath == fncPath # Last path no longer exists -> fallback to $HOME testDir = fncPath / "test_dir" testDir.mkdir() - build.setLastPath(testDir) - assert build.lastPath == testDir + build.setLastBuildPath(testDir) + assert build.lastBuildPath == testDir testDir.rmdir() - assert build.lastPath == CONFIG.homePath() + assert build.lastBuildPath == CONFIG.homePath() # Last build name build.setLastBuildName(None) # type: ignore @@ -119,7 +119,7 @@ def testCoreBuildSettings_ClassAttributes(fncPath: Path): # Set some sensible values build.setName("Test Build") build.setBuildID("5cf45d24-f496-42c9-8733-529a9e52a62b") - build.setLastPath(fncPath) + build.setLastBuildPath(fncPath) build.setLastBuildName("Build Name") build.setLastFormat(nwBuildFmt.HTML) diff --git a/tests/test_tools/test_tools_manusbuild.py b/tests/test_tools/test_tools_manusbuild.py index eb1685aa..b6e22edc 100644 --- a/tests/test_tools/test_tools_manusbuild.py +++ b/tests/test_tools/test_tools_manusbuild.py @@ -47,7 +47,7 @@ def testToolManuscriptBuild_Main( buildTestProject(nwGUI, projPath) nwGUI.openProject(projPath) build = BuildSettings() - build.setLastPath(fncPath) + build.setLastBuildPath(fncPath) manus = GuiManuscriptBuild(nwGUI, build) manus.show() @@ -100,7 +100,7 @@ def testToolManuscriptBuild_Main( assert build.lastBuildName == "TestBuild" assert build.lastFormat == lastFmt - assert build.lastPath == fncPath + assert build.lastBuildPath == fncPath # Error Handling # ==============