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