Fix word count accounting and double click tree expansion
This commit is contained in:
@@ -82,7 +82,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
# Tree Settings
|
# Tree Settings
|
||||||
iPx = self.theTheme.baseIconSize
|
iPx = self.theTheme.baseIconSize
|
||||||
self.setIconSize(QSize(iPx, iPx))
|
self.setIconSize(QSize(iPx, iPx))
|
||||||
self.setExpandsOnDoubleClick(True)
|
self.setExpandsOnDoubleClick(False)
|
||||||
self.setIndentation(iPx)
|
self.setIndentation(iPx)
|
||||||
self.setColumnCount(4)
|
self.setColumnCount(4)
|
||||||
self.setHeaderLabels([
|
self.setHeaderLabels([
|
||||||
@@ -349,6 +349,14 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
theList = self._scanChildren(theList, theItem, 0)
|
theList = self._scanChildren(theList, theItem, 0)
|
||||||
return theList
|
return theList
|
||||||
|
|
||||||
|
def toggleExpanded(self, tHandle):
|
||||||
|
"""Expand an item based on its handle.
|
||||||
|
"""
|
||||||
|
trItem = self._getTreeItem(tHandle)
|
||||||
|
if trItem is not None:
|
||||||
|
trItem.setExpanded(not trItem.isExpanded())
|
||||||
|
return
|
||||||
|
|
||||||
def getColumnSizes(self):
|
def getColumnSizes(self):
|
||||||
"""Return the column widths for the tree columns.
|
"""Return the column widths for the tree columns.
|
||||||
"""
|
"""
|
||||||
@@ -576,7 +584,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def propagateCount(self, tHandle, theCount):
|
def propagateCount(self, tHandle, newCount, countChildren=False):
|
||||||
"""Recursive function setting the word count for a given item,
|
"""Recursive function setting the word count for a given item,
|
||||||
and propagating that count upwards in the tree until reaching a
|
and propagating that count upwards in the tree until reaching a
|
||||||
root item. This function is more efficient than recalculating
|
root item. This function is more efficient than recalculating
|
||||||
@@ -588,8 +596,12 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
if tItem is None:
|
if tItem is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
tItem.setText(self.C_COUNT, f"{theCount:n}")
|
if countChildren:
|
||||||
tItem.setData(self.C_COUNT, Qt.UserRole, int(theCount))
|
for i in range(tItem.childCount()):
|
||||||
|
newCount += int(tItem.child(i).data(self.C_COUNT, Qt.UserRole))
|
||||||
|
|
||||||
|
tItem.setText(self.C_COUNT, f"{newCount:n}")
|
||||||
|
tItem.setData(self.C_COUNT, Qt.UserRole, int(newCount))
|
||||||
|
|
||||||
pItem = tItem.parent()
|
pItem = tItem.parent()
|
||||||
if pItem is None:
|
if pItem is None:
|
||||||
@@ -602,7 +614,12 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
pHandle = pItem.data(self.C_NAME, Qt.UserRole)
|
pHandle = pItem.data(self.C_NAME, Qt.UserRole)
|
||||||
|
|
||||||
if pHandle:
|
if pHandle:
|
||||||
self.propagateCount(pHandle, pCount)
|
if self.theProject.projTree.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.theIndex.getCounts(pHandle)[1]
|
||||||
|
|
||||||
|
self.propagateCount(pHandle, pCount, countChildren=False)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -724,7 +741,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
def doUpdateCounts(self, tHandle, cCount, wCount, pCount):
|
def doUpdateCounts(self, tHandle, cCount, wCount, pCount):
|
||||||
"""Slot for updating the word count of a specific item.
|
"""Slot for updating the word count of a specific item.
|
||||||
"""
|
"""
|
||||||
self.propagateCount(tHandle, wCount)
|
self.propagateCount(tHandle, wCount, countChildren=True)
|
||||||
self.wordCountsChanged.emit()
|
self.wordCountsChanged.emit()
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -908,7 +925,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
self._treeMap[pHandle].insertChild(byIndex+1, newItem)
|
self._treeMap[pHandle].insertChild(byIndex+1, newItem)
|
||||||
else:
|
else:
|
||||||
self._treeMap[pHandle].addChild(newItem)
|
self._treeMap[pHandle].addChild(newItem)
|
||||||
self.propagateCount(tHandle, nwItem.wordCount)
|
self.propagateCount(tHandle, nwItem.wordCount, countChildren=True)
|
||||||
|
|
||||||
self.setTreeItemValues(tHandle)
|
self.setTreeItemValues(tHandle)
|
||||||
newItem.setExpanded(nwItem.isExpanded)
|
newItem.setExpanded(nwItem.isExpanded)
|
||||||
|
|||||||
@@ -906,7 +906,7 @@ class GuiMain(QMainWindow):
|
|||||||
tItem.setCharCount(cC)
|
tItem.setCharCount(cC)
|
||||||
tItem.setWordCount(wC)
|
tItem.setWordCount(wC)
|
||||||
tItem.setParaCount(pC)
|
tItem.setParaCount(pC)
|
||||||
self.treeView.propagateCount(tItem.itemHandle, wC)
|
self.treeView.propagateCount(tItem.itemHandle, wC, countChildren=True)
|
||||||
self.treeView.setTreeItemValues(tItem.itemHandle)
|
self.treeView.setTreeItemValues(tItem.itemHandle)
|
||||||
|
|
||||||
tEnd = time()
|
tEnd = time()
|
||||||
@@ -1568,11 +1568,17 @@ class GuiMain(QMainWindow):
|
|||||||
@pyqtSlot("QTreeWidgetItem*", int)
|
@pyqtSlot("QTreeWidgetItem*", int)
|
||||||
def _treeDoubleClick(self, tItem, colNo):
|
def _treeDoubleClick(self, tItem, colNo):
|
||||||
"""The user double-clicked an item in the tree. If it is a file,
|
"""The user double-clicked an item in the tree. If it is a file,
|
||||||
we open it. Otherwise, we do nothing.
|
we open it. Otherwise, we toggle the expanded status.
|
||||||
"""
|
"""
|
||||||
tHandle = self.treeView.getSelectedHandle()
|
tHandle = self.treeView.getSelectedHandle()
|
||||||
if tHandle is not None:
|
if tHandle is not None:
|
||||||
self.openDocument(tHandle, changeFocus=False, doScroll=False)
|
tItem = self.theProject.projTree[tHandle]
|
||||||
|
if tItem is None:
|
||||||
|
return
|
||||||
|
if tItem.itemType == nwItemType.FILE:
|
||||||
|
self.openDocument(tHandle, changeFocus=False, doScroll=False)
|
||||||
|
else:
|
||||||
|
self.treeView.toggleExpanded(tHandle)
|
||||||
return
|
return
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
%%~name: Making a Scene
|
%%~name: Making a Scene
|
||||||
%%~path: e7ded148d6e4a/636b6aa9b697b
|
%%~path: 6a2d6d5f4f401/636b6aa9b697b
|
||||||
%%~kind: NOVEL/DOCUMENT
|
%%~kind: NOVEL/DOCUMENT
|
||||||
### Making a Scene
|
### Making a Scene
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
%%~name: We Found John!
|
%%~name: We Found John!
|
||||||
%%~path: e7ded148d6e4a/ae7339df26ded
|
%%~path: 88706ddc78b1b/ae7339df26ded
|
||||||
%%~kind: NOVEL/DOCUMENT
|
%%~kind: NOVEL/DOCUMENT
|
||||||
### We Found John!
|
### We Found John!
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
%%~name: Another Scene
|
%%~name: Another Scene
|
||||||
%%~path: e7ded148d6e4a/bc0cbd2a407f3
|
%%~path: 6a2d6d5f4f401/bc0cbd2a407f3
|
||||||
%%~kind: NOVEL/DOCUMENT
|
%%~kind: NOVEL/DOCUMENT
|
||||||
### Another Scene
|
### Another Scene
|
||||||
|
|
||||||
|
|||||||
+11
-11
@@ -1,13 +1,13 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<novelWriterXML appVersion="1.7-alpha0" hexVersion="0x010700a0" fileVersion="1.4" timeStamp="2022-04-23 16:56:31">
|
<novelWriterXML appVersion="1.7-alpha0" hexVersion="0x010700a0" fileVersion="1.4" timeStamp="2022-04-23 18:59:25">
|
||||||
<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>
|
||||||
<saveCount>1309</saveCount>
|
<saveCount>1323</saveCount>
|
||||||
<autoCount>201</autoCount>
|
<autoCount>207</autoCount>
|
||||||
<editTime>65353</editTime>
|
<editTime>66237</editTime>
|
||||||
</project>
|
</project>
|
||||||
<settings>
|
<settings>
|
||||||
<doBackup>False</doBackup>
|
<doBackup>False</doBackup>
|
||||||
@@ -69,22 +69,22 @@
|
|||||||
<meta expanded="True"/>
|
<meta expanded="True"/>
|
||||||
<name status="s90e6c9" import="ia857f0">A Folder</name>
|
<name status="s90e6c9" import="ia857f0">A Folder</name>
|
||||||
</item>
|
</item>
|
||||||
<item handle="ba8a28a246524" parent="e7ded148d6e4a" root="7031beac91f75" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
<item handle="6a2d6d5f4f401" parent="e7ded148d6e4a" root="7031beac91f75" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||||
<meta expanded="False" charCount="617" wordCount="101" paraCount="3" cursorPos="4"/>
|
|
||||||
<name status="sf12341" import="ia857f0" exported="True">Interlude</name>
|
|
||||||
</item>
|
|
||||||
<item handle="6a2d6d5f4f401" parent="e7ded148d6e4a" root="7031beac91f75" order="1" type="FILE" class="NOVEL" layout="DOCUMENT">
|
|
||||||
<meta expanded="True" charCount="75" wordCount="14" paraCount="1" cursorPos="279"/>
|
<meta expanded="True" charCount="75" wordCount="14" paraCount="1" cursorPos="279"/>
|
||||||
<name status="sf24ce6" import="ia857f0" exported="True">Chapter One</name>
|
<name status="sf24ce6" import="ia857f0" exported="True">Chapter One</name>
|
||||||
</item>
|
</item>
|
||||||
<item handle="636b6aa9b697b" parent="6a2d6d5f4f401" root="7031beac91f75" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
<item handle="636b6aa9b697b" parent="6a2d6d5f4f401" root="7031beac91f75" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||||
<meta expanded="False" charCount="2429" wordCount="432" paraCount="14" cursorPos="219"/>
|
<meta expanded="True" charCount="2429" wordCount="432" paraCount="14" cursorPos="1479"/>
|
||||||
<name status="s90e6c9" import="ia857f0" exported="True">Making a Scene</name>
|
<name status="s90e6c9" import="ia857f0" exported="True">Making a Scene</name>
|
||||||
</item>
|
</item>
|
||||||
<item handle="bc0cbd2a407f3" parent="6a2d6d5f4f401" root="7031beac91f75" order="1" type="FILE" class="NOVEL" layout="DOCUMENT">
|
<item handle="bc0cbd2a407f3" parent="6a2d6d5f4f401" root="7031beac91f75" order="1" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||||
<meta expanded="False" charCount="476" wordCount="93" paraCount="3" cursorPos="577"/>
|
<meta expanded="False" charCount="476" wordCount="93" paraCount="3" cursorPos="577"/>
|
||||||
<name status="s90e6c9" import="ia857f0" exported="True">Another Scene</name>
|
<name status="s90e6c9" import="ia857f0" exported="True">Another Scene</name>
|
||||||
</item>
|
</item>
|
||||||
|
<item handle="ba8a28a246524" parent="e7ded148d6e4a" root="7031beac91f75" order="1" type="FILE" class="NOVEL" layout="DOCUMENT">
|
||||||
|
<meta expanded="False" charCount="617" wordCount="101" paraCount="3" cursorPos="4"/>
|
||||||
|
<name status="sf12341" import="ia857f0" exported="True">Interlude</name>
|
||||||
|
</item>
|
||||||
<item handle="96b68994dfa3d" parent="e7ded148d6e4a" root="7031beac91f75" order="2" type="FILE" class="NOVEL" layout="NOTE">
|
<item handle="96b68994dfa3d" parent="e7ded148d6e4a" root="7031beac91f75" order="2" type="FILE" class="NOVEL" layout="NOTE">
|
||||||
<meta expanded="False" charCount="1692" wordCount="313" paraCount="6" cursorPos="1110"/>
|
<meta expanded="False" charCount="1692" wordCount="313" paraCount="6" cursorPos="1110"/>
|
||||||
<name status="sd51c5b" import="ia857f0" exported="False">A Note on Structure</name>
|
<name status="sd51c5b" import="ia857f0" exported="False">A Note on Structure</name>
|
||||||
@@ -138,7 +138,7 @@
|
|||||||
<name status="sf12341" import="ia857f0">Scenes</name>
|
<name status="sf12341" import="ia857f0">Scenes</name>
|
||||||
</item>
|
</item>
|
||||||
<item handle="8a5deb88c0e97" parent="ae9bf3c3ea159" root="6827118336ac1" order="0" type="FILE" class="ARCHIVE" layout="DOCUMENT">
|
<item handle="8a5deb88c0e97" parent="ae9bf3c3ea159" root="6827118336ac1" order="0" type="FILE" class="ARCHIVE" layout="DOCUMENT">
|
||||||
<meta expanded="False" charCount="315" wordCount="55" paraCount="1" cursorPos="322"/>
|
<meta expanded="False" charCount="314" wordCount="55" paraCount="1" cursorPos="322"/>
|
||||||
<name status="s90e6c9" import="ia857f0" exported="True">Old File</name>
|
<name status="s90e6c9" import="ia857f0" exported="True">Old File</name>
|
||||||
</item>
|
</item>
|
||||||
<item handle="98acd8c76c93a" parent="None" root="98acd8c76c93a" order="4" type="ROOT" class="TRASH">
|
<item handle="98acd8c76c93a" parent="None" root="98acd8c76c93a" order="4" type="ROOT" class="TRASH">
|
||||||
|
|||||||
Reference in New Issue
Block a user