Add project variables for character counts
This commit is contained in:
+20
-4
@@ -897,9 +897,10 @@ class RecentProjects:
|
|||||||
puuid = str(entry.get("uuid", ""))
|
puuid = str(entry.get("uuid", ""))
|
||||||
title = str(entry.get("title", ""))
|
title = str(entry.get("title", ""))
|
||||||
words = checkInt(entry.get("words", 0), 0)
|
words = checkInt(entry.get("words", 0), 0)
|
||||||
|
chars = checkInt(entry.get("chars", 0), 0)
|
||||||
saved = checkInt(entry.get("time", 0), 0)
|
saved = checkInt(entry.get("time", 0), 0)
|
||||||
if path and title:
|
if path and title:
|
||||||
self._setEntry(puuid, path, title, words, saved)
|
self._setEntry(puuid, path, title, words, chars, saved)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.error("Could not load recent project cache")
|
logger.error("Could not load recent project cache")
|
||||||
logException()
|
logException()
|
||||||
@@ -932,7 +933,14 @@ class RecentProjects:
|
|||||||
try:
|
try:
|
||||||
if (remove := self._map.get(data.uuid)) and (remove != str(path)):
|
if (remove := self._map.get(data.uuid)) and (remove != str(path)):
|
||||||
self.remove(remove)
|
self.remove(remove)
|
||||||
self._setEntry(data.uuid, str(path), data.name, sum(data.currCounts), int(saved))
|
self._setEntry(
|
||||||
|
data.uuid,
|
||||||
|
str(path),
|
||||||
|
data.name,
|
||||||
|
sum(data.currCounts[:2]),
|
||||||
|
sum(data.currCounts[2:]),
|
||||||
|
int(saved),
|
||||||
|
)
|
||||||
self.saveCache()
|
self.saveCache()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
@@ -945,9 +953,17 @@ class RecentProjects:
|
|||||||
self.saveCache()
|
self.saveCache()
|
||||||
return
|
return
|
||||||
|
|
||||||
def _setEntry(self, puuid: str, path: str, title: str, words: int, saved: int) -> None:
|
def _setEntry(
|
||||||
|
self, puuid: str, path: str, title: str, words: int, chars: int, saved: int
|
||||||
|
) -> None:
|
||||||
"""Set an entry in the recent projects record."""
|
"""Set an entry in the recent projects record."""
|
||||||
self._data[path] = {"uuid": puuid, "title": title, "words": words, "time": saved}
|
self._data[path] = {
|
||||||
|
"uuid": puuid,
|
||||||
|
"title": title,
|
||||||
|
"words": words,
|
||||||
|
"chars": chars,
|
||||||
|
"time": saved,
|
||||||
|
}
|
||||||
if puuid:
|
if puuid:
|
||||||
self._map[puuid] = path
|
self._map[puuid] = path
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ class NWProject:
|
|||||||
# Often, the index needs to be rebuilt when updating format
|
# Often, the index needs to be rebuilt when updating format
|
||||||
self._index.rebuild()
|
self._index.rebuild()
|
||||||
|
|
||||||
self.updateWordCounts()
|
self.updateCounts()
|
||||||
self._session.startSession()
|
self._session.startSession()
|
||||||
self.setProjectChanged(False)
|
self.setProjectChanged(False)
|
||||||
self._valid = True
|
self._valid = True
|
||||||
@@ -397,7 +397,7 @@ class NWProject:
|
|||||||
else:
|
else:
|
||||||
self._data.incSaveCount()
|
self._data.incSaveCount()
|
||||||
|
|
||||||
self.updateWordCounts()
|
self.updateCounts()
|
||||||
self.countStatus()
|
self.countStatus()
|
||||||
|
|
||||||
xmlWriter = self._storage.getXmlWriter()
|
xmlWriter = self._storage.getXmlWriter()
|
||||||
@@ -515,10 +515,10 @@ class NWProject:
|
|||||||
# Class Methods
|
# Class Methods
|
||||||
##
|
##
|
||||||
|
|
||||||
def updateWordCounts(self) -> None:
|
def updateCounts(self) -> None:
|
||||||
"""Update the total word count values."""
|
"""Update the total word and character count values."""
|
||||||
novel, notes = self._tree.sumWords()
|
wNovel, wNotes, cNovel, cNotes = self._tree.sumWords()
|
||||||
self._data.setCurrCounts(novel=novel, notes=notes)
|
self._data.setCurrCounts(wNovel=wNovel, wNotes=wNotes, cNovel=cNovel, cNotes=cNotes)
|
||||||
return
|
return
|
||||||
|
|
||||||
def countStatus(self) -> None:
|
def countStatus(self) -> None:
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ class NWProjectData:
|
|||||||
self._spellLang = None
|
self._spellLang = None
|
||||||
|
|
||||||
# Project Dictionaries
|
# Project Dictionaries
|
||||||
self._initCounts = [0, 0]
|
self._initCounts = [0, 0, 0, 0]
|
||||||
self._currCounts = [0, 0]
|
self._currCounts = [0, 0, 0, 0]
|
||||||
self._lastHandle: dict[str, str | None] = {
|
self._lastHandle: dict[str, str | None] = {
|
||||||
"editor": None,
|
"editor": None,
|
||||||
"viewer": None,
|
"viewer": None,
|
||||||
@@ -148,18 +148,18 @@ class NWProjectData:
|
|||||||
return self._spellLang
|
return self._spellLang
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def initCounts(self) -> tuple[int, int]:
|
def initCounts(self) -> tuple[int, int, int, int]:
|
||||||
"""Return the initial count of words for novel and note
|
"""Return the initial count of words and characters for novel
|
||||||
documents.
|
and note documents.
|
||||||
"""
|
"""
|
||||||
return self._initCounts[0], self._initCounts[1]
|
return self._initCounts[0], self._initCounts[1], self._initCounts[2], self._initCounts[3]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def currCounts(self) -> tuple[int, int]:
|
def currCounts(self) -> tuple[int, int, int, int]:
|
||||||
"""Return the current count of words for novel and note
|
"""Return the current count of words and characters for novel
|
||||||
documents.
|
and note documents.
|
||||||
"""
|
"""
|
||||||
return self._currCounts[0], self._currCounts[1]
|
return self._currCounts[0], self._currCounts[1], self._currCounts[2], self._currCounts[3]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def lastHandle(self) -> dict[str, str | None]:
|
def lastHandle(self) -> dict[str, str | None]:
|
||||||
@@ -301,22 +301,40 @@ class NWProjectData:
|
|||||||
self._project.setProjectChanged(True)
|
self._project.setProjectChanged(True)
|
||||||
return
|
return
|
||||||
|
|
||||||
def setInitCounts(self, novel: Any = None, notes: Any = None) -> None:
|
def setInitCounts(
|
||||||
"""Set the word count totals for novel and note files."""
|
self, wNovel: Any = None, wNotes: Any = None, cNovel: Any = None, cNotes: Any = None
|
||||||
if novel is not None:
|
) -> None:
|
||||||
self._initCounts[0] = checkInt(novel, 0)
|
"""Set the count totals for novel and note files."""
|
||||||
self._currCounts[0] = checkInt(novel, 0)
|
if wNovel is not None:
|
||||||
if notes is not None:
|
count = checkInt(wNovel, 0)
|
||||||
self._initCounts[1] = checkInt(notes, 0)
|
self._initCounts[0] = count
|
||||||
self._currCounts[1] = checkInt(notes, 0)
|
self._currCounts[0] = count
|
||||||
|
if wNotes is not None:
|
||||||
|
count = checkInt(wNotes, 0)
|
||||||
|
self._initCounts[1] = count
|
||||||
|
self._currCounts[1] = count
|
||||||
|
if cNovel is not None:
|
||||||
|
count = checkInt(cNovel, 0)
|
||||||
|
self._initCounts[2] = count
|
||||||
|
self._currCounts[2] = count
|
||||||
|
if cNotes is not None:
|
||||||
|
count = checkInt(cNotes, 0)
|
||||||
|
self._initCounts[3] = count
|
||||||
|
self._currCounts[3] = count
|
||||||
return
|
return
|
||||||
|
|
||||||
def setCurrCounts(self, novel: Any = None, notes: Any = None) -> None:
|
def setCurrCounts(
|
||||||
"""Set the word count totals for novel and note files."""
|
self, wNovel: Any = None, wNotes: Any = None, cNovel: Any = None, cNotes: Any = None
|
||||||
if novel is not None:
|
) -> None:
|
||||||
self._currCounts[0] = checkInt(novel, 0)
|
"""Set the count totals for novel and note files."""
|
||||||
if notes is not None:
|
if wNovel is not None:
|
||||||
self._currCounts[1] = checkInt(notes, 0)
|
self._currCounts[0] = checkInt(wNovel, 0)
|
||||||
|
if wNotes is not None:
|
||||||
|
self._currCounts[1] = checkInt(wNotes, 0)
|
||||||
|
if cNovel is not None:
|
||||||
|
self._currCounts[2] = checkInt(cNovel, 0)
|
||||||
|
if cNotes is not None:
|
||||||
|
self._currCounts[3] = checkInt(cNotes, 0)
|
||||||
return
|
return
|
||||||
|
|
||||||
def setAutoReplace(self, value: dict) -> None:
|
def setAutoReplace(self, value: dict) -> None:
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ if TYPE_CHECKING:
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
FILE_VERSION = "1.5" # The current project file format version
|
FILE_VERSION = "1.5" # The current project file format version
|
||||||
FILE_REVISION = "4" # The current project file format revision
|
FILE_REVISION = "5" # The current project file format revision
|
||||||
HEX_VERSION = 0x0105
|
HEX_VERSION = 0x0105
|
||||||
|
|
||||||
NUM_VERSION = {
|
NUM_VERSION = {
|
||||||
@@ -109,6 +109,8 @@ class ProjectXMLReader:
|
|||||||
Rev 3: Added TEMPLATE class. 2.3.
|
Rev 3: Added TEMPLATE class. 2.3.
|
||||||
Rev 4: Added shape attribute to status and importance entry
|
Rev 4: Added shape attribute to status and importance entry
|
||||||
nodes. 2.5.
|
nodes. 2.5.
|
||||||
|
Rev 5: Added novelChars and notesChars attributes to content
|
||||||
|
node. 2.7 RC 1.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, path: str | Path) -> None:
|
def __init__(self, path: str | Path) -> None:
|
||||||
@@ -286,9 +288,9 @@ class ProjectXMLReader:
|
|||||||
elif xItem.tag == "spellLang": # Changed to spellChecking in 1.5
|
elif xItem.tag == "spellLang": # Changed to spellChecking in 1.5
|
||||||
data.setSpellLang(xItem.text)
|
data.setSpellLang(xItem.text)
|
||||||
elif xItem.tag == "novelWordCount": # Moved to content attribute in 1.5
|
elif xItem.tag == "novelWordCount": # Moved to content attribute in 1.5
|
||||||
data.setInitCounts(novel=xItem.text)
|
data.setInitCounts(wNovel=xItem.text)
|
||||||
elif xItem.tag == "notesWordCount": # Moved to content attribute in 1.5
|
elif xItem.tag == "notesWordCount": # Moved to content attribute in 1.5
|
||||||
data.setInitCounts(notes=xItem.text)
|
data.setInitCounts(wNotes=xItem.text)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -298,8 +300,13 @@ class ProjectXMLReader:
|
|||||||
"""Parse the content section of the XML file."""
|
"""Parse the content section of the XML file."""
|
||||||
logger.debug("Parsing <content> section")
|
logger.debug("Parsing <content> section")
|
||||||
|
|
||||||
data.setInitCounts(novel=xSection.attrib.get("novelWords", None)) # Moved in 1.5
|
# Moved in 1.5
|
||||||
data.setInitCounts(notes=xSection.attrib.get("notesWords", None)) # Moved in 1.5
|
data.setInitCounts(
|
||||||
|
wNovel=xSection.attrib.get("novelWords", None),
|
||||||
|
wNotes=xSection.attrib.get("notesWords", None),
|
||||||
|
cNovel=xSection.attrib.get("novelChars", None),
|
||||||
|
cNotes=xSection.attrib.get("notesChars", None),
|
||||||
|
)
|
||||||
|
|
||||||
for xItem in xSection:
|
for xItem in xSection:
|
||||||
if xItem.tag != "item":
|
if xItem.tag != "item":
|
||||||
@@ -527,10 +534,13 @@ class ProjectXMLWriter:
|
|||||||
self._packSingleValue(xImport, "entry", label, attrib=attrib)
|
self._packSingleValue(xImport, "entry", label, attrib=attrib)
|
||||||
|
|
||||||
# Save Tree Content
|
# Save Tree Content
|
||||||
|
counts = data.currCounts
|
||||||
contAttr = {
|
contAttr = {
|
||||||
"items": str(len(content)),
|
"items": str(len(content)),
|
||||||
"novelWords": str(data.currCounts[0]),
|
"novelWords": str(counts[0]),
|
||||||
"notesWords": str(data.currCounts[1]),
|
"notesWords": str(counts[1]),
|
||||||
|
"novelChars": str(counts[2]),
|
||||||
|
"notesChars": str(counts[3]),
|
||||||
}
|
}
|
||||||
|
|
||||||
xContent = ET.SubElement(xRoot, "content", attrib=contAttr)
|
xContent = ET.SubElement(xRoot, "content", attrib=contAttr)
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ class NWSessionLog:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
now = time()
|
now = time()
|
||||||
iNovel, iNotes = self._project.data.initCounts
|
iNovel, iNotes, _, _ = self._project.data.initCounts
|
||||||
cNovel, cNotes = self._project.data.currCounts
|
cNovel, cNotes, _, _ = self._project.data.currCounts
|
||||||
iTotal = iNovel + iNotes
|
iTotal = iNovel + iNotes
|
||||||
wDiff = cNovel + cNotes - iTotal
|
wDiff = cNovel + cNotes - iTotal
|
||||||
sTime = now - self._start
|
sTime = now - self._start
|
||||||
|
|||||||
@@ -410,16 +410,20 @@ class NWTree:
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def sumWords(self) -> tuple[int, int]:
|
def sumWords(self) -> tuple[int, int, int, int]:
|
||||||
"""Loop over all entries and add up the word counts."""
|
"""Loop over all entries and add up the word and char counts."""
|
||||||
noteWords = 0
|
|
||||||
novelWords = 0
|
novelWords = 0
|
||||||
|
notesWords = 0
|
||||||
|
novelChars = 0
|
||||||
|
notesChars = 0
|
||||||
for item in self._items.values():
|
for item in self._items.values():
|
||||||
if item.itemLayout == nwItemLayout.NOTE:
|
if item.itemLayout == nwItemLayout.NOTE:
|
||||||
noteWords += item.wordCount
|
notesWords += item.wordCount
|
||||||
|
notesChars += item.charCount
|
||||||
elif item.itemLayout == nwItemLayout.DOCUMENT:
|
elif item.itemLayout == nwItemLayout.DOCUMENT:
|
||||||
novelWords += item.wordCount
|
novelWords += item.wordCount
|
||||||
return novelWords, noteWords
|
novelChars += item.charCount
|
||||||
|
return novelWords, notesWords, novelChars, notesChars
|
||||||
|
|
||||||
##
|
##
|
||||||
# Tree Item Methods
|
# Tree Item Methods
|
||||||
|
|||||||
@@ -1261,15 +1261,14 @@ class GuiMain(QMainWindow):
|
|||||||
if self._lastTotalCount != currentTotalCount:
|
if self._lastTotalCount != currentTotalCount:
|
||||||
self._lastTotalCount = currentTotalCount
|
self._lastTotalCount = currentTotalCount
|
||||||
|
|
||||||
SHARED.project.updateWordCounts()
|
SHARED.project.updateCounts()
|
||||||
if CONFIG.incNotesWCount:
|
if CONFIG.incNotesWCount:
|
||||||
iTotal = sum(SHARED.project.data.initCounts)
|
iTotal = sum(SHARED.project.data.initCounts[:2])
|
||||||
cTotal = sum(SHARED.project.data.currCounts)
|
cTotal = sum(SHARED.project.data.currCounts[:2])
|
||||||
self.mainStatus.setProjectStats(cTotal, cTotal - iTotal)
|
|
||||||
else:
|
else:
|
||||||
iNovel, _ = SHARED.project.data.initCounts
|
iTotal = SHARED.project.data.initCounts[0]
|
||||||
cNovel, _ = SHARED.project.data.currCounts
|
cTotal = SHARED.project.data.currCounts[0]
|
||||||
self.mainStatus.setProjectStats(cNovel, cNovel - iNovel)
|
self.mainStatus.setProjectStats(cTotal, cTotal - iTotal)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -256,8 +256,8 @@ class _OverviewPage(NScrollablePage):
|
|||||||
def updateProjectData(self) -> None:
|
def updateProjectData(self) -> None:
|
||||||
"""Load information about the project."""
|
"""Load information about the project."""
|
||||||
project = SHARED.project
|
project = SHARED.project
|
||||||
project.updateWordCounts()
|
project.updateCounts()
|
||||||
wcNovel, wcNotes = project.data.currCounts
|
wcNovel, wcNotes, _, _ = project.data.currCounts
|
||||||
|
|
||||||
self.projName.setText(project.data.name)
|
self.projName.setText(project.data.name)
|
||||||
self.projRevisions.setText(f"{project.data.saveCount:n}")
|
self.projRevisions.setText(f"{project.data.saveCount:n}")
|
||||||
|
|||||||
Reference in New Issue
Block a user