From 44926a4e9a7039f5fe4ac871d1d89372c0cc723c Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sat, 28 May 2022 14:33:25 +0200 Subject: [PATCH] Also make tree and options properties of the project --- novelwriter/core/document.py | 2 +- novelwriter/core/index.py | 6 +- novelwriter/core/project.py | 86 ++++++++++++---------- novelwriter/core/tokenizer.py | 6 +- novelwriter/dialogs/docmerge.py | 8 +- novelwriter/dialogs/docsplit.py | 13 ++-- novelwriter/dialogs/itemeditor.py | 2 +- novelwriter/dialogs/projdetails.py | 45 ++++++------ novelwriter/dialogs/projsettings.py | 23 +++--- novelwriter/dialogs/wordlist.py | 11 +-- novelwriter/gui/doceditor.py | 9 +-- novelwriter/gui/dochighlight.py | 2 +- novelwriter/gui/docviewer.py | 10 +-- novelwriter/gui/itemdetails.py | 2 +- novelwriter/gui/outline.py | 20 ++--- novelwriter/gui/outlinedetails.py | 3 +- novelwriter/gui/projtree.py | 44 +++++------ novelwriter/guimain.py | 12 +-- novelwriter/tools/build.py | 90 +++++++++++------------ novelwriter/tools/writingstats.py | 67 ++++++++--------- tests/test_core/test_core_document.py | 2 +- tests/test_core/test_core_index.py | 32 ++++---- tests/test_core/test_core_project.py | 50 ++++++------- tests/test_dialogs/test_dlg_itemeditor.py | 4 +- tests/test_gui/test_gui_doceditor.py | 18 ++--- tests/test_gui/test_gui_docviewer.py | 2 +- tests/test_gui/test_gui_guimain.py | 20 ++--- tests/test_gui/test_gui_projtree.py | 50 ++++++------- 28 files changed, 324 insertions(+), 315 deletions(-) diff --git a/novelwriter/core/document.py b/novelwriter/core/document.py index 2334c77c..5420d44e 100644 --- a/novelwriter/core/document.py +++ b/novelwriter/core/document.py @@ -52,7 +52,7 @@ class NWDoc(): self._docHandle = theHandle if self._docHandle is not None: - self._theItem = self.theProject.projTree[theHandle] + self._theItem = self.theProject.tree[theHandle] return diff --git a/novelwriter/core/index.py b/novelwriter/core/index.py index 9b8dd47c..7647a9f6 100644 --- a/novelwriter/core/index.py +++ b/novelwriter/core/index.py @@ -107,7 +107,7 @@ class NWIndex(): project. """ logger.debug("Re-indexing item '%s'", tHandle) - if not self.theProject.projTree.checkType(tHandle, nwItemType.FILE): + if not self.theProject.tree.checkType(tHandle, nwItemType.FILE): return False theDoc = NWDoc(self.theProject, tHandle) @@ -207,7 +207,7 @@ class NWIndex(): files before we save them in which case we already have the text. """ - theItem = self.theProject.projTree[tHandle] + theItem = self.theProject.tree[tHandle] if theItem is None: logger.info("Not indexing unknown item '%s'", tHandle) return False @@ -639,7 +639,7 @@ class NWIndex(): """Return a list of all handles that exist in the novel index. """ theHandles = [] - for tItem in self.theProject.projTree: + for tItem in self.theProject.tree: if tItem is None: continue if not tItem.isExported and skipExcluded: diff --git a/novelwriter/core/project.py b/novelwriter/core/project.py index 24a281b6..0a13cb16 100644 --- a/novelwriter/core/project.py +++ b/novelwriter/core/project.py @@ -63,10 +63,10 @@ class NWProject(): self.mainConf = novelwriter.CONFIG # Core Elements - self.optState = OptionState(self) # Project-specific GUI options - self.projTree = NWTree(self) # The project tree + self._optState = OptionState(self) # Project-specific GUI options + self._projTree = NWTree(self) # The project tree self._projIndex = NWIndex(self) # The projecty index - self.langData = {} # Localisation data + self._langData = {} # Localisation data # Project Status self.projOpened = 0 # The time stamp of when the project file was opened @@ -123,9 +123,17 @@ class NWProject(): ## @property - def index(self): + def index(self) -> NWIndex: return self._projIndex + @property + def tree(self) -> NWTree: + return self._projTree + + @property + def options(self) -> OptionState: + return self._optState + ## # Item Methods ## @@ -139,8 +147,8 @@ class NWProject(): newItem.setName(label) newItem.setType(nwItemType.ROOT) newItem.setClass(itemClass) - self.projTree.append(None, None, newItem) - self.projTree.updateItemData(newItem.itemHandle) + self._projTree.append(None, None, newItem) + self._projTree.updateItemData(newItem.itemHandle) return newItem.itemHandle def newFolder(self, label, pHandle): @@ -149,8 +157,8 @@ class NWProject(): newItem = NWItem(self) newItem.setName(label) newItem.setType(nwItemType.FOLDER) - self.projTree.append(None, pHandle, newItem) - self.projTree.updateItemData(newItem.itemHandle) + self._projTree.append(None, pHandle, newItem) + self._projTree.updateItemData(newItem.itemHandle) return newItem.itemHandle def newFile(self, label, pHandle): @@ -159,21 +167,21 @@ class NWProject(): newItem = NWItem(self) newItem.setName(label) newItem.setType(nwItemType.FILE) - self.projTree.append(None, pHandle, newItem) - self.projTree.updateItemData(newItem.itemHandle) + self._projTree.append(None, pHandle, newItem) + self._projTree.updateItemData(newItem.itemHandle) return newItem.itemHandle def trashFolder(self): """Add the special trash root folder to the project. """ - trashHandle = self.projTree.trashRoot() + trashHandle = self._projTree.trashRoot() if trashHandle is None: newItem = NWItem(self) newItem.setName(trConst(nwLabels.CLASS_NAME[nwItemClass.TRASH])) newItem.setType(nwItemType.ROOT) newItem.setClass(nwItemClass.TRASH) - self.projTree.append(None, None, newItem) - self.projTree.updateItemData(newItem.itemHandle) + self._projTree.append(None, None, newItem) + self._projTree.updateItemData(newItem.itemHandle) return newItem.itemHandle return trashHandle @@ -194,7 +202,7 @@ class NWProject(): self.autoCount = 0 # Project Tree - self.projTree.clear() + self._projTree.clear() # Project Settings self.projPath = None @@ -598,9 +606,9 @@ class NWProject(): elif xChild.tag == "content": logger.debug("Found project content") - self.projTree.unpackXML(xChild) + self._projTree.unpackXML(xChild) - self.optState.loadSettings() + self._optState.loadSettings() # Sort out old file locations if legacyList: @@ -618,12 +626,12 @@ class NWProject(): self.mainConf.saveRecentCache() # Check the project tree consistency - for tItem in self.projTree: + for tItem in self._projTree: tHandle = tItem.itemHandle logger.verbose("Checking item '%s'", tHandle) - if not self.projTree.updateItemData(tHandle): + if not self._projTree.updateItemData(tHandle): logger.error("There was a problem item '%s', and it has been removed", tHandle) - del self.projTree[tHandle] # The file will be re-added as orphaned + del self._projTree[tHandle] # The file will be re-added as orphaned self._scanProjectFolder() self._loadProjectLocalisation() @@ -710,7 +718,7 @@ class NWProject(): # Save Tree Content logger.debug("Writing project content") - self.projTree.packXML(nwXML) + self._projTree.packXML(nwXML) # Write the xml tree to file tempFile = os.path.join(self.projPath, self.projFile+"~") @@ -743,7 +751,7 @@ class NWProject(): return False # Save project GUI options - self.optState.saveSettings() + self._optState.saveSettings() # Update recent projects self.mainConf.updateRecentCache(self.projPath, self.projName, self.currWCount, saveTime) @@ -759,8 +767,8 @@ class NWProject(): """Close the current project and clear all meta data. """ logger.info("Closing project: %s", self.projPath) - self.optState.saveSettings() - self.projTree.writeToCFile() + self._optState.saveSettings() + self._projTree.writeToCFile() self._appendSessionStats(idleTime) self._clearLockFile() self.clearProject() @@ -1060,9 +1068,9 @@ class NWProject(): items in the GUI project tree. The user can rearrange the order by drag-and-drop. Forwarded to the NWTree class. """ - if len(self.projTree) != len(newOrder): + if len(self._projTree) != len(newOrder): logger.warning("Sizes of new and old tree order do not match") - self.projTree.setOrder(newOrder) + self._projTree.setOrder(newOrder) self.setProjectChanged(True) return True @@ -1156,16 +1164,16 @@ class NWProject(): capable of handling it. """ sentItems = [] - iterItems = self.projTree.handles() + iterItems = self._projTree.handles() n = 0 nMax = min(len(iterItems), 10000) while n < nMax: tHandle = iterItems[n] - tItem = self.projTree[tHandle] + tItem = self._projTree[tHandle] n += 1 if tItem is None: # Technically a bug since treeOrder is built from the - # same data as projTree + # same data as _projTree continue elif tItem.itemParent is None: # Item is a root, or already been identified as an @@ -1196,7 +1204,7 @@ class NWProject(): def updateWordCounts(self): """Update the total word count values. """ - wcNovel, wcNotes = self.projTree.sumWords() + wcNovel, wcNotes = self._projTree.sumWords() wcTotal = wcNovel + wcNotes if wcTotal != self.currWCount: self.currNovelWC = wcNovel @@ -1212,7 +1220,7 @@ class NWProject(): """ self.statusItems.resetCounts() self.importItems.resetCounts() - for nwItem in self.projTree: + for nwItem in self._projTree: if nwItem.isNovelLike(): self.statusItems.increment(nwItem.itemStatus) else: @@ -1224,7 +1232,7 @@ class NWProject(): return it. The variable is cast to a string before lookup. If the word does not exist, it returns itself. """ - return self.langData.get(str(theWord), str(theWord)) + return self._langData.get(str(theWord), str(theWord)) ## # Internal Functions @@ -1256,7 +1264,7 @@ class NWProject(): """Load the language data for the current project language. """ if self.projLang is None: - self.langData = {} + self._langData = {} return False langFile = os.path.join(self.mainConf.nwLangPath, "project_%s.json" % self.projLang) @@ -1265,7 +1273,7 @@ class NWProject(): try: with open(langFile, mode="r", encoding="utf-8") as inFile: - self.langData = json.load(inFile) + self._langData = json.load(inFile) logger.debug("Loaded project language file: %s", os.path.basename(langFile)) except Exception: @@ -1400,7 +1408,7 @@ class NWProject(): logger.warning("Skipping file: %s", fileItem) continue - if fHandle in self.projTree: + if fHandle in self._projTree: self.projFiles.append(fHandle) logger.debug("Checking file %s, handle '%s': OK", fileItem, fHandle) else: @@ -1447,10 +1455,10 @@ class NWProject(): if oLayout is None: oLayout = nwItemLayout.NOTE - if oParent is None or oParent not in self.projTree: - oParent = self.projTree.findRoot(oClass) + if oParent is None or oParent not in self._projTree: + oParent = self._projTree.findRoot(oClass) if oParent is None: - oParent = self.projTree.findRoot(nwItemClass.NOVEL) + oParent = self._projTree.findRoot(nwItemClass.NOVEL) # If the file still has no parent item, skip it if oParent is None: @@ -1462,8 +1470,8 @@ class NWProject(): orphItem.setType(nwItemType.FILE) orphItem.setClass(oClass) orphItem.setLayout(oLayout) - self.projTree.append(oHandle, oParent, orphItem) - self.projTree.updateItemData(orphItem.itemHandle) + self._projTree.append(oHandle, oParent, orphItem) + self._projTree.updateItemData(orphItem.itemHandle) if noWhere: self.theParent.makeAlert(self.tr( diff --git a/novelwriter/core/tokenizer.py b/novelwriter/core/tokenizer.py index 271ffd2c..bb5f3d8e 100644 --- a/novelwriter/core/tokenizer.py +++ b/novelwriter/core/tokenizer.py @@ -275,7 +275,7 @@ class Tokenizer(ABC): def addRootHeading(self, theHandle): """Add a heading at the start of a new root folder. """ - if not self.theProject.projTree.checkType(theHandle, nwItemType.ROOT): + if not self.theProject.tree.checkType(theHandle, nwItemType.ROOT): return False if self._isFirst: @@ -284,7 +284,7 @@ class Tokenizer(ABC): else: textAlign = self.A_PBB | self.A_CENTRE - theItem = self.theProject.projTree[theHandle] + theItem = self.theProject.tree[theHandle] locNotes = self._localLookup("Notes") theTitle = f"{locNotes}: {theItem.itemName}" self._theTokens = [] @@ -301,7 +301,7 @@ class Tokenizer(ABC): not set, load it from the file. """ self._theHandle = theHandle - self._theItem = self.theProject.projTree[theHandle] + self._theItem = self.theProject.tree[theHandle] if self._theItem is None: return False diff --git a/novelwriter/dialogs/docmerge.py b/novelwriter/dialogs/docmerge.py index c082dd3b..033f3698 100644 --- a/novelwriter/dialogs/docmerge.py +++ b/novelwriter/dialogs/docmerge.py @@ -125,13 +125,13 @@ class GuiDocMerge(QDialog): ), nwAlert.ERROR) return False - srcItem = self.theProject.projTree[self.sourceItem] + srcItem = self.theProject.tree[self.sourceItem] if srcItem is None: self.theParent.makeAlert(self.tr("Internal error."), nwAlert.ERROR) return False nHandle = self.theProject.newFile(srcItem.itemName, srcItem.itemParent) - newItem = self.theProject.projTree[nHandle] + newItem = self.theProject.tree[nHandle] newItem.setStatus(srcItem.itemStatus) newItem.setImport(srcItem.itemImport) @@ -170,7 +170,7 @@ class GuiDocMerge(QDialog): if tHandle is None: return False - nwItem = self.theProject.projTree[tHandle] + nwItem = self.theProject.tree[tHandle] if nwItem is None: return False @@ -182,7 +182,7 @@ class GuiDocMerge(QDialog): for sHandle in self.theParent.treeView.getTreeFromHandle(tHandle): newItem = QListWidgetItem() - nwItem = self.theProject.projTree[sHandle] + nwItem = self.theProject.tree[sHandle] if nwItem.itemType is not nwItemType.FILE: continue newItem.setText(nwItem.itemName) diff --git a/novelwriter/dialogs/docsplit.py b/novelwriter/dialogs/docsplit.py index ff2cb849..76e64d5f 100644 --- a/novelwriter/dialogs/docsplit.py +++ b/novelwriter/dialogs/docsplit.py @@ -50,7 +50,6 @@ class GuiDocSplit(QDialog): self.mainConf = novelwriter.CONFIG self.theParent = theParent self.theProject = theParent.theProject - self.optState = theParent.theProject.optState self.sourceItem = None self.sourceText = [] @@ -75,7 +74,7 @@ class GuiDocSplit(QDialog): self.splitLevel.addItem(self.tr("Split up to Header Level 3 (Scene)"), 3) self.splitLevel.addItem(self.tr("Split up to Header Level 4 (Section)"), 4) spIndex = self.splitLevel.findData( - self.optState.getInt("GuiDocSplit", "spLevel", 3) + self.theProject.options.getInt("GuiDocSplit", "spLevel", 3) ) if spIndex != -1: self.splitLevel.setCurrentIndex(spIndex) @@ -121,7 +120,7 @@ class GuiDocSplit(QDialog): ), nwAlert.ERROR) return False - srcItem = self.theProject.projTree[self.sourceItem] + srcItem = self.theProject.tree[self.sourceItem] if srcItem is None: self.theParent.makeAlert(self.tr( "Could not parse source document." @@ -184,7 +183,7 @@ class GuiDocSplit(QDialog): wTitle = wTitle.lstrip("#").strip() nHandle = self.theProject.newFile(wTitle, fHandle) - newItem = self.theProject.projTree[nHandle] + newItem = self.theProject.tree[nHandle] newItem.setStatus(srcItem.itemStatus) newItem.setImport(srcItem.itemImport) logger.verbose( @@ -211,7 +210,7 @@ class GuiDocSplit(QDialog): def _doClose(self): """Close the dialog window without doing anything. """ - self.optState.saveSettings() + self.theProject.options.saveSettings() self.close() return @@ -232,7 +231,7 @@ class GuiDocSplit(QDialog): if self.sourceItem is None: return False - nwItem = self.theProject.projTree[self.sourceItem] + nwItem = self.theProject.tree[self.sourceItem] if nwItem is None: return False @@ -249,7 +248,7 @@ class GuiDocSplit(QDialog): return False spLevel = self.splitLevel.currentData() - self.optState.setValue("GuiDocSplit", "spLevel", spLevel) + self.theProject.options.setValue("GuiDocSplit", "spLevel", spLevel) logger.debug( "Scanning document '%s' for headings level <= %d", self.sourceItem, spLevel diff --git a/novelwriter/dialogs/itemeditor.py b/novelwriter/dialogs/itemeditor.py index b5faec0d..acf07134 100644 --- a/novelwriter/dialogs/itemeditor.py +++ b/novelwriter/dialogs/itemeditor.py @@ -55,7 +55,7 @@ class GuiItemEditor(QDialog): # Build GUI ## - self.theItem = self.theProject.projTree[tHandle] + self.theItem = self.theProject.tree[tHandle] if self.theItem is None: self.close() return diff --git a/novelwriter/dialogs/projdetails.py b/novelwriter/dialogs/projdetails.py index 491df296..258b82e4 100644 --- a/novelwriter/dialogs/projdetails.py +++ b/novelwriter/dialogs/projdetails.py @@ -52,18 +52,18 @@ class GuiProjectDetails(PagedDialog): self.mainConf = novelwriter.CONFIG self.theParent = theParent self.theProject = theParent.theProject - self.optState = theParent.theProject.optState self.setWindowTitle(self.tr("Project Details")) wW = self.mainConf.pxInt(600) wH = self.mainConf.pxInt(400) + pOptions = self.theProject.options self.setMinimumWidth(wW) self.setMinimumHeight(wH) self.resize( - self.mainConf.pxInt(self.optState.getInt("GuiProjectDetails", "winWidth", wW)), - self.mainConf.pxInt(self.optState.getInt("GuiProjectDetails", "winHeight", wH)) + self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "winWidth", wW)), + self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "winHeight", wH)) ) self.tabMain = GuiProjectDetailsMain(self.theParent, self.theProject) @@ -120,16 +120,17 @@ class GuiProjectDetails(PagedDialog): countFrom = self.tabContents.poValue.value() clearDouble = self.tabContents.dblValue.isChecked() - self.optState.setValue("GuiProjectDetails", "winWidth", winWidth) - self.optState.setValue("GuiProjectDetails", "winHeight", winHeight) - self.optState.setValue("GuiProjectDetails", "widthCol0", widthCol0) - self.optState.setValue("GuiProjectDetails", "widthCol1", widthCol1) - self.optState.setValue("GuiProjectDetails", "widthCol2", widthCol2) - self.optState.setValue("GuiProjectDetails", "widthCol3", widthCol3) - self.optState.setValue("GuiProjectDetails", "widthCol4", widthCol4) - self.optState.setValue("GuiProjectDetails", "wordsPerPage", wordsPerPage) - self.optState.setValue("GuiProjectDetails", "countFrom", countFrom) - self.optState.setValue("GuiProjectDetails", "clearDouble", clearDouble) + pOptions = self.theProject.options + pOptions.setValue("GuiProjectDetails", "winWidth", winWidth) + pOptions.setValue("GuiProjectDetails", "winHeight", winHeight) + pOptions.setValue("GuiProjectDetails", "widthCol0", widthCol0) + pOptions.setValue("GuiProjectDetails", "widthCol1", widthCol1) + pOptions.setValue("GuiProjectDetails", "widthCol2", widthCol2) + pOptions.setValue("GuiProjectDetails", "widthCol3", widthCol3) + pOptions.setValue("GuiProjectDetails", "widthCol4", widthCol4) + pOptions.setValue("GuiProjectDetails", "wordsPerPage", wordsPerPage) + pOptions.setValue("GuiProjectDetails", "countFrom", countFrom) + pOptions.setValue("GuiProjectDetails", "clearDouble", clearDouble) return @@ -277,7 +278,6 @@ class GuiProjectDetailsContents(QWidget): self.theParent = theParent self.theProject = theProject self.theTheme = theParent.theTheme - self.optState = theProject.optState # Internal self._theToC = [] @@ -285,6 +285,7 @@ class GuiProjectDetailsContents(QWidget): iPx = self.theTheme.baseIconSize hPx = self.mainConf.pxInt(12) vPx = self.mainConf.pxInt(4) + pOptions = self.theProject.options # Contents Tree # ============= @@ -313,11 +314,11 @@ class GuiProjectDetailsContents(QWidget): treeHeader.setStretchLastSection(True) treeHeader.setMinimumSectionSize(hPx) - wCol0 = self.mainConf.pxInt(self.optState.getInt("GuiProjectDetails", "widthCol0", 200)) - wCol1 = self.mainConf.pxInt(self.optState.getInt("GuiProjectDetails", "widthCol1", 60)) - wCol2 = self.mainConf.pxInt(self.optState.getInt("GuiProjectDetails", "widthCol2", 60)) - wCol3 = self.mainConf.pxInt(self.optState.getInt("GuiProjectDetails", "widthCol3", 60)) - wCol4 = self.mainConf.pxInt(self.optState.getInt("GuiProjectDetails", "widthCol4", 90)) + wCol0 = self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol0", 200)) + wCol1 = self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol1", 60)) + wCol2 = self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol2", 60)) + wCol3 = self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol3", 60)) + wCol4 = self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol4", 90)) self.tocTree.setColumnWidth(0, wCol0) self.tocTree.setColumnWidth(1, wCol1) @@ -329,9 +330,9 @@ class GuiProjectDetailsContents(QWidget): # Options # ======= - wordsPerPage = self.optState.getInt("GuiProjectDetails", "wordsPerPage", 350) - countFrom = self.optState.getInt("GuiProjectDetails", "countFrom", 1) - clearDouble = self.optState.getInt("GuiProjectDetails", "clearDouble", True) + wordsPerPage = pOptions.getInt("GuiProjectDetails", "wordsPerPage", 350) + countFrom = pOptions.getInt("GuiProjectDetails", "countFrom", 1) + clearDouble = pOptions.getInt("GuiProjectDetails", "clearDouble", True) wordsHelp = ( self.tr("Typical word count for a 5 by 8 inch book page with 11 pt font is 350.") diff --git a/novelwriter/dialogs/projsettings.py b/novelwriter/dialogs/projsettings.py index 927f4ddd..8bbdcee3 100644 --- a/novelwriter/dialogs/projsettings.py +++ b/novelwriter/dialogs/projsettings.py @@ -52,19 +52,19 @@ class GuiProjectSettings(PagedDialog): self.mainConf = novelwriter.CONFIG self.theParent = theParent self.theProject = theParent.theProject - self.optState = theParent.theProject.optState self.theProject.countStatus() self.setWindowTitle(self.tr("Project Settings")) wW = self.mainConf.pxInt(570) wH = self.mainConf.pxInt(375) + pOptions = self.theProject.options self.setMinimumWidth(wW) self.setMinimumHeight(wH) self.resize( - self.mainConf.pxInt(self.optState.getInt("GuiProjectSettings", "winWidth", wW)), - self.mainConf.pxInt(self.optState.getInt("GuiProjectSettings", "winHeight", wH)) + self.mainConf.pxInt(pOptions.getInt("GuiProjectSettings", "winWidth", wW)), + self.mainConf.pxInt(pOptions.getInt("GuiProjectSettings", "winHeight", wH)) ) self.tabMain = GuiProjectEditMain(self.theParent, self.theProject) @@ -152,11 +152,12 @@ class GuiProjectSettings(PagedDialog): statusColW = self.mainConf.rpxInt(self.tabStatus.listBox.columnWidth(0)) importColW = self.mainConf.rpxInt(self.tabImport.listBox.columnWidth(0)) - self.optState.setValue("GuiProjectSettings", "winWidth", winWidth) - self.optState.setValue("GuiProjectSettings", "winHeight", winHeight) - self.optState.setValue("GuiProjectSettings", "replaceColW", replaceColW) - self.optState.setValue("GuiProjectSettings", "statusColW", statusColW) - self.optState.setValue("GuiProjectSettings", "importColW", importColW) + pOptions = self.theProject.options + pOptions.setValue("GuiProjectSettings", "winWidth", winWidth) + pOptions.setValue("GuiProjectSettings", "winHeight", winHeight) + pOptions.setValue("GuiProjectSettings", "replaceColW", replaceColW) + pOptions.setValue("GuiProjectSettings", "statusColW", statusColW) + pOptions.setValue("GuiProjectSettings", "importColW", importColW) return @@ -261,7 +262,6 @@ class GuiProjectEditStatus(QWidget): self.mainConf = novelwriter.CONFIG self.theParent = theParent self.theProject = theProject - self.optState = theProject.optState self.theTheme = theParent.theTheme if isStatus: @@ -274,7 +274,7 @@ class GuiProjectEditStatus(QWidget): colSetting = "importColW" wCol0 = self.mainConf.pxInt( - self.optState.getInt("GuiProjectSettings", colSetting, 130) + self.theProject.options.getInt("GuiProjectSettings", colSetting, 130) ) self.colDeleted = [] @@ -534,11 +534,10 @@ class GuiProjectEditReplace(QWidget): self.theParent = theParent self.theTheme = theParent.theTheme self.theProject = theProject - self.optState = theProject.optState self.arChanged = False wCol0 = self.mainConf.pxInt( - self.optState.getInt("GuiProjectSettings", "replaceColW", 130) + self.theProject.options.getInt("GuiProjectSettings", "replaceColW", 130) ) pageLabel = self.tr("Text Replace List for Preview and Export") diff --git a/novelwriter/dialogs/wordlist.py b/novelwriter/dialogs/wordlist.py index 7dadf258..77a4fb5a 100644 --- a/novelwriter/dialogs/wordlist.py +++ b/novelwriter/dialogs/wordlist.py @@ -52,19 +52,19 @@ class GuiWordList(QDialog): self.theParent = theParent self.theTheme = theParent.theTheme self.theProject = theParent.theProject - self.optState = theParent.theProject.optState self.setWindowTitle(self.tr("Project Word List")) mS = self.mainConf.pxInt(250) wW = self.mainConf.pxInt(320) wH = self.mainConf.pxInt(340) + pOptions = self.theProject.options self.setMinimumWidth(mS) self.setMinimumHeight(mS) self.resize( - self.mainConf.pxInt(self.optState.getInt("GuiWordList", "winWidth", wW)), - self.mainConf.pxInt(self.optState.getInt("GuiWordList", "winHeight", wH)) + self.mainConf.pxInt(pOptions.getInt("GuiWordList", "winWidth", wW)), + self.mainConf.pxInt(pOptions.getInt("GuiWordList", "winHeight", wH)) ) # Main Widgets @@ -207,8 +207,9 @@ class GuiWordList(QDialog): winWidth = self.mainConf.rpxInt(self.width()) winHeight = self.mainConf.rpxInt(self.height()) - self.optState.setValue("GuiWordList", "winWidth", winWidth) - self.optState.setValue("GuiWordList", "winHeight", winHeight) + pOptions = self.theProject.options + pOptions.setValue("GuiWordList", "winWidth", winWidth) + pOptions.setValue("GuiWordList", "winHeight", winHeight) return diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 9cd99497..64e72259 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -2701,15 +2701,15 @@ class GuiDocEditHeader(QWidget): if self.mainConf.showFullPath: tTitle = [] - tTree = self.theProject.projTree.getItemPath(tHandle) + tTree = self.theProject.tree.getItemPath(tHandle) for aHandle in reversed(tTree): - nwItem = self.theProject.projTree[aHandle] + nwItem = self.theProject.tree[aHandle] if nwItem is not None: tTitle.append(nwItem.itemName) sSep = " %s " % nwUnicode.U_RSAQUO self.theTitle.setText(sSep.join(tTitle)) else: - nwItem = self.theProject.projTree[tHandle] + nwItem = self.theProject.tree[tHandle] if nwItem is None: return False self.theTitle.setText(nwItem.itemName) @@ -2795,7 +2795,6 @@ class GuiDocEditFooter(QWidget): self.theParent = docEditor.theParent self.theProject = docEditor.theProject self.theTheme = docEditor.theTheme - self.optState = docEditor.theProject.optState self._theItem = None self._docHandle = None @@ -2918,7 +2917,7 @@ class GuiDocEditFooter(QWidget): logger.verbose("No handle set, so clearing the editor footer") self._theItem = None else: - self._theItem = self.theProject.projTree[self._docHandle] + self._theItem = self.theProject.tree[self._docHandle] self.setHasSelection(False) self.updateInfo() diff --git a/novelwriter/gui/dochighlight.py b/novelwriter/gui/dochighlight.py index 0133f91c..bd2d78eb 100644 --- a/novelwriter/gui/dochighlight.py +++ b/novelwriter/gui/dochighlight.py @@ -288,7 +288,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): if theText.startswith("@"): # Keywords and commands self.setCurrentBlockState(self.BLOCK_META) pIndex = self.theProject.index - tItem = self.theParent.theProject.projTree[self.theHandle] + tItem = self.theParent.theProject.tree[self.theHandle] isValid, theBits, thePos = pIndex.scanThis(theText) isGood = pIndex.checkThese(theBits, tItem) if isValid: diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index 615f121c..2587f125 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -160,7 +160,7 @@ class GuiDocViewer(QTextBrowser): def loadText(self, tHandle, updateHistory=True): """Load text into the viewer from an item handle. """ - if not self.theProject.projTree.checkType(tHandle, nwItemType.FILE): + if not self.theProject.tree.checkType(tHandle, nwItemType.FILE): logger.warning("Item not found") return False @@ -863,15 +863,15 @@ class GuiDocViewHeader(QWidget): if self.mainConf.showFullPath: tTitle = [] - tTree = self.theProject.projTree.getItemPath(tHandle) + tTree = self.theProject.tree.getItemPath(tHandle) for aHandle in reversed(tTree): - nwItem = self.theProject.projTree[aHandle] + nwItem = self.theProject.tree[aHandle] if nwItem is not None: tTitle.append(nwItem.itemName) sSep = " %s " % nwUnicode.U_RSAQUO self.theTitle.setText(sSep.join(tTitle)) else: - nwItem = self.theProject.projTree[tHandle] + nwItem = self.theProject.tree[tHandle] if nwItem is None: return False self.theTitle.setText(nwItem.itemName) @@ -1202,7 +1202,7 @@ class GuiDocViewDetails(QScrollArea): theRefs = self.theProject.index.getBackReferenceList(tHandle) theList = [] for tHandle in theRefs: - tItem = self.theProject.projTree[tHandle] + tItem = self.theProject.tree[tHandle] if tItem is not None: theList.append("%s" % ( tHandle, theRefs[tHandle], self.linkStyle, tItem.itemName diff --git a/novelwriter/gui/itemdetails.py b/novelwriter/gui/itemdetails.py index 88419395..89a38b76 100644 --- a/novelwriter/gui/itemdetails.py +++ b/novelwriter/gui/itemdetails.py @@ -227,7 +227,7 @@ class GuiItemDetails(QWidget): self.clearDetails() return - nwItem = self.theProject.projTree[tHandle] + nwItem = self.theProject.tree[tHandle] if nwItem is None: self.clearDetails() return diff --git a/novelwriter/gui/outline.py b/novelwriter/gui/outline.py index 2b7a654b..26cb8029 100644 --- a/novelwriter/gui/outline.py +++ b/novelwriter/gui/outline.py @@ -91,7 +91,6 @@ class GuiOutline(QTreeWidget): self.theParent = theParent self.theProject = theParent.theProject self.theTheme = theParent.theTheme - self.optState = theParent.theProject.optState self.headerMenu = GuiOutlineHeaderMenu(self) self.setFrameStyle(QFrame.NoFrame) @@ -273,10 +272,12 @@ class GuiOutline(QTreeWidget): """Load the state of the main tree header, that is, column order and column width. """ + pOptions = self.theProject.options + # Load whatever we saved last time, regardless of wether it # contains the correct names or number of columns. The names # must be valid though. - tempOrder = self.optState.getValue("GuiOutline", "headerOrder", []) + tempOrder = pOptions.getValue("GuiOutline", "headerOrder", []) treeOrder = [] for hName in tempOrder: try: @@ -299,14 +300,14 @@ class GuiOutline(QTreeWidget): # We load whatever column widths and hidden states we find in # the file, and leave the rest in their default state. - tmpWidth = self.optState.getValue("GuiOutline", "columnWidth", {}) + tmpWidth = pOptions.getValue("GuiOutline", "columnWidth", {}) for hName in tmpWidth: try: self._colWidth[nwOutline[hName]] = self.mainConf.pxInt(tmpWidth[hName]) except Exception: logger.warning("Ignored unknown outline column '%s'", str(hName)) - tmpHidden = self.optState.getValue("GuiOutline", "columnHidden", {}) + tmpHidden = pOptions.getValue("GuiOutline", "columnHidden", {}) for hName in tmpHidden: try: self._colHidden[nwOutline[hName]] = tmpHidden[hName] @@ -347,10 +348,11 @@ class GuiOutline(QTreeWidget): if not logHidden and logWidth > 0: colWidth[hName] = logWidth - self.optState.setValue("GuiOutline", "headerOrder", treeOrder) - self.optState.setValue("GuiOutline", "columnWidth", colWidth) - self.optState.setValue("GuiOutline", "columnHidden", colHidden) - self.optState.saveSettings() + pOptions = self.theProject.options + pOptions.setValue("GuiOutline", "headerOrder", treeOrder) + pOptions.setValue("GuiOutline", "columnWidth", colWidth) + pOptions.setValue("GuiOutline", "columnHidden", colHidden) + pOptions.saveSettings() return @@ -437,7 +439,7 @@ class GuiOutline(QTreeWidget): def _createTreeItem(self, tHandle, sTitle, novIdx): """Populate a tree item with all the column values. """ - nwItem = self.theProject.projTree[tHandle] + nwItem = self.theProject.tree[tHandle] newItem = QTreeWidgetItem() hIcon = "doc_%s" % novIdx["level"].lower() diff --git a/novelwriter/gui/outlinedetails.py b/novelwriter/gui/outlinedetails.py index 92d41c3c..40a3d29e 100644 --- a/novelwriter/gui/outlinedetails.py +++ b/novelwriter/gui/outlinedetails.py @@ -58,7 +58,6 @@ class GuiOutlineDetails(QScrollArea): self.theParent = theParent self.theProject = theParent.theProject self.theTheme = theParent.theTheme - self.optState = theParent.theProject.optState # Sizes minTitle = 30*self.theTheme.textNWidth @@ -283,7 +282,7 @@ class GuiOutlineDetails(QScrollArea): number pointing to a header. """ pIndex = self.theProject.index - nwItem = self.theProject.projTree[tHandle] + nwItem = self.theProject.tree[tHandle] novIdx = pIndex.getNovelData(tHandle, sTitle) theRefs = pIndex.getReferences(tHandle, sTitle) if nwItem is None or novIdx is None: diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index fd9e21ce..e35662f1 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -180,14 +180,14 @@ class GuiProjectTree(QTreeWidget): elif itemType in (nwItemType.FILE, nwItemType.FOLDER): sHandle = self.getSelectedHandle() - if sHandle is None or sHandle not in self.theProject.projTree: + if sHandle is None or sHandle not in self.theProject.tree: self.theParent.makeAlert(self.tr( "Did not find anywhere to add the file or folder!" ), nwAlert.ERROR) return False # If the selected item is a file, the new item will be a sibling - pItem = self.theProject.projTree[sHandle] + pItem = self.theProject.tree[sHandle] if pItem.itemType == nwItemType.FILE: nHandle = sHandle sHandle = pItem.itemParent @@ -195,7 +195,7 @@ class GuiProjectTree(QTreeWidget): logger.error("Internal error") # Bug return False - if self.theProject.projTree.isTrash(sHandle): + if self.theProject.tree.isTrash(sHandle): self.theParent.makeAlert(self.tr( "Cannot add new files or folders to the Trash folder." ), nwAlert.ERROR) @@ -221,7 +221,7 @@ class GuiProjectTree(QTreeWidget): # Add the new item to the tree self.revealNewTreeItem(tHandle, nHandle) self.theParent.editItem(tHandle) - nwItem = self.theProject.projTree[tHandle] + nwItem = self.theProject.tree[tHandle] # If this is a folder, return here if nwItem.itemType != nwItemType.FILE: @@ -254,7 +254,7 @@ class GuiProjectTree(QTreeWidget): def revealNewTreeItem(self, tHandle, nHandle=None): """Reveal a newly added project item in the project tree. """ - nwItem = self.theProject.projTree[tHandle] + nwItem = self.theProject.tree[tHandle] if nwItem is None: return False @@ -375,7 +375,7 @@ class GuiProjectTree(QTreeWidget): logger.error("No project open") return False - trashHandle = self.theProject.projTree.trashRoot() + trashHandle = self.theProject.tree.trashRoot() logger.debug("Emptying Trash folder") if trashHandle is None: @@ -436,7 +436,7 @@ class GuiProjectTree(QTreeWidget): return False trItemS = self._getTreeItem(tHandle) - nwItemS = self.theProject.projTree[tHandle] + nwItemS = self.theProject.tree[tHandle] if trItemS is None or nwItemS is None: logger.error("Could not find tree item for deletion") @@ -477,7 +477,7 @@ class GuiProjectTree(QTreeWidget): logger.error("Could not delete item") return False - if self.theProject.projTree.isTrash(tHandle): + if self.theProject.tree.isTrash(tHandle): # If the file is in the trash folder already, as the # user if they want to permanently delete the file. doPermanent = False @@ -531,7 +531,7 @@ class GuiProjectTree(QTreeWidget): already coming from the project tree. """ trItem = self._getTreeItem(tHandle) - nwItem = self.theProject.projTree[tHandle] + nwItem = self.theProject.tree[tHandle] if trItem is None or nwItem is None: return @@ -596,7 +596,7 @@ class GuiProjectTree(QTreeWidget): pHandle = pItem.data(self.C_NAME, Qt.UserRole) if pHandle: - if self.theProject.projTree.checkType(pHandle, nwItemType.FILE): + if self.theProject.tree.checkType(pHandle, nwItemType.FILE): # A file has an internal word count we need to account # for, but a folder always has 0 words on its own. pCount += self.theProject.index.getCounts(pHandle)[1] @@ -711,7 +711,7 @@ class GuiProjectTree(QTreeWidget): if isinstance(selItem, QTreeWidgetItem): tHandle = selItem.data(self.C_NAME, Qt.UserRole) self.setSelectedHandle(tHandle) # Just to be safe - tItem = self.theProject.projTree[tHandle] + tItem = self.theProject.tree[tHandle] if tItem is not None: if self.ctxMenu.filterActions(tItem): # Only open menu if any actions remain after filter @@ -749,7 +749,7 @@ class GuiProjectTree(QTreeWidget): return tHandle = selItem.data(self.C_NAME, Qt.UserRole) - tItem = self.theProject.projTree[tHandle] + tItem = self.theProject.tree[tHandle] if tItem is None: return @@ -797,7 +797,7 @@ class GuiProjectTree(QTreeWidget): """Run various maintenance tasks for a moved item. """ trItemS = self._getTreeItem(tHandle) - nwItemS = self.theProject.projTree[tHandle] + nwItemS = self.theProject.tree[tHandle] trItemP = trItemS.parent() if trItemP is None: logger.error("Failed to find new parent item of '%s'", tHandle) @@ -814,7 +814,7 @@ class GuiProjectTree(QTreeWidget): logger.debug("A total of %d item(s) were moved", len(mHandles)) for mHandle in mHandles: logger.debug("Updating item '%s'", mHandle) - self.theProject.projTree.updateItemData(mHandle) + self.theProject.tree.updateItemData(mHandle) # Update the index if nwItemS.isInactive(): @@ -847,7 +847,7 @@ class GuiProjectTree(QTreeWidget): def _deleteTreeItem(self, tHandle): """Permanently delete a tree item from the project and the map. """ - if self.theProject.projTree.checkType(tHandle, nwItemType.FILE): + if self.theProject.tree.checkType(tHandle, nwItemType.FILE): delDoc = NWDoc(self.theProject, tHandle) if not delDoc.deleteDocument(): self.theParent.makeAlert([ @@ -856,7 +856,7 @@ class GuiProjectTree(QTreeWidget): return False self.theProject.index.deleteHandle(tHandle) - del self.theProject.projTree[tHandle] + del self.theProject.tree[tHandle] self._treeMap.pop(tHandle, None) return True @@ -869,7 +869,7 @@ class GuiProjectTree(QTreeWidget): cCount = tItem.childCount() # Update tree-related meta data - nwItem = self.theProject.projTree[tHandle] + nwItem = self.theProject.tree[tHandle] nwItem.setExpanded(tItem.isExpanded() and cCount > 0) nwItem.setOrder(tIndex) @@ -943,7 +943,7 @@ class GuiProjectTree(QTreeWidget): trItem = self._getTreeItem(trashHandle) if trItem is None: trItem = self._addTreeItem( - self.theProject.projTree[trashHandle] + self.theProject.tree[trashHandle] ) if trItem is not None: trItem.setExpanded(True) @@ -963,8 +963,8 @@ class GuiProjectTree(QTreeWidget): def _emitItemChange(self, tHandle): """Emit an item change signal for a given handle. """ - if self.theProject.projTree.checkType(tHandle, nwItemType.FILE): - nwItem = self.theProject.projTree[tHandle] + if self.theProject.tree.checkType(tHandle, nwItemType.FILE): + nwItem = self.theProject.tree[tHandle] if nwItem.isNovelLike(): self.novelItemChanged.emit() else: @@ -1047,9 +1047,9 @@ class GuiProjectTreeMenu(QMenu): logger.error("Failed to extract information to build tree context menu") return False - trashHandle = self.theTree.theProject.projTree.trashRoot() + trashHandle = self.theTree.theProject.tree.trashRoot() - inTrash = self.theTree.theProject.projTree.isTrash(theItem.itemHandle) + inTrash = self.theTree.theProject.tree.isTrash(theItem.itemHandle) isTrash = theItem.itemHandle == trashHandle and trashHandle is not None isFile = theItem.itemType == nwItemType.FILE diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index 34f9abcd..3a957577 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -572,7 +572,7 @@ class GuiMain(QMainWindow): logger.error("No project open") return False - if not self.theProject.projTree.checkType(tHandle, nwItemType.FILE): + if not self.theProject.tree.checkType(tHandle, nwItemType.FILE): logger.debug("Requested item '%s' is not a document", tHandle) return False @@ -600,8 +600,8 @@ class GuiMain(QMainWindow): nHandle = None # The next handle after tHandle fHandle = None # The first file handle we encounter foundIt = False # We've found tHandle, pick the next we see - for tItem in self.theProject.projTree: - if not self.theProject.projTree.checkType(tItem.itemHandle, nwItemType.FILE): + for tItem in self.theProject.tree: + if not self.theProject.tree.checkType(tItem.itemHandle, nwItemType.FILE): continue if fHandle is None: fHandle = tItem.itemHandle @@ -818,7 +818,7 @@ class GuiMain(QMainWindow): logger.warning("No item selected") return False - tItem = self.theProject.projTree[tHandle] + tItem = self.theProject.tree[tHandle] if tItem is None: return False if tItem.itemType == nwItemType.NO_TYPE: @@ -864,7 +864,7 @@ class GuiMain(QMainWindow): self.treeView.saveTreeOrder() self.theProject.index.clearIndex() - for tItem in self.theProject.projTree: + for tItem in self.theProject.tree: if tItem is not None: self.setStatus(self.tr("Indexing: '{0}'").format(tItem.itemName)) @@ -1560,7 +1560,7 @@ class GuiMain(QMainWindow): """ tHandle = self.treeView.getSelectedHandle() if tHandle is not None: - tItem = self.theProject.projTree[tHandle] + tItem = self.theProject.tree[tHandle] if tItem is None: return if tItem.itemType == nwItemType.FILE: diff --git a/novelwriter/tools/build.py b/novelwriter/tools/build.py index d84a0d4c..06849ee9 100644 --- a/novelwriter/tools/build.py +++ b/novelwriter/tools/build.py @@ -75,7 +75,6 @@ class GuiBuildNovel(QDialog): self.theParent = theParent self.theTheme = theParent.theTheme self.theProject = theParent.theProject - self.optState = theParent.theProject.optState self.htmlText = [] # List of html documents self.htmlStyle = [] # List of html styles @@ -86,9 +85,10 @@ class GuiBuildNovel(QDialog): self.setMinimumWidth(self.mainConf.pxInt(700)) self.setMinimumHeight(self.mainConf.pxInt(600)) + pOptions = self.theProject.options self.resize( - self.mainConf.pxInt(self.optState.getInt("GuiBuildNovel", "winWidth", 900)), - self.mainConf.pxInt(self.optState.getInt("GuiBuildNovel", "winHeight", 800)) + self.mainConf.pxInt(pOptions.getInt("GuiBuildNovel", "winWidth", 900)), + self.mainConf.pxInt(pOptions.getInt("GuiBuildNovel", "winHeight", 800)) ) self.docView = GuiBuildNovelDocView(self, self.theProject) @@ -174,12 +174,12 @@ class GuiBuildNovel(QDialog): self.hideScene = QSwitch(width=wS, height=hS) self.hideScene.setChecked( - self.optState.getBool("GuiBuildNovel", "hideScene", False) + pOptions.getBool("GuiBuildNovel", "hideScene", False) ) self.hideSection = QSwitch(width=wS, height=hS) self.hideSection.setChecked( - self.optState.getBool("GuiBuildNovel", "hideSection", True) + pOptions.getBool("GuiBuildNovel", "hideSection", True) ) # Wrapper boxes due to QGridView and QLineEdit expand bug @@ -235,7 +235,7 @@ class GuiBuildNovel(QDialog): self.textFont.setReadOnly(True) self.textFont.setMinimumWidth(xFmt) self.textFont.setText( - self.optState.getString("GuiBuildNovel", "textFont", self.mainConf.textFont) + pOptions.getString("GuiBuildNovel", "textFont", self.mainConf.textFont) ) self.fontButton = QPushButton("...") self.fontButton.setMaximumWidth(int(2.5*self.theTheme.getTextWidth("..."))) @@ -247,7 +247,7 @@ class GuiBuildNovel(QDialog): self.textSize.setMaximum(72) self.textSize.setSingleStep(1) self.textSize.setValue( - self.optState.getInt("GuiBuildNovel", "textSize", self.mainConf.textSize) + pOptions.getInt("GuiBuildNovel", "textSize", self.mainConf.textSize) ) self.lineHeight = QDoubleSpinBox(self) @@ -257,7 +257,7 @@ class GuiBuildNovel(QDialog): self.lineHeight.setSingleStep(0.05) self.lineHeight.setDecimals(2) self.lineHeight.setValue( - self.optState.getFloat("GuiBuildNovel", "lineHeight", 1.15) + pOptions.getFloat("GuiBuildNovel", "lineHeight", 1.15) ) # Wrapper box due to QGridView and QLineEdit expand bug @@ -291,12 +291,12 @@ class GuiBuildNovel(QDialog): self.justifyText = QSwitch(width=wS, height=hS) self.justifyText.setChecked( - self.optState.getBool("GuiBuildNovel", "justifyText", False) + pOptions.getBool("GuiBuildNovel", "justifyText", False) ) self.noStyling = QSwitch(width=wS, height=hS) self.noStyling.setChecked( - self.optState.getBool("GuiBuildNovel", "noStyling", False) + pOptions.getBool("GuiBuildNovel", "noStyling", False) ) self.styleForm.addWidget(justifyLabel, 1, 0, 1, 1, Qt.AlignLeft) @@ -316,22 +316,22 @@ class GuiBuildNovel(QDialog): self.includeSynopsis = QSwitch(width=wS, height=hS) self.includeSynopsis.setChecked( - self.optState.getBool("GuiBuildNovel", "incSynopsis", False) + pOptions.getBool("GuiBuildNovel", "incSynopsis", False) ) self.includeComments = QSwitch(width=wS, height=hS) self.includeComments.setChecked( - self.optState.getBool("GuiBuildNovel", "incComments", False) + pOptions.getBool("GuiBuildNovel", "incComments", False) ) self.includeKeywords = QSwitch(width=wS, height=hS) self.includeKeywords.setChecked( - self.optState.getBool("GuiBuildNovel", "incKeywords", False) + pOptions.getBool("GuiBuildNovel", "incKeywords", False) ) self.includeBody = QSwitch(width=wS, height=hS) self.includeBody.setChecked( - self.optState.getBool("GuiBuildNovel", "incBodyText", True) + pOptions.getBool("GuiBuildNovel", "incBodyText", True) ) synopsisLabel = QLabel(self.tr("Include synopsis")) @@ -360,17 +360,17 @@ class GuiBuildNovel(QDialog): self.novelFiles = QSwitch(width=wS, height=hS) self.novelFiles.setChecked( - self.optState.getBool("GuiBuildNovel", "addNovel", True) + pOptions.getBool("GuiBuildNovel", "addNovel", True) ) self.noteFiles = QSwitch(width=wS, height=hS) self.noteFiles.setChecked( - self.optState.getBool("GuiBuildNovel", "addNotes", False) + pOptions.getBool("GuiBuildNovel", "addNotes", False) ) self.ignoreFlag = QSwitch(width=wS, height=hS) self.ignoreFlag.setChecked( - self.optState.getBool("GuiBuildNovel", "ignoreFlag", False) + pOptions.getBool("GuiBuildNovel", "ignoreFlag", False) ) novelLabel = QLabel(self.tr("Include novel files")) @@ -396,12 +396,12 @@ class GuiBuildNovel(QDialog): self.replaceTabs = QSwitch(width=wS, height=hS) self.replaceTabs.setChecked( - self.optState.getBool("GuiBuildNovel", "replaceTabs", False) + pOptions.getBool("GuiBuildNovel", "replaceTabs", False) ) self.replaceUCode = QSwitch(width=wS, height=hS) self.replaceUCode.setChecked( - self.optState.getBool("GuiBuildNovel", "replaceUCode", False) + pOptions.getBool("GuiBuildNovel", "replaceUCode", False) ) tabsLabel = QLabel(self.tr("Replace tabs with spaces")) @@ -493,9 +493,9 @@ class GuiBuildNovel(QDialog): # Splitter Position boxWidth = self.mainConf.pxInt(350) - boxWidth = self.optState.getInt("GuiBuildNovel", "boxWidth", boxWidth) + boxWidth = pOptions.getInt("GuiBuildNovel", "boxWidth", boxWidth) docWidth = max(self.width() - boxWidth, 100) - docWidth = self.optState.getInt("GuiBuildNovel", "docWidth", docWidth) + docWidth = pOptions.getInt("GuiBuildNovel", "docWidth", docWidth) # The Tool Box self.toolsBox = QVBoxLayout() @@ -712,10 +712,10 @@ class GuiBuildNovel(QDialog): self.theParent.treeView.flushTreeOrder() self.theParent.saveDocument() - self.buildProgress.setMaximum(len(self.theProject.projTree)) + self.buildProgress.setMaximum(len(self.theProject.tree)) self.buildProgress.setValue(0) - for nItt, tItem in enumerate(self.theProject.projTree): + for nItt, tItem in enumerate(self.theProject.tree): noteRoot = noteFiles noteRoot &= tItem.itemType == nwItemType.ROOT @@ -1153,28 +1153,28 @@ class GuiBuildNovel(QDialog): self.theProject.setProjectLang(buildLang) # GUI Settings - self.optState.setValue("GuiBuildNovel", "hideScene", hideScene) - self.optState.setValue("GuiBuildNovel", "hideSection", hideSection) - self.optState.setValue("GuiBuildNovel", "winWidth", winWidth) - self.optState.setValue("GuiBuildNovel", "winHeight", winHeight) - self.optState.setValue("GuiBuildNovel", "boxWidth", boxWidth) - self.optState.setValue("GuiBuildNovel", "docWidth", docWidth) - self.optState.setValue("GuiBuildNovel", "justifyText", justifyText) - self.optState.setValue("GuiBuildNovel", "noStyling", noStyling) - self.optState.setValue("GuiBuildNovel", "textFont", textFont) - self.optState.setValue("GuiBuildNovel", "textSize", textSize) - self.optState.setValue("GuiBuildNovel", "lineHeight", lineHeight) - self.optState.setValue("GuiBuildNovel", "addNovel", novelFiles) - self.optState.setValue("GuiBuildNovel", "addNotes", noteFiles) - self.optState.setValue("GuiBuildNovel", "ignoreFlag", ignoreFlag) - self.optState.setValue("GuiBuildNovel", "incSynopsis", incSynopsis) - self.optState.setValue("GuiBuildNovel", "incComments", incComments) - self.optState.setValue("GuiBuildNovel", "incKeywords", incKeywords) - self.optState.setValue("GuiBuildNovel", "incBodyText", incBodyText) - self.optState.setValue("GuiBuildNovel", "replaceTabs", replaceTabs) - self.optState.setValue("GuiBuildNovel", "replaceUCode", replaceUCode) - - self.optState.saveSettings() + pOptions = self.theProject.options + pOptions.setValue("GuiBuildNovel", "hideScene", hideScene) + pOptions.setValue("GuiBuildNovel", "hideSection", hideSection) + pOptions.setValue("GuiBuildNovel", "winWidth", winWidth) + pOptions.setValue("GuiBuildNovel", "winHeight", winHeight) + pOptions.setValue("GuiBuildNovel", "boxWidth", boxWidth) + pOptions.setValue("GuiBuildNovel", "docWidth", docWidth) + pOptions.setValue("GuiBuildNovel", "justifyText", justifyText) + pOptions.setValue("GuiBuildNovel", "noStyling", noStyling) + pOptions.setValue("GuiBuildNovel", "textFont", textFont) + pOptions.setValue("GuiBuildNovel", "textSize", textSize) + pOptions.setValue("GuiBuildNovel", "lineHeight", lineHeight) + pOptions.setValue("GuiBuildNovel", "addNovel", novelFiles) + pOptions.setValue("GuiBuildNovel", "addNotes", noteFiles) + pOptions.setValue("GuiBuildNovel", "ignoreFlag", ignoreFlag) + pOptions.setValue("GuiBuildNovel", "incSynopsis", incSynopsis) + pOptions.setValue("GuiBuildNovel", "incComments", incComments) + pOptions.setValue("GuiBuildNovel", "incKeywords", incKeywords) + pOptions.setValue("GuiBuildNovel", "incBodyText", incBodyText) + pOptions.setValue("GuiBuildNovel", "replaceTabs", replaceTabs) + pOptions.setValue("GuiBuildNovel", "replaceUCode", replaceUCode) + pOptions.saveSettings() return diff --git a/novelwriter/tools/writingstats.py b/novelwriter/tools/writingstats.py index 4ce83b66..aff7bc3d 100644 --- a/novelwriter/tools/writingstats.py +++ b/novelwriter/tools/writingstats.py @@ -67,33 +67,34 @@ class GuiWritingStats(QDialog): self.theParent = theParent self.theTheme = theParent.theTheme self.theProject = theParent.theProject - self.optState = theParent.theProject.optState self.logData = [] self.filterData = [] self.timeFilter = 0.0 self.wordOffset = 0 + pOptions = self.theProject.options + self.setWindowTitle(self.tr("Writing Statistics")) self.setMinimumWidth(self.mainConf.pxInt(420)) self.setMinimumHeight(self.mainConf.pxInt(400)) self.resize( - self.mainConf.pxInt(self.optState.getInt("GuiWritingStats", "winWidth", 550)), - self.mainConf.pxInt(self.optState.getInt("GuiWritingStats", "winHeight", 500)) + self.mainConf.pxInt(pOptions.getInt("GuiWritingStats", "winWidth", 550)), + self.mainConf.pxInt(pOptions.getInt("GuiWritingStats", "winHeight", 500)) ) # List Box wCol0 = self.mainConf.pxInt( - self.optState.getInt("GuiWritingStats", "widthCol0", 180) + pOptions.getInt("GuiWritingStats", "widthCol0", 180) ) wCol1 = self.mainConf.pxInt( - self.optState.getInt("GuiWritingStats", "widthCol1", 80) + pOptions.getInt("GuiWritingStats", "widthCol1", 80) ) wCol2 = self.mainConf.pxInt( - self.optState.getInt("GuiWritingStats", "widthCol2", 80) + pOptions.getInt("GuiWritingStats", "widthCol2", 80) ) wCol3 = self.mainConf.pxInt( - self.optState.getInt("GuiWritingStats", "widthCol3", 80) + pOptions.getInt("GuiWritingStats", "widthCol3", 80) ) self.listBox = QTreeWidget() @@ -115,9 +116,9 @@ class GuiWritingStats(QDialog): hHeader.setTextAlignment(self.C_IDLE, Qt.AlignRight) hHeader.setTextAlignment(self.C_COUNT, Qt.AlignRight) - sortCol = checkIntRange(self.optState.getInt("GuiWritingStats", "sortCol", 0), 0, 2, 0) + sortCol = checkIntRange(pOptions.getInt("GuiWritingStats", "sortCol", 0), 0, 2, 0) sortOrder = checkIntTuple( - self.optState.getInt("GuiWritingStats", "sortOrder", Qt.DescendingOrder), + pOptions.getInt("GuiWritingStats", "sortOrder", Qt.DescendingOrder), (Qt.AscendingOrder, Qt.DescendingOrder), Qt.DescendingOrder ) self.listBox.sortByColumn(sortCol, sortOrder) @@ -190,37 +191,37 @@ class GuiWritingStats(QDialog): self.incNovel = QSwitch(width=2*sPx, height=sPx) self.incNovel.setChecked( - self.optState.getBool("GuiWritingStats", "incNovel", True) + pOptions.getBool("GuiWritingStats", "incNovel", True) ) self.incNovel.clicked.connect(self._updateListBox) self.incNotes = QSwitch(width=2*sPx, height=sPx) self.incNotes.setChecked( - self.optState.getBool("GuiWritingStats", "incNotes", True) + pOptions.getBool("GuiWritingStats", "incNotes", True) ) self.incNotes.clicked.connect(self._updateListBox) self.hideZeros = QSwitch(width=2*sPx, height=sPx) self.hideZeros.setChecked( - self.optState.getBool("GuiWritingStats", "hideZeros", True) + pOptions.getBool("GuiWritingStats", "hideZeros", True) ) self.hideZeros.clicked.connect(self._updateListBox) self.hideNegative = QSwitch(width=2*sPx, height=sPx) self.hideNegative.setChecked( - self.optState.getBool("GuiWritingStats", "hideNegative", False) + pOptions.getBool("GuiWritingStats", "hideNegative", False) ) self.hideNegative.clicked.connect(self._updateListBox) self.groupByDay = QSwitch(width=2*sPx, height=sPx) self.groupByDay.setChecked( - self.optState.getBool("GuiWritingStats", "groupByDay", False) + pOptions.getBool("GuiWritingStats", "groupByDay", False) ) self.groupByDay.clicked.connect(self._updateListBox) self.showIdleTime = QSwitch(width=2*sPx, height=sPx) self.showIdleTime.setChecked( - self.optState.getBool("GuiWritingStats", "showIdleTime", False) + pOptions.getBool("GuiWritingStats", "showIdleTime", False) ) self.showIdleTime.clicked.connect(self._updateListBox) @@ -244,7 +245,7 @@ class GuiWritingStats(QDialog): self.histMax.setMaximum(100000) self.histMax.setSingleStep(100) self.histMax.setValue( - self.optState.getInt("GuiWritingStats", "histMax", 2000) + pOptions.getInt("GuiWritingStats", "histMax", 2000) ) self.histMax.valueChanged.connect(self._updateListBox) @@ -323,23 +324,23 @@ class GuiWritingStats(QDialog): showIdleTime = self.showIdleTime.isChecked() histMax = self.histMax.value() - self.optState.setValue("GuiWritingStats", "winWidth", winWidth) - self.optState.setValue("GuiWritingStats", "winHeight", winHeight) - self.optState.setValue("GuiWritingStats", "widthCol0", widthCol0) - self.optState.setValue("GuiWritingStats", "widthCol1", widthCol1) - self.optState.setValue("GuiWritingStats", "widthCol2", widthCol2) - self.optState.setValue("GuiWritingStats", "widthCol3", widthCol3) - self.optState.setValue("GuiWritingStats", "sortCol", sortCol) - self.optState.setValue("GuiWritingStats", "sortOrder", sortOrder) - self.optState.setValue("GuiWritingStats", "incNovel", incNovel) - self.optState.setValue("GuiWritingStats", "incNotes", incNotes) - self.optState.setValue("GuiWritingStats", "hideZeros", hideZeros) - self.optState.setValue("GuiWritingStats", "hideNegative", hideNegative) - self.optState.setValue("GuiWritingStats", "groupByDay", groupByDay) - self.optState.setValue("GuiWritingStats", "showIdleTime", showIdleTime) - self.optState.setValue("GuiWritingStats", "histMax", histMax) - - self.optState.saveSettings() + pOptions = self.theProject.options + pOptions.setValue("GuiWritingStats", "winWidth", winWidth) + pOptions.setValue("GuiWritingStats", "winHeight", winHeight) + pOptions.setValue("GuiWritingStats", "widthCol0", widthCol0) + pOptions.setValue("GuiWritingStats", "widthCol1", widthCol1) + pOptions.setValue("GuiWritingStats", "widthCol2", widthCol2) + pOptions.setValue("GuiWritingStats", "widthCol3", widthCol3) + pOptions.setValue("GuiWritingStats", "sortCol", sortCol) + pOptions.setValue("GuiWritingStats", "sortOrder", sortOrder) + pOptions.setValue("GuiWritingStats", "incNovel", incNovel) + pOptions.setValue("GuiWritingStats", "incNotes", incNotes) + pOptions.setValue("GuiWritingStats", "hideZeros", hideZeros) + pOptions.setValue("GuiWritingStats", "hideNegative", hideNegative) + pOptions.setValue("GuiWritingStats", "groupByDay", groupByDay) + pOptions.setValue("GuiWritingStats", "showIdleTime", showIdleTime) + pOptions.setValue("GuiWritingStats", "histMax", histMax) + pOptions.saveSettings() self.close() return diff --git a/tests/test_core/test_core_document.py b/tests/test_core/test_core_document.py index 881290d6..2f80e45a 100644 --- a/tests/test_core/test_core_document.py +++ b/tests/test_core/test_core_document.py @@ -64,7 +64,7 @@ def testCoreDocument_LoadSave(monkeypatch, mockGUI, nwMinimal): assert theDoc.readDocument() == "### New Scene\n\n" # Try to open a new (non-existent) file - nHandle = theProject.projTree.findRoot(nwItemClass.NOVEL) + nHandle = theProject.tree.findRoot(nwItemClass.NOVEL) assert nHandle is not None xHandle = theProject.newFile("New File", nHandle) theDoc = NWDoc(theProject, xHandle) diff --git a/tests/test_core/test_core_index.py b/tests/test_core/test_core_index.py index 93ec35c6..0d070eba 100644 --- a/tests/test_core/test_core_index.py +++ b/tests/test_core/test_core_index.py @@ -54,7 +54,7 @@ def testCoreIndex_LoadSave(monkeypatch, nwLipsum, mockGUI, outDir, refDir): "6c6afb1247750": False, # Plot ROOT "60bdf227455cc": False, # World ROOT } - for tItem in theProject.projTree: + for tItem in theProject.tree: assert theIndex.reIndexHandle(tItem.itemHandle) is notIndexable.get(tItem.itemHandle, True) assert theIndex.reIndexHandle(None) is False @@ -180,8 +180,8 @@ def testCoreIndex_CheckThese(nwMinimal, mockGUI): theIndex = NWIndex(theProject) nHandle = theProject.newFile("Hello", "a508bb932959c") cHandle = theProject.newFile("Jane", "afb3043c7b2b3") - nItem = theProject.projTree[nHandle] - cItem = theProject.projTree[cHandle] + nItem = theProject.tree[nHandle] + cItem = theProject.tree[cHandle] assert theIndex.novelChangedSince(0) is False assert theIndex.notesChangedSince(0) is False @@ -258,7 +258,7 @@ def testCoreIndex_ScanText(nwMinimal, mockGUI): # Some items for fail to scan tests dHandle = theProject.newFolder("Folder", "a508bb932959c") xHandle = theProject.newFile("No Layout", "a508bb932959c") - xItem = theProject.projTree[xHandle] + xItem = theProject.tree[xHandle] xItem.setLayout(nwItemLayout.NO_LAYOUT) # Check invalid data @@ -272,18 +272,18 @@ def testCoreIndex_ScanText(nwMinimal, mockGUI): # Create the trash folder tHandle = theProject.trashFolder() - assert theProject.projTree[tHandle] is not None + assert theProject.tree[tHandle] is not None xItem.setParent(tHandle) - theProject.projTree.updateItemData(xItem.itemHandle) + theProject.tree.updateItemData(xItem.itemHandle) assert xItem.itemRoot == tHandle assert xItem.itemClass == nwItemClass.TRASH assert theIndex.scanText(xHandle, "Hello World!") is False # Create the archive root aHandle = theProject.newRoot(nwItemClass.ARCHIVE) - assert theProject.projTree[aHandle] is not None + assert theProject.tree[aHandle] is not None xItem.setParent(aHandle) - theProject.projTree.updateItemData(xItem.itemHandle) + theProject.tree.updateItemData(xItem.itemHandle) assert theIndex.scanText(xHandle, "Hello World!") is False # Make some usable items @@ -433,7 +433,7 @@ def testCoreIndex_ScanText(nwMinimal, mockGUI): # Page wo/Title # ============= - theProject.projTree[pHandle]._layout = nwItemLayout.DOCUMENT + theProject.tree[pHandle]._layout = nwItemLayout.DOCUMENT assert theIndex.scanText(pHandle, ( "This is a page with some text on it.\n\n" )) @@ -446,7 +446,7 @@ def testCoreIndex_ScanText(nwMinimal, mockGUI): assert theIndex._fileIndex[pHandle]["T000000"]["pCount"] == 1 assert theIndex._fileIndex[pHandle]["T000000"]["synopsis"] == "" - theProject.projTree[pHandle]._layout = nwItemLayout.NOTE + theProject.tree[pHandle]._layout = nwItemLayout.NOTE assert theIndex.scanText(pHandle, ( "This is a page with some text on it.\n\n" )) @@ -499,7 +499,7 @@ def testCoreIndex_ExtractData(nwMinimal, mockGUI): assert theKeys == ["%s:T000001" % nHandle] # Check that excluded files can be skipped - theProject.projTree[nHandle].setExported(False) + theProject.tree[nHandle].setExported(False) theKeys = [] for aKey, _, _, _ in theIndex.novelStructure(skipExcluded=False): @@ -631,9 +631,9 @@ def testCoreIndex_ExtractData(nwMinimal, mockGUI): sHandle = theProject.newFile("Scene One", "a508bb932959c") tHandle = theProject.newFile("Scene Two", "a508bb932959c") - theProject.projTree[hHandle].itemLayout == nwItemLayout.DOCUMENT - theProject.projTree[sHandle].itemLayout == nwItemLayout.DOCUMENT - theProject.projTree[tHandle].itemLayout == nwItemLayout.DOCUMENT + theProject.tree[hHandle].itemLayout == nwItemLayout.DOCUMENT + theProject.tree[sHandle].itemLayout == nwItemLayout.DOCUMENT + theProject.tree[tHandle].itemLayout == nwItemLayout.DOCUMENT assert theIndex.scanText(hHandle, "## Chapter One\n\n") assert theIndex.scanText(sHandle, "### Scene One\n\n") @@ -643,9 +643,9 @@ def testCoreIndex_ExtractData(nwMinimal, mockGUI): assert theIndex._listNovelHandles(True) == [hHandle, sHandle, tHandle] # Add a fake handle to the tree and check that it's ignored - theProject.projTree._treeOrder.append("0000000000000") + theProject.tree._treeOrder.append("0000000000000") assert theIndex._listNovelHandles(False) == [nHandle, hHandle, sHandle, tHandle] - theProject.projTree._treeOrder.remove("0000000000000") + theProject.tree._treeOrder.remove("0000000000000") # Extract stats assert theIndex.getNovelWordCount(False) == 34 diff --git a/tests/test_core/test_core_project.py b/tests/test_core/test_core_project.py index e6e5092d..005277c6 100644 --- a/tests/test_core/test_core_project.py +++ b/tests/test_core/test_core_project.py @@ -634,17 +634,17 @@ def testCoreProject_AccessItems(nwMinimal, mockGUI): "afb3043c7b2b3", # ROOT: Characters "9d5247ab588e0", # ROOT: World ] - assert theProject.projTree.handles() == oldOrder + assert theProject.tree.handles() == oldOrder assert theProject.setTreeOrder(newOrder) - assert theProject.projTree.handles() == newOrder + assert theProject.tree.handles() == newOrder # Add a non-existing item - theProject.projTree._treeOrder.append("01234567789abc") + theProject.tree._treeOrder.append("01234567789abc") # Add an item with a non-existent parent nHandle = theProject.newFile("Test File", "a6d311a93600a") - theProject.projTree[nHandle].setParent("cba9876543210") - assert theProject.projTree[nHandle].itemParent == "cba9876543210" + theProject.tree[nHandle].setParent("cba9876543210") + assert theProject.tree[nHandle].itemParent == "cba9876543210" retOrder = [] for tItem in theProject.getProjectItems(): @@ -661,7 +661,7 @@ def testCoreProject_AccessItems(nwMinimal, mockGUI): "f5ab3e30151e1", # FILE: New Chapter "8c659a11cd429", # FILE: New Scene ] - assert theProject.projTree[nHandle].itemParent is None + assert theProject.tree[nHandle].itemParent is None # END Test testCoreProject_AccessItems @@ -679,15 +679,15 @@ def testCoreProject_StatusImport(mockGUI, fncDir, mockRnd): # Change Status # ============= - theProject.projTree["0000000000014"].setStatus("Finished") - theProject.projTree["0000000000015"].setStatus("Draft") - theProject.projTree["0000000000016"].setStatus("Note") - theProject.projTree["0000000000017"].setStatus("Finished") + theProject.tree["0000000000014"].setStatus("Finished") + theProject.tree["0000000000015"].setStatus("Draft") + theProject.tree["0000000000016"].setStatus("Note") + theProject.tree["0000000000017"].setStatus("Finished") - assert theProject.projTree["0000000000014"].itemStatus == statusKeys[3] - assert theProject.projTree["0000000000015"].itemStatus == statusKeys[2] - assert theProject.projTree["0000000000016"].itemStatus == statusKeys[1] - assert theProject.projTree["0000000000017"].itemStatus == statusKeys[3] + assert theProject.tree["0000000000014"].itemStatus == statusKeys[3] + assert theProject.tree["0000000000015"].itemStatus == statusKeys[2] + assert theProject.tree["0000000000016"].itemStatus == statusKeys[1] + assert theProject.tree["0000000000017"].itemStatus == statusKeys[3] newList = [ {"key": statusKeys[0], "name": "New", "cols": (1, 1, 1)}, @@ -723,9 +723,9 @@ def testCoreProject_StatusImport(mockGUI, fncDir, mockRnd): # ================= fHandle = theProject.newFile("Jane Doe", "8b9d2e465e150") - theProject.projTree[fHandle].setImport("Main") + theProject.tree[fHandle].setImport("Main") - assert theProject.projTree[fHandle].itemImport == importKeys[3] + assert theProject.tree[fHandle].itemImport == importKeys[3] newList = [ {"key": importKeys[0], "name": "New", "cols": (1, 1, 1)}, {"key": importKeys[1], "name": "Minor", "cols": (2, 2, 2)}, @@ -851,7 +851,7 @@ def testCoreProject_Methods(monkeypatch, mockGUI, tmpDir, fncDir, mockRnd): # Trash folder # Should create on first call, and just returned on later calls hTrash = "0000000000018" - assert theProject.projTree[hTrash] is None + assert theProject.tree[hTrash] is None assert theProject.trashFolder() == hTrash assert theProject.trashFolder() == hTrash @@ -929,11 +929,11 @@ def testCoreProject_Methods(monkeypatch, mockGUI, tmpDir, fncDir, mockRnd): "0000000000010", "0000000000011", "0000000000012", "0000000000016", "0000000000017", ] - assert theProject.projTree.handles() == oldOrder + assert theProject.tree.handles() == oldOrder assert theProject.setTreeOrder(newOrder) - assert theProject.projTree.handles() == newOrder + assert theProject.tree.handles() == newOrder assert theProject.setTreeOrder(oldOrder) - assert theProject.projTree.handles() == oldOrder + assert theProject.tree.handles() == oldOrder # Session stats theProject.currWCount = 200 @@ -1003,7 +1003,7 @@ def testCoreProject_OrphanedFiles(mockGUI, nwLipsum): theProject = NWProject(mockGUI) assert theProject.openProject(nwLipsum) is True - assert theProject.projTree["636b6aa9b697b"] is None + assert theProject.tree["636b6aa9b697b"] is None # Add a file with non-existent parent # This file will be renoved from the project on open @@ -1041,11 +1041,11 @@ def testCoreProject_OrphanedFiles(mockGUI, nwLipsum): assert theProject.openProject(nwLipsum) assert theProject.projPath is not None - assert theProject.projTree["636b6aa9b697bb"] is None - assert theProject.projTree["abcdefghijklm"] is None + assert theProject.tree["636b6aa9b697bb"] is None + assert theProject.tree["abcdefghijklm"] is None # First Item with Meta Data - oItem = theProject.projTree["636b6aa9b697b"] + oItem = theProject.tree["636b6aa9b697b"] assert oItem is not None assert oItem.itemName == "[Recovered] Mars" assert oItem.itemHandle == "636b6aa9b697b" @@ -1055,7 +1055,7 @@ def testCoreProject_OrphanedFiles(mockGUI, nwLipsum): assert oItem.itemLayout == nwItemLayout.NOTE # Second Item without Meta Data - oItem = theProject.projTree["736b6aa9b697b"] + oItem = theProject.tree["736b6aa9b697b"] assert oItem is not None assert oItem.itemName == "Recovered File 1" assert oItem.itemHandle == "736b6aa9b697b" diff --git a/tests/test_dialogs/test_dlg_itemeditor.py b/tests/test_dialogs/test_dlg_itemeditor.py index c221138e..95b1ee71 100644 --- a/tests/test_dialogs/test_dlg_itemeditor.py +++ b/tests/test_dialogs/test_dlg_itemeditor.py @@ -65,9 +65,9 @@ def testDlgItemEditor_Dialog(qtbot, monkeypatch, nwGUI, fncProj, mockRnd): assert nwGUI.editItem() is False # Invalid Type - nwGUI.theProject.projTree[tHandle]._type = nwItemType.NO_TYPE + nwGUI.theProject.tree[tHandle]._type = nwItemType.NO_TYPE assert nwGUI.editItem() is False - nwGUI.theProject.projTree[tHandle]._type = nwItemType.FILE + nwGUI.theProject.tree[tHandle]._type = nwItemType.FILE # Open Properly assert nwGUI.editItem() is True diff --git a/tests/test_gui/test_gui_doceditor.py b/tests/test_gui/test_gui_doceditor.py index 7f3aa30c..1727b69f 100644 --- a/tests/test_gui/test_gui_doceditor.py +++ b/tests/test_gui/test_gui_doceditor.py @@ -185,10 +185,10 @@ def testGuiEditor_SaveText(qtbot, monkeypatch, caplog, nwGUI, nwMinimal, ipsumTe assert "Could not save document." in caplog.text # Change header level - assert nwGUI.theProject.projTree[sHandle].itemLayout == nwItemLayout.DOCUMENT + assert nwGUI.theProject.tree[sHandle].itemLayout == nwItemLayout.DOCUMENT nwGUI.docEditor.replaceText(longText[1:]) assert nwGUI.docEditor.saveText() is True - assert nwGUI.theProject.projTree[sHandle].itemLayout == nwItemLayout.DOCUMENT + assert nwGUI.theProject.tree[sHandle].itemLayout == nwItemLayout.DOCUMENT # Regular save assert nwGUI.docEditor.saveText() is True @@ -236,9 +236,9 @@ def testGuiEditor_MetaData(qtbot, monkeypatch, nwGUI, nwMinimal): assert nwGUI.docEditor.setCursorPosition(None) is False assert nwGUI.docEditor.setCursorPosition(10) is True assert nwGUI.docEditor.getCursorPosition() == 10 - assert nwGUI.theProject.projTree[sHandle].cursorPos != 10 + assert nwGUI.theProject.tree[sHandle].cursorPos != 10 nwGUI.docEditor.saveCursorPosition() - assert nwGUI.theProject.projTree[sHandle].cursorPos == 10 + assert nwGUI.theProject.tree[sHandle].cursorPos == 10 assert nwGUI.docEditor.setCursorLine(None) is False assert nwGUI.docEditor.setCursorLine(2) is True @@ -1226,8 +1226,8 @@ def testGuiEditor_WordCounters(qtbot, monkeypatch, caplog, nwGUI, nwMinimal, ips # Open a document and populate it sHandle = "8c659a11cd429" - nwGUI.theProject.projTree[sHandle]._initCount = 0 # Clear item's count - nwGUI.theProject.projTree[sHandle]._wordCount = 0 # Clear item's count + nwGUI.theProject.tree[sHandle]._initCount = 0 # Clear item's count + nwGUI.theProject.tree[sHandle]._wordCount = 0 # Clear item's count assert nwGUI.openDocument(sHandle) is True qtbot.wait(stepDelay) @@ -1253,9 +1253,9 @@ def testGuiEditor_WordCounters(qtbot, monkeypatch, caplog, nwGUI, nwMinimal, ips nwGUI.docEditor.wCounterDoc.run() # nwGUI.docEditor._updateDocCounts(cC, wC, pC) qtbot.wait(stepDelay) - assert nwGUI.theProject.projTree[sHandle]._charCount == cC - assert nwGUI.theProject.projTree[sHandle]._wordCount == wC - assert nwGUI.theProject.projTree[sHandle]._paraCount == pC + assert nwGUI.theProject.tree[sHandle]._charCount == cC + assert nwGUI.theProject.tree[sHandle]._wordCount == wC + assert nwGUI.theProject.tree[sHandle]._paraCount == pC assert nwGUI.docEditor.docFooter.wordsText.text() == f"Words: {wC} (+{wC})" # Select all text diff --git a/tests/test_gui/test_gui_docviewer.py b/tests/test_gui/test_gui_docviewer.py index 48f61eff..d3f245d1 100644 --- a/tests/test_gui/test_gui_docviewer.py +++ b/tests/test_gui/test_gui_docviewer.py @@ -140,7 +140,7 @@ def testGuiViewer_Main(qtbot, monkeypatch, nwGUI, nwLipsum): nwGUI.docViewer.reloadText() # Change document title - nwItem = nwGUI.theProject.projTree["4c4f28287af27"] + nwItem = nwGUI.theProject.tree["4c4f28287af27"] nwItem.setName("Test Title") assert nwItem.itemName == "Test Title" nwGUI.docViewer.updateDocInfo("4c4f28287af27") diff --git a/tests/test_gui/test_gui_guimain.py b/tests/test_gui/test_gui_guimain.py index e0d7e2ec..5e00815d 100644 --- a/tests/test_gui/test_gui_guimain.py +++ b/tests/test_gui/test_gui_guimain.py @@ -181,10 +181,10 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock assert nwGUI.saveProject() assert nwGUI.closeProject() - assert len(nwGUI.theProject.projTree) == 0 - assert len(nwGUI.theProject.projTree._treeOrder) == 0 - assert len(nwGUI.theProject.projTree._treeRoots) == 0 - assert nwGUI.theProject.projTree.trashRoot() is None + assert len(nwGUI.theProject.tree) == 0 + assert len(nwGUI.theProject.tree._treeOrder) == 0 + assert len(nwGUI.theProject.tree._treeRoots) == 0 + assert nwGUI.theProject.tree.trashRoot() is None assert nwGUI.theProject.projPath is None assert nwGUI.theProject.projMeta is None assert nwGUI.theProject.projFile == "nwProject.nwx" @@ -208,10 +208,10 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock qtbot.wait(stepDelay) # Check that we loaded the data - assert len(nwGUI.theProject.projTree) == 8 - assert len(nwGUI.theProject.projTree._treeOrder) == 8 - assert len(nwGUI.theProject.projTree._treeRoots) == 4 - assert nwGUI.theProject.projTree.trashRoot() is None + assert len(nwGUI.theProject.tree) == 8 + assert len(nwGUI.theProject.tree._treeOrder) == 8 + assert len(nwGUI.theProject.tree._treeRoots) == 4 + assert nwGUI.theProject.tree.trashRoot() is None assert nwGUI.theProject.projPath == fncProj assert nwGUI.theProject.projMeta == os.path.join(fncProj, "meta") assert nwGUI.theProject.projFile == "nwProject.nwx" @@ -464,11 +464,11 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir, mock # Check a Quick Create and Delete assert nwGUI.treeView.newTreeItem(nwItemType.FILE, None) newHandle = nwGUI.treeView.getSelectedHandle() - assert nwGUI.theProject.projTree["0000000000020"] is not None + assert nwGUI.theProject.tree["0000000000020"] is not None assert nwGUI.treeView.deleteItem() assert nwGUI.treeView.setSelectedHandle(newHandle) assert nwGUI.treeView.deleteItem() - assert nwGUI.theProject.projTree["0000000000024"] is not None # Trash + assert nwGUI.theProject.tree["0000000000024"] is not None # Trash assert nwGUI.saveProject() # Check the files diff --git a/tests/test_gui/test_gui_projtree.py b/tests/test_gui/test_gui_projtree.py index 5d3354f9..39e0b4dc 100644 --- a/tests/test_gui/test_gui_projtree.py +++ b/tests/test_gui/test_gui_projtree.py @@ -63,7 +63,7 @@ def testGuiProjTree_NewItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd) # Create root item assert nwTree.newTreeItem(nwItemType.ROOT, nwItemClass.WORLD) is True - assert "0000000000010" in nwGUI.theProject.projTree + assert "0000000000010" in nwGUI.theProject.tree # File/Folder Items # ================= @@ -78,42 +78,42 @@ def testGuiProjTree_NewItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockRnd) # Create new folder as child of Novel folder nwTree.setSelectedHandle("0000000000008") assert nwTree.newTreeItem(nwItemType.FOLDER) is True - assert nwGUI.theProject.projTree["0000000000011"].itemParent == "0000000000008" - assert nwGUI.theProject.projTree["0000000000011"].itemRoot == "0000000000008" - assert nwGUI.theProject.projTree["0000000000011"].itemClass == nwItemClass.NOVEL + assert nwGUI.theProject.tree["0000000000011"].itemParent == "0000000000008" + assert nwGUI.theProject.tree["0000000000011"].itemRoot == "0000000000008" + assert nwGUI.theProject.tree["0000000000011"].itemClass == nwItemClass.NOVEL # Add a new file in the new folder nwTree.setSelectedHandle("0000000000011") assert nwTree.newTreeItem(nwItemType.FILE) is True - assert nwGUI.theProject.projTree["0000000000012"].itemParent == "0000000000011" - assert nwGUI.theProject.projTree["0000000000012"].itemRoot == "0000000000008" - assert nwGUI.theProject.projTree["0000000000012"].itemClass == nwItemClass.NOVEL + assert nwGUI.theProject.tree["0000000000012"].itemParent == "0000000000011" + assert nwGUI.theProject.tree["0000000000012"].itemRoot == "0000000000008" + assert nwGUI.theProject.tree["0000000000012"].itemClass == nwItemClass.NOVEL # Add a new file next to the other new file nwTree.setSelectedHandle("0000000000012") assert nwTree.newTreeItem(nwItemType.FILE) is True - assert nwGUI.theProject.projTree["0000000000013"].itemParent == "0000000000011" - assert nwGUI.theProject.projTree["0000000000013"].itemRoot == "0000000000008" - assert nwGUI.theProject.projTree["0000000000013"].itemClass == nwItemClass.NOVEL + assert nwGUI.theProject.tree["0000000000013"].itemParent == "0000000000011" + assert nwGUI.theProject.tree["0000000000013"].itemRoot == "0000000000008" + assert nwGUI.theProject.tree["0000000000013"].itemClass == nwItemClass.NOVEL assert nwGUI.openDocument("0000000000013") assert nwGUI.docEditor.getText() == "### New Document\n\n" # Add a new file to the characters folder nwTree.setSelectedHandle("000000000000a") assert nwTree.newTreeItem(nwItemType.FILE) is True - assert nwGUI.theProject.projTree["0000000000014"].itemParent == "000000000000a" - assert nwGUI.theProject.projTree["0000000000014"].itemRoot == "000000000000a" - assert nwGUI.theProject.projTree["0000000000014"].itemClass == nwItemClass.CHARACTER + assert nwGUI.theProject.tree["0000000000014"].itemParent == "000000000000a" + assert nwGUI.theProject.tree["0000000000014"].itemRoot == "000000000000a" + assert nwGUI.theProject.tree["0000000000014"].itemClass == nwItemClass.CHARACTER assert nwGUI.openDocument("0000000000014") assert nwGUI.docEditor.getText() == "# New Note\n\n" # Make sure the sibling folder bug trap works nwTree.setSelectedHandle("0000000000013") - nwGUI.theProject.projTree["0000000000013"].setParent(None) # This should not happen + nwGUI.theProject.tree["0000000000013"].setParent(None) # This should not happen caplog.clear() assert nwTree.newTreeItem(nwItemType.FILE) is False assert "Internal error" in caplog.text - nwGUI.theProject.projTree["0000000000013"].setParent("0000000000011") + nwGUI.theProject.tree["0000000000013"].setParent("0000000000011") # Get the trash folder nwTree._addTrashRoot() @@ -242,22 +242,22 @@ def testGuiProjTree_MoveItems(qtbot, monkeypatch, nwGUI, fncDir, mockRnd): # =========== nwTree.setSelectedHandle("0000000000008") - assert nwGUI.theProject.projTree._treeOrder.index("0000000000008") == 0 + assert nwGUI.theProject.tree._treeOrder.index("0000000000008") == 0 # Move novel folder up assert nwTree.moveTreeItem(-1) is False nwTree.flushTreeOrder() - assert nwGUI.theProject.projTree._treeOrder.index("0000000000008") == 0 + assert nwGUI.theProject.tree._treeOrder.index("0000000000008") == 0 # Move novel folder down assert nwTree.moveTreeItem(1) is True nwTree.flushTreeOrder() - assert nwGUI.theProject.projTree._treeOrder.index("0000000000008") == 1 + assert nwGUI.theProject.tree._treeOrder.index("0000000000008") == 1 # Move novel folder up again assert nwTree.moveTreeItem(-1) is True nwTree.flushTreeOrder() - assert nwGUI.theProject.projTree._treeOrder.index("0000000000008") == 0 + assert nwGUI.theProject.tree._treeOrder.index("0000000000008") == 0 # Clean up # qtbot.stopForInteraction() @@ -341,7 +341,7 @@ def testGuiProjTree_DeleteItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockR "000000000000d", "000000000000e", "000000000000f", "0000000000010" ] - trashHandle = nwGUI.theProject.projTree.trashRoot() + trashHandle = nwGUI.theProject.tree.trashRoot() assert nwTree.getTreeFromHandle(trashHandle) == [ trashHandle, "0000000000012", "0000000000011" ] @@ -349,30 +349,30 @@ def testGuiProjTree_DeleteItems(qtbot, caplog, monkeypatch, nwGUI, fncDir, mockR # Delete the first file again (permanent), and ask for permission # Also open the document in the editor, which should trigger a close assert os.path.isfile(os.path.join(prjDir, "content", "0000000000012.nwd")) - assert "0000000000012" in nwGUI.theProject.projTree + assert "0000000000012" in nwGUI.theProject.tree assert nwGUI.docEditor.docHandle() is None assert nwGUI.openDocument("0000000000012") is True assert nwGUI.docEditor.docHandle() == "0000000000012" assert nwTree.deleteItem("0000000000012") is True assert nwGUI.docEditor.docHandle() is None assert not os.path.isfile(os.path.join(prjDir, "content", "0000000000012.nwd")) - assert "0000000000012" not in nwGUI.theProject.projTree + assert "0000000000012" not in nwGUI.theProject.tree assert nwTree.getTreeFromHandle(trashHandle) == [ trashHandle, "0000000000011" ] # Delete the second file, and skip asking for permission assert os.path.isfile(os.path.join(prjDir, "content", "0000000000011.nwd")) - assert "0000000000011" in nwGUI.theProject.projTree + assert "0000000000011" in nwGUI.theProject.tree assert nwTree.deleteItem("0000000000011", alreadyAsked=True) is True assert not os.path.isfile(os.path.join(prjDir, "content", "0000000000011.nwd")) - assert "0000000000011" not in nwGUI.theProject.projTree + assert "0000000000011" not in nwGUI.theProject.tree assert nwTree.getTreeFromHandle(trashHandle) == [trashHandle] # Delete Folder # ============= - trashHandle = nwGUI.theProject.projTree.trashRoot() + trashHandle = nwGUI.theProject.tree.trashRoot() # Add a folder with two files nwTree.setSelectedHandle("0000000000009")