Merge branch 'release' into dev

This commit is contained in:
Veronica K. B. Olsen
2021-02-01 23:02:40 +01:00
7 changed files with 179 additions and 35 deletions
+30
View File
@@ -613,6 +613,36 @@ class NWIndex():
return hCount return hCount
def getHandleWordCounts(self, tHandle):
"""Get all header word counts for a specific handle.
"""
theCounts = []
hRecord = self._novelIndex.get(tHandle, None)
if hRecord is None:
hRecord = self._noteIndex.get(tHandle, None)
if hRecord is None:
return theCounts
for sTitle, sData in hRecord.items():
theCounts.append(("%s:%s" % (tHandle, sTitle), sData["wCount"]))
return theCounts
def getHandleHeaders(self, tHandle):
"""Get all headers for a specific handle.
"""
theHeaders = []
hRecord = self._novelIndex.get(tHandle, None)
if hRecord is None:
hRecord = self._noteIndex.get(tHandle, None)
if hRecord is None:
return theHeaders
for sTitle, sData in hRecord.items():
theHeaders.append((sTitle, sData["level"], sData["title"]))
return theHeaders
def getTableOfContents(self, maxDepth, skipExcluded=True): def getTableOfContents(self, maxDepth, skipExcluded=True):
"""Generate a table of contents up to a maxiumum depth. """Generate a table of contents up to a maxiumum depth.
""" """
+33 -1
View File
@@ -75,12 +75,14 @@ class GuiDocEditor(QTextEdit):
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.theParent = theParent self.theParent = theParent
self.theTheme = theParent.theTheme self.theTheme = theParent.theTheme
self.theIndex = theParent.theIndex
self.theProject = theParent.theProject self.theProject = theParent.theProject
self.nwDocument = NWDoc(self.theProject, self.theParent) self.nwDocument = NWDoc(self.theProject, self.theParent)
self.docChanged = False # Flag for changed status of document self.docChanged = False # Flag for changed status of document
self.spellCheck = False # Flag for spell checking enabled self.spellCheck = False # Flag for spell checking enabled
self.theHandle = None # The handle of the open file self.theHandle = None # The handle of the open file
self.theHeaders = [] # Record of headers in the file
self.theDict = None # The current spell check dictionary self.theDict = None # The current spell check dictionary
self.nonWord = "\"'" # Characters to not include in spell checking self.nonWord = "\"'" # Characters to not include in spell checking
@@ -342,6 +344,7 @@ class GuiDocEditor(QTextEdit):
self.docFooter.updateLineCount() self.docFooter.updateLineCount()
self.lengthLast = self.qDocument.characterCount() self.lengthLast = self.qDocument.characterCount()
self.theHeaders = self.theIndex.getHandleHeaders(self.theHandle)
qApp.processEvents() qApp.processEvents()
self.setDocumentChanged(False) self.setDocumentChanged(False)
@@ -411,7 +414,7 @@ class GuiDocEditor(QTextEdit):
self.nwDocument.saveDocument(docText) self.nwDocument.saveDocument(docText)
self.setDocumentChanged(False) self.setDocumentChanged(False)
self.theParent.theIndex.scanText(tHandle, docText) self.theIndex.scanText(tHandle, docText)
hLevel, _ = self.theParent.theIndex.getFirstTitle(tHandle) hLevel, _ = self.theParent.theIndex.getFirstTitle(tHandle)
if self.theProject.projTree.updateItemLayout(tHandle, hLevel): if self.theProject.projTree.updateItemLayout(tHandle, hLevel):
@@ -419,6 +422,11 @@ class GuiDocEditor(QTextEdit):
self.nwDocument.saveDocument(docText) self.nwDocument.saveDocument(docText)
self.docFooter.updateInfo() self.docFooter.updateInfo()
if self._updateHeaders(checkLevel=True):
self.theParent.novelView.refreshTree()
else:
self.theParent.novelView.updateWordCounts(tHandle)
return True return True
def updateDocMargins(self): def updateDocMargins(self):
@@ -1230,6 +1238,30 @@ class GuiDocEditor(QTextEdit):
return return
def _updateHeaders(self, checkPos=False, checkLevel=False):
"""Update the headers record and return True if anything
changed, if a check flag was provided.
"""
if self.theHandle is None:
return False
newHeaders = self.theIndex.getHandleHeaders(self.theHandle)
if checkPos:
newPos = [x[0] for x in newHeaders]
oldPos = [x[0] for x in self.theHeaders]
if checkLevel:
newLev = [x[1] for x in newHeaders]
oldLev = [x[1] for x in self.theHeaders]
self.theHeaders = newHeaders
if checkPos:
return newPos != oldPos
if checkLevel:
return newLev != oldLev
return False
def _replaceQuotes(self, sQuote, oQuote, cQuote): def _replaceQuotes(self, sQuote, oQuote, cQuote):
"""Replace all straight quotes in the selected text. """Replace all straight quotes in the selected text.
""" """
+12 -4
View File
@@ -1,9 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""novelWriter GUI Novel Tree """
novelWriter GUI Novel Tree novelWriter GUI Novel Tree
============================== ============================
Class holding the project's novel files tree view GUI classe for the main window novel tree
File History: File History:
Created: 2020-12-20 [1.1a0] Created: 2020-12-20 [1.1a0]
@@ -151,6 +150,15 @@ class GuiNovelTree(QTreeWidget):
return return
def updateWordCounts(self, tHandle):
"""Update the word count for a given handle.
"""
tHeaders = self.theIndex.getHandleWordCounts(tHandle)
for titleKey, wCount in tHeaders:
if titleKey in self._treeMap:
self._treeMap[titleKey].setText(self.C_WORDS, f"{wCount:n}")
return
def getColumnSizes(self): def getColumnSizes(self):
"""Return the column widths for the tree columns. """Return the column widths for the tree columns.
""" """
+19 -1
View File
@@ -1,5 +1,23 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""novelWriter Test Config """
novelWriter Test Suite Configuration
======================================
This file is a part of novelWriter
Copyright 20182021, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
import sys import sys
+19 -1
View File
@@ -1,5 +1,23 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""novelWriter Test Dummy GUI Classes """
novelWriter Test Suite Dummy Classes
======================================
This file is a part of novelWriter
Copyright 20182021, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
# =========================================================================== # # =========================================================================== #
+32 -12
View File
@@ -538,12 +538,12 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI):
"@char: Jane\n\n" "@char: Jane\n\n"
"% this is a comment\n\n" "% this is a comment\n\n"
"This is a story about Jane Smith.\n\n" "This is a story about Jane Smith.\n\n"
"Well, not really.\n" "Well, not really. She's still awesome though.\n"
)) ))
# Whole document # Whole document
cC, wC, pC = theIndex.getCounts(nHandle) cC, wC, pC = theIndex.getCounts(nHandle)
assert cC == 124 assert cC == 152
assert wC == 24 assert wC == 28
assert pC == 4 assert pC == 4
# First part # First part
@@ -554,8 +554,8 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI):
# Second part # Second part
cC, wC, pC = theIndex.getCounts(nHandle, "T000011") cC, wC, pC = theIndex.getCounts(nHandle, "T000011")
assert cC == 62 assert cC == 90
assert wC == 12 assert wC == 16
assert pC == 2 assert pC == 2
# Get section counts for a note file # Get section counts for a note file
@@ -571,12 +571,12 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI):
"@char: Jane\n\n" "@char: Jane\n\n"
"% this is a comment\n\n" "% this is a comment\n\n"
"This is a story about Jane Smith.\n\n" "This is a story about Jane Smith.\n\n"
"Well, not really.\n" "Well, not really. She's still awesome though.\n"
)) ))
# Whole document # Whole document
cC, wC, pC = theIndex.getCounts(cHandle) cC, wC, pC = theIndex.getCounts(cHandle)
assert cC == 124 assert cC == 152
assert wC == 24 assert wC == 28
assert pC == 4 assert pC == 4
# First part # First part
@@ -587,8 +587,8 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI):
# Second part # Second part
cC, wC, pC = theIndex.getCounts(cHandle, "T000011") cC, wC, pC = theIndex.getCounts(cHandle, "T000011")
assert cC == 62 assert cC == 90
assert wC == 12 assert wC == 16
assert pC == 2 assert pC == 2
# getFirstTitle # getFirstTitle
@@ -620,7 +620,7 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI):
theProject.projTree._treeOrder.remove("0000000000000") theProject.projTree._treeOrder.remove("0000000000000")
# Extract stats # Extract stats
assert theIndex.getNovelWordCount(False) == 30 assert theIndex.getNovelWordCount(False) == 34
assert theIndex.getNovelWordCount(True) == 6 assert theIndex.getNovelWordCount(True) == 6
assert theIndex.getNovelTitleCounts(False) == [0, 2, 1, 2, 0] assert theIndex.getNovelTitleCounts(False) == [0, 2, 1, 2, 0]
assert theIndex.getNovelTitleCounts(True) == [0, 0, 1, 2, 0] assert theIndex.getNovelTitleCounts(True) == [0, 0, 1, 2, 0]
@@ -640,11 +640,31 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI):
assert theIndex.getTableOfContents(0, False) == [] assert theIndex.getTableOfContents(0, False) == []
assert theIndex.getTableOfContents(1, False) == [ assert theIndex.getTableOfContents(1, False) == [
("%s:T000001" % nHandle, 1, "Hello World!", 12), ("%s:T000001" % nHandle, 1, "Hello World!", 12),
("%s:T000011" % nHandle, 1, "Hello World!", 18), ("%s:T000011" % nHandle, 1, "Hello World!", 22),
]
# Header Word Counts
bHandle = "0000000000000"
assert theIndex.getHandleWordCounts(bHandle) == []
assert theIndex.getHandleWordCounts(hHandle) == [("%s:T000001" % hHandle, 2)]
assert theIndex.getHandleWordCounts(sHandle) == [("%s:T000001" % sHandle, 2)]
assert theIndex.getHandleWordCounts(tHandle) == [("%s:T000001" % tHandle, 2)]
assert theIndex.getHandleWordCounts(nHandle) == [
("%s:T000001" % nHandle, 12), ("%s:T000011" % nHandle, 16)
] ]
assert theProject.closeProject() assert theProject.closeProject()
# Header Record
bHandle = "0000000000000"
assert theIndex.getHandleHeaders(bHandle) == []
assert theIndex.getHandleHeaders(hHandle) == [("T000001", "H2", "Chapter One")]
assert theIndex.getHandleHeaders(sHandle) == [("T000001", "H3", "Scene One")]
assert theIndex.getHandleHeaders(tHandle) == [("T000001", "H3", "Scene Two")]
assert theIndex.getHandleHeaders(nHandle) == [
("T000001", "H1", "Hello World!"), ("T000011", "H1", "Hello World!")
]
# END Test testCoreIndex_ExtractData # END Test testCoreIndex_ExtractData
@pytest.mark.core @pytest.mark.core
+19 -1
View File
@@ -1,5 +1,23 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""novelWriter Test Tools """
novelWriter Test Suite Tools
==============================
This file is a part of novelWriter
Copyright 20182021, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
import os import os