Proagate word counts and save them for files.

This commit is contained in:
Veronica K. B. Olsen
2019-04-22 17:02:52 +02:00
parent 2727ade4a0
commit 3631b239fc
10 changed files with 103 additions and 91 deletions
+8 -4
View File
@@ -34,7 +34,7 @@ class GuiDocEditor(QWidget):
self.theParent = theParent self.theParent = theParent
self.charCount = 0 self.charCount = 0
self.wordCount = 0 self.wordCount = 0
self.lineCount = 0 self.paraCount = 0
self.lastEdit = 0 self.lastEdit = 0
self.outerBox = QVBoxLayout() self.outerBox = QVBoxLayout()
@@ -183,11 +183,15 @@ class GuiDocEditor(QWidget):
def _updateCounts(self): def _updateCounts(self):
"""Slot for the word counter's finished signal """Slot for the word counter's finished signal
""" """
logger.verbose("Updating word counts") logger.verbose("Updating word count")
tHandle = self.theParent.theDocument.docHandle
self.charCount = self.wCounter.charCount self.charCount = self.wCounter.charCount
self.wordCount = self.wCounter.wordCount self.wordCount = self.wCounter.wordCount
self.theParent.statusBar.setCharCount(self.charCount) self.paraCount = self.wCounter.paraCount
self.theParent.statusBar.setWordCount(self.wordCount) self.theParent.statusBar.setCounts(self.charCount,self.wordCount,self.paraCount)
self.theParent.treeView.propagateCount(tHandle, self.wordCount)
return return
## ##
+19 -5
View File
@@ -15,10 +15,11 @@ import nw
from os import path from os import path
from PyQt5.QtGui import QIcon from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QSize from PyQt5.QtCore import Qt, QSize
from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QAbstractItemView from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QAbstractItemView
from nw.enum import nwItemType, nwItemClass from nw.enum import nwItemType, nwItemClass
from nw.project.item import NWItem
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -33,12 +34,11 @@ class GuiDocTree(QTreeWidget):
self.theProject = theProject self.theProject = theProject
self.theMap = {} self.theMap = {}
self.setStyleSheet("QTreeWidget {font-size: 13px;}")
self.setIconSize(QSize(13,13)) self.setIconSize(QSize(13,13))
self.setExpandsOnDoubleClick(True) self.setExpandsOnDoubleClick(True)
self.setIndentation(13) self.setIndentation(13)
self.setColumnCount(4) self.setColumnCount(4)
self.setHeaderLabels(["Name","","","Handle"]) self.setHeaderLabels(["Name","S","#","Handle"])
if not self.debugGUI: if not self.debugGUI:
self.hideColumn(3) self.hideColumn(3)
@@ -134,15 +134,16 @@ class GuiDocTree(QTreeWidget):
tHandle = nwItem.itemHandle tHandle = nwItem.itemHandle
pHandle = nwItem.parHandle pHandle = nwItem.parHandle
tStatus = 0 tStatus = 0
wCount = 0
newItem = QTreeWidgetItem([ newItem = QTreeWidgetItem([
tName, str(tStatus), str(wCount), tHandle tName, str(tStatus), "0", tHandle
]) ])
self.theMap[tHandle] = newItem self.theMap[tHandle] = newItem
if pHandle is None: if pHandle is None:
self.addTopLevelItem(newItem) self.addTopLevelItem(newItem)
else: else:
self.theMap[pHandle].addChild(newItem) self.theMap[pHandle].addChild(newItem)
self.propagateCount(tHandle, nwItem.wordCount)
newItem.setTextAlignment(2,Qt.AlignRight)
newItem.setExpanded(nwItem.isExpanded) newItem.setExpanded(nwItem.isExpanded)
if nwItem.itemType == nwItemType.ROOT: if nwItem.itemType == nwItemType.ROOT:
newItem.setIcon(0, QIcon.fromTheme("drive-harddisk")) newItem.setIcon(0, QIcon.fromTheme("drive-harddisk"))
@@ -152,6 +153,19 @@ class GuiDocTree(QTreeWidget):
newItem.setIcon(0, QIcon.fromTheme("x-office-document")) newItem.setIcon(0, QIcon.fromTheme("x-office-document"))
return True return True
def propagateCount(self, tHandle, theCount, nDepth=0):
tItem = self.theMap[tHandle]
tItem.setText(2,str(theCount))
pItem = tItem.parent()
if pItem is not None:
pCount = 0
for i in range(pItem.childCount()):
pCount += int(pItem.child(i).text(2))
pHandle = pItem.text(3)
if not nDepth > NWItem.MAX_DEPTH:
self.propagateCount(pHandle, pCount, nDepth+1)
return
def buildTree(self): def buildTree(self):
self.clear() self.clear()
for tHandle in self.theProject.projTree: for tHandle in self.theProject.projTree:
+9 -20
View File
@@ -14,7 +14,7 @@ import logging
import nw import nw
from os import path from os import path
from PyQt5.QtWidgets import QStatusBar, QLabel from PyQt5.QtWidgets import QStatusBar, QLabel, QFrame
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -27,35 +27,24 @@ class GuiMainStatus(QStatusBar):
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.boxWordCount = QLabel() self.boxCounts = QLabel()
self.boxCharCount = QLabel() self.boxCounts.setFrameStyle(QFrame.Panel | QFrame.Sunken);
self.boxDocHandle = QLabel() self.addPermanentWidget(self.boxCounts)
self.addPermanentWidget(self.boxWordCount) self.boxDocHandle = QLabel()
self.addPermanentWidget(self.boxCharCount) self.boxDocHandle.setFrameStyle(QFrame.Panel | QFrame.Sunken);
if self.mainConf.debugGUI: if self.mainConf.debugGUI:
self.addPermanentWidget(self.boxDocHandle) self.addPermanentWidget(self.boxDocHandle)
logger.debug("GuiMainStatus initialisation complete") logger.debug("GuiMainStatus initialisation complete")
self.setWordCount(None) self.setCounts(0,0,0)
self.setCharCount(None)
self.setDocHandleCount(None) self.setDocHandleCount(None)
return return
def setWordCount(self, theCount): def setCounts(self, cC, wC, pC):
if theCount is None: self.boxCounts.setText("<b>C:</b> {:n}&nbsp;&nbsp;<b>W:</b> {:n}&nbsp;&nbsp;<b>P:</b> {:n}".format(cC,wC,pC))
self.boxWordCount.setText("<b>Words:</b> --")
else:
self.boxWordCount.setText("<b>Words:</b> {:n}".format(theCount))
return
def setCharCount(self, theCount):
if theCount is None:
self.boxCharCount.setText("<b>Chars:</b> --")
else:
self.boxCharCount.setText("<b>Chars:</b> {:n}".format(theCount))
return return
def setDocHandleCount(self, theHandle): def setDocHandleCount(self, theHandle):
+3
View File
@@ -156,6 +156,9 @@ class GuiMain(QMainWindow):
def saveDocument(self): def saveDocument(self):
docHtml = self.docEditor.getText() docHtml = self.docEditor.getText()
self.theDocument.theItem.setCharCount(self.docEditor.charCount)
self.theDocument.theItem.setWordCount(self.docEditor.wordCount)
self.theDocument.theItem.setParaCount(self.docEditor.paraCount)
self.theDocument.saveDocument(docHtml) self.theDocument.saveDocument(docHtml)
return return
+16 -2
View File
@@ -26,12 +26,16 @@ class WordCounter(QThread):
self.theParent = theParent self.theParent = theParent
self.charCount = 0 self.charCount = 0
self.wordCount = 0 self.wordCount = 0
self.paraCount = 0
return return
def run(self): def run(self):
self.charCount = 0 self.charCount = 0
self.wordCount = 0 self.wordCount = 0
self.paraCount = 0
prevEmpty = True
for n in range(self.theParent.theDoc.blockCount()): for n in range(self.theParent.theDoc.blockCount()):
@@ -39,30 +43,40 @@ class WordCounter(QThread):
if not theBlock.isValid(): if not theBlock.isValid():
continue continue
theText = theBlock.text() countPara = True
theLen = len(theText) theText = theBlock.text()
theLen = len(theText)
if theLen == 0: if theLen == 0:
prevEmpty = True
continue continue
if theText[0] == "@" or theText[0] == "%": if theText[0] == "@" or theText[0] == "%":
prevEmpty = True
continue continue
if theText[0:5] == "#### ": if theText[0:5] == "#### ":
self.wordCount -= 1 self.wordCount -= 1
self.charCount -= 5 self.charCount -= 5
countPara = False
elif theText[0:4] == "### ": elif theText[0:4] == "### ":
self.wordCount -= 1 self.wordCount -= 1
self.charCount -= 4 self.charCount -= 4
countPara = False
elif theText[0:3] == "## ": elif theText[0:3] == "## ":
self.wordCount -= 1 self.wordCount -= 1
self.charCount -= 3 self.charCount -= 3
countPara = False
elif theText[0:2] == "# ": elif theText[0:2] == "# ":
self.wordCount -= 1 self.wordCount -= 1
self.charCount -= 2 self.charCount -= 2
countPara = False
theBuff = theText.replace(""," ").replace(""," ") theBuff = theText.replace(""," ").replace(""," ")
self.wordCount += len(theBuff.split()) self.wordCount += len(theBuff.split())
self.charCount += theLen self.charCount += theLen
if countPara and prevEmpty:
self.paraCount += 1
prevEmpty = countPara == False
pass pass
-25
View File
@@ -31,11 +31,6 @@ class NWDoc():
self.theItem = None self.theItem = None
self.docHandle = None self.docHandle = None
# Document Info
self.charCount = None
self.lineCount = None
self.wordCount = None
return return
def openDocument(self, tHandle): def openDocument(self, tHandle):
@@ -83,28 +78,8 @@ class NWDoc():
if path.isfile(docTemp): unlink(docTemp) if path.isfile(docTemp): unlink(docTemp)
docAna = TextAnalysis(docText,"en_GB")
wC, sC, pC = docAna.getStats()
# rScr, gLev = docAna.getReadabilityScore()
self.theItem.setWordCount(wC)
self.theItem.setSentCount(sC)
self.theItem.setParaCount(pC)
return True return True
##
# Setters
##
def setCharCount(self, theCount):
self.charCount = theCount
return
def setLineCount(self, theCount):
self.lineCount = theCount
return
## ##
# Internal Functions # Internal Functions
## ##
+15 -14
View File
@@ -37,9 +37,9 @@ class NWItem():
self.hasChildren = False self.hasChildren = False
self.isExpanded = False self.isExpanded = False
self.wordCount = None self.charCount = 0
self.sentCount = None self.wordCount = 0
self.paraCount = None self.paraCount = 0
return return
@@ -59,9 +59,10 @@ class NWItem():
xSub = self._subPack(xPack,"depth", text=str(self.itemDepth)) xSub = self._subPack(xPack,"depth", text=str(self.itemDepth))
xSub = self._subPack(xPack,"children", text=str(self.hasChildren)) xSub = self._subPack(xPack,"children", text=str(self.hasChildren))
xSub = self._subPack(xPack,"expanded", text=str(self.isExpanded)) xSub = self._subPack(xPack,"expanded", text=str(self.isExpanded))
xSub = self._subPack(xPack,"wordCount", text=str(self.wordCount), none=False) if self.itemType == nwItemType.FILE:
xSub = self._subPack(xPack,"sentCount", text=str(self.sentCount), none=False) xSub = self._subPack(xPack,"charCount", text=str(self.charCount), none=False)
xSub = self._subPack(xPack,"paraCount", text=str(self.paraCount), none=False) xSub = self._subPack(xPack,"wordCount", text=str(self.wordCount), none=False)
xSub = self._subPack(xPack,"paraCount", text=str(self.paraCount), none=False)
return xPack return xPack
def _subPack(self, xParent, name, attrib=None, text=None, none=True): def _subPack(self, xParent, name, attrib=None, text=None, none=True):
@@ -85,8 +86,8 @@ class NWItem():
elif tagName == "depth": self.setDepth(tagValue) elif tagName == "depth": self.setDepth(tagValue)
elif tagName == "children": self.setChildren(tagValue) elif tagName == "children": self.setChildren(tagValue)
elif tagName == "expanded": self.setExpanded(tagValue) elif tagName == "expanded": self.setExpanded(tagValue)
elif tagName == "charCount": self.setCharCount(tagValue)
elif tagName == "wordCount": self.setWordCount(tagValue) elif tagName == "wordCount": self.setWordCount(tagValue)
elif tagName == "sentCount": self.setSentCount(tagValue)
elif tagName == "paraCount": self.setParaCount(tagValue) elif tagName == "paraCount": self.setParaCount(tagValue)
else: else:
logger.error("Unknown tag '%s'" % tagName) logger.error("Unknown tag '%s'" % tagName)
@@ -159,18 +160,18 @@ class NWItem():
# Set Stats # Set Stats
## ##
def setCharCount(self, theCount):
theCount = self._checkInt(theCount,0)
self.charCount = theCount
return
def setWordCount(self, theCount): def setWordCount(self, theCount):
theCount = self._checkInt(theCount,None,True) theCount = self._checkInt(theCount,0)
self.wordCount = theCount self.wordCount = theCount
return return
def setSentCount(self, theCount):
theCount = self._checkInt(theCount,None,True)
self.sentCount = theCount
return
def setParaCount(self, theCount): def setParaCount(self, theCount):
theCount = self._checkInt(theCount,None,True) theCount = self._checkInt(theCount,0)
self.paraCount = theCount self.paraCount = theCount
return return
+13 -8
View File
@@ -43,8 +43,9 @@ class NWProject():
return return
def buildProjectTree(self): ##
return True # Add Entries
##
def newRoot(self, rootName, rootClass): def newRoot(self, rootName, rootClass):
newItem = NWItem() newItem = NWItem()
@@ -85,6 +86,10 @@ class NWProject():
hScene = self.newFile("New Scene", nwItemClass.NOVEL, hChapt) hScene = self.newFile("New Scene", nwItemClass.NOVEL, hChapt)
return return
##
# File I/O
##
def openProject(self, fileName): def openProject(self, fileName):
if not path.isfile(fileName): if not path.isfile(fileName):
@@ -194,9 +199,9 @@ class NWProject():
return True return True
# ##
# Set Functions # Set Functions
# ##
def setProjectPath(self, projPath): def setProjectPath(self, projPath):
self.projPath = projPath self.projPath = projPath
@@ -225,9 +230,9 @@ class NWProject():
self.treeOrder = newOrder self.treeOrder = newOrder
return True return True
# ##
# Get Functions # Get Functions
# ##
def getItem(self, tHandle): def getItem(self, tHandle):
if tHandle in self.projTree: if tHandle in self.projTree:
@@ -305,9 +310,9 @@ class NWProject():
return validActions return validActions
# ##
# Internal Functions # Internal Functions
# ##
def _checkRootUnique(self, theClass): def _checkRootUnique(self, theClass):
"""Checks if there already is a root entry of class 'theClass' in the """Checks if there already is a root entry of class 'theClass' in the
+6 -8
View File
@@ -7,12 +7,10 @@ QTextEdit {
color: #c7cfd0; color: #c7cfd0;
} }
QStatusBar::item { QTreeView, QHeaderView {
background-color: rgba(0,0,0,0.1); font-size: 13px;
border: 1px solid #666666;
}
QStatusBar::item QLabel {
background-color: rgba(0,0,0,0.0);
padding: 1px 4px;
} }
/* QStatusBar::item QLabel {
color: #990000;
font-style: normal;
} */
+14 -5
View File
@@ -1,12 +1,12 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.0.1" fileVersion="1.0" timeStamp="2019-04-19 23:41:53"> <novelWriterXML appVersion="0.0.1" fileVersion="1.0" timeStamp="2019-04-22 16:39:21">
<project> <project>
<name>Sample Project</name> <name>Sample Project</name>
<title>Sample Project</title> <title>Sample Project</title>
<author>Jane Smith</author> <author>Jane Smith</author>
<author>Jay Doh</author> <author>Jay Doh</author>
</project> </project>
<content count="8"> <content count="9">
<item handle="7031beac91f75" order="0" parent="None"> <item handle="7031beac91f75" order="0" parent="None">
<name>Novel</name> <name>Novel</name>
<type>ROOT</type> <type>ROOT</type>
@@ -30,9 +30,9 @@
<depth>2</depth> <depth>2</depth>
<children>False</children> <children>False</children>
<expanded>False</expanded> <expanded>False</expanded>
<wordCount>381</wordCount> <charCount>2573</charCount>
<sentCount>51</sentCount> <wordCount>377</wordCount>
<paraCount>9</paraCount> <paraCount>5</paraCount>
</item> </item>
<item handle="636b6aa9b697b" order="1" parent="e7ded148d6e4a"> <item handle="636b6aa9b697b" order="1" parent="e7ded148d6e4a">
<name>New File</name> <name>New File</name>
@@ -41,6 +41,9 @@
<depth>2</depth> <depth>2</depth>
<children>False</children> <children>False</children>
<expanded>False</expanded> <expanded>False</expanded>
<charCount>125</charCount>
<wordCount>24</wordCount>
<paraCount>2</paraCount>
</item> </item>
<item handle="f6622b4617424" order="1" parent="None"> <item handle="f6622b4617424" order="1" parent="None">
<name>Characters</name> <name>Characters</name>
@@ -57,6 +60,9 @@
<depth>1</depth> <depth>1</depth>
<children>False</children> <children>False</children>
<expanded>False</expanded> <expanded>False</expanded>
<charCount>0</charCount>
<wordCount>0</wordCount>
<paraCount>0</paraCount>
</item> </item>
<item handle="bb2c23b3c42cc" order="1" parent="f6622b4617424"> <item handle="bb2c23b3c42cc" order="1" parent="f6622b4617424">
<name>Jane Smith</name> <name>Jane Smith</name>
@@ -65,6 +71,9 @@
<depth>1</depth> <depth>1</depth>
<children>False</children> <children>False</children>
<expanded>False</expanded> <expanded>False</expanded>
<charCount>0</charCount>
<wordCount>0</wordCount>
<paraCount>0</paraCount>
</item> </item>
<item handle="73eee34351f85" order="2" parent="None"> <item handle="73eee34351f85" order="2" parent="None">
<name>World</name> <name>World</name>