Merge branch 'main' into travis_tweak
This commit is contained in:
@@ -277,3 +277,20 @@ Settings`.
|
|||||||
For the backup to be able to run, the :guilabel:`Working Title` must be set in :guilabel:`Project
|
For the backup to be able to run, the :guilabel:`Working Title` must be set in :guilabel:`Project
|
||||||
Settings`. This value is used to generate the folder name for the zip files. Without it, the
|
Settings`. This value is used to generate the folder name for the zip files. Without it, the
|
||||||
backup will not run at all, but produce a warning message.
|
backup will not run at all, but produce a warning message.
|
||||||
|
|
||||||
|
.. _a_proj_stats:
|
||||||
|
|
||||||
|
Writing Statistics
|
||||||
|
==================
|
||||||
|
|
||||||
|
When you work on your project, a log file records when you opened it, when you closed it, and how
|
||||||
|
many words you added to your novel and note files during the session. You can view this file in the
|
||||||
|
``meta`` folder in the directory where you saved your project. The file is named
|
||||||
|
``sessionStats.log``.
|
||||||
|
|
||||||
|
A small tool to view the content of this file is available in the :guilabel:`Tools` menu under
|
||||||
|
:guilabel:`Writing Statistics`. You can also launch it by pressing :kbd:`F6`.
|
||||||
|
|
||||||
|
The tool will show a list of all your sessions, and a set of filters to apply to it. You can also
|
||||||
|
export the filtered data to a JSON file or to a CSV file that can be opened by a spreadsheet
|
||||||
|
application like for instance Libre Office Calc.
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ class OptionState():
|
|||||||
"hideZeros",
|
"hideZeros",
|
||||||
"hideNegative",
|
"hideNegative",
|
||||||
"groupByDay",
|
"groupByDay",
|
||||||
|
"histMax",
|
||||||
},
|
},
|
||||||
"GuiDocSplit": {
|
"GuiDocSplit": {
|
||||||
"spLevel",
|
"spLevel",
|
||||||
|
|||||||
+35
-9
@@ -36,7 +36,7 @@ from PyQt5.QtCore import Qt
|
|||||||
from PyQt5.QtGui import QFont, QPixmap
|
from PyQt5.QtGui import QFont, QPixmap
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
qApp, QDialog, QTreeWidget, QTreeWidgetItem, QDialogButtonBox, QGridLayout,
|
qApp, QDialog, QTreeWidget, QTreeWidgetItem, QDialogButtonBox, QGridLayout,
|
||||||
QLabel, QGroupBox, QMenu, QAction, QFileDialog
|
QLabel, QGroupBox, QMenu, QAction, QFileDialog, QSpinBox, QHBoxLayout
|
||||||
)
|
)
|
||||||
|
|
||||||
from nw.constants import nwConst, nwFiles, nwAlert
|
from nw.constants import nwConst, nwFiles, nwAlert
|
||||||
@@ -207,11 +207,31 @@ class GuiWritingStats(QDialog):
|
|||||||
self.filterForm.addWidget(self.groupByDay, 4, 1)
|
self.filterForm.addWidget(self.groupByDay, 4, 1)
|
||||||
self.filterForm.setRowStretch(5, 1)
|
self.filterForm.setRowStretch(5, 1)
|
||||||
|
|
||||||
|
# Settings
|
||||||
|
self.histMax = QSpinBox(self)
|
||||||
|
self.histMax.setMinimum(100)
|
||||||
|
self.histMax.setMaximum(100000)
|
||||||
|
self.histMax.setSingleStep(100)
|
||||||
|
self.histMax.setValue(
|
||||||
|
self.optState.getInt("GuiWritingStats", "histMax", 2000)
|
||||||
|
)
|
||||||
|
self.histMax.valueChanged.connect(self._updateListBox)
|
||||||
|
|
||||||
|
self.optsBox = QHBoxLayout()
|
||||||
|
self.optsBox.addStretch(1)
|
||||||
|
self.optsBox.addWidget(QLabel("Word count cap for the histogram"), 0)
|
||||||
|
self.optsBox.addWidget(self.histMax, 0)
|
||||||
|
|
||||||
# Buttons
|
# Buttons
|
||||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
|
self.buttonBox = QDialogButtonBox()
|
||||||
self.buttonBox.rejected.connect(self._doClose)
|
self.buttonBox.rejected.connect(self._doClose)
|
||||||
|
|
||||||
|
self.btnClose = self.buttonBox.addButton(QDialogButtonBox.Close)
|
||||||
|
self.btnClose.setAutoDefault(False)
|
||||||
|
|
||||||
self.btnSave = self.buttonBox.addButton("Save As", QDialogButtonBox.ActionRole)
|
self.btnSave = self.buttonBox.addButton("Save As", QDialogButtonBox.ActionRole)
|
||||||
|
self.btnSave.setAutoDefault(False)
|
||||||
|
|
||||||
self.saveMenu = QMenu(self)
|
self.saveMenu = QMenu(self)
|
||||||
self.btnSave.setMenu(self.saveMenu)
|
self.btnSave.setMenu(self.saveMenu)
|
||||||
|
|
||||||
@@ -226,9 +246,10 @@ class GuiWritingStats(QDialog):
|
|||||||
# Assemble
|
# Assemble
|
||||||
self.outerBox = QGridLayout()
|
self.outerBox = QGridLayout()
|
||||||
self.outerBox.addWidget(self.listBox, 0, 0, 1, 2)
|
self.outerBox.addWidget(self.listBox, 0, 0, 1, 2)
|
||||||
self.outerBox.addWidget(self.infoBox, 1, 0)
|
self.outerBox.addLayout(self.optsBox, 1, 0, 1, 2)
|
||||||
self.outerBox.addWidget(self.filterBox, 1, 1)
|
self.outerBox.addWidget(self.infoBox, 2, 0)
|
||||||
self.outerBox.addWidget(self.buttonBox, 2, 0, 1, 2)
|
self.outerBox.addWidget(self.filterBox, 2, 1)
|
||||||
|
self.outerBox.addWidget(self.buttonBox, 3, 0, 1, 2)
|
||||||
self.outerBox.setRowStretch(0, 1)
|
self.outerBox.setRowStretch(0, 1)
|
||||||
|
|
||||||
self.setLayout(self.outerBox)
|
self.setLayout(self.outerBox)
|
||||||
@@ -262,6 +283,7 @@ class GuiWritingStats(QDialog):
|
|||||||
hideZeros = self.hideZeros.isChecked()
|
hideZeros = self.hideZeros.isChecked()
|
||||||
hideNegative = self.hideNegative.isChecked()
|
hideNegative = self.hideNegative.isChecked()
|
||||||
groupByDay = self.groupByDay.isChecked()
|
groupByDay = self.groupByDay.isChecked()
|
||||||
|
histMax = self.histMax.value()
|
||||||
|
|
||||||
self.optState.setValue("GuiWritingStats", "winWidth", winWidth)
|
self.optState.setValue("GuiWritingStats", "winWidth", winWidth)
|
||||||
self.optState.setValue("GuiWritingStats", "winHeight", winHeight)
|
self.optState.setValue("GuiWritingStats", "winHeight", winHeight)
|
||||||
@@ -275,6 +297,7 @@ class GuiWritingStats(QDialog):
|
|||||||
self.optState.setValue("GuiWritingStats", "hideZeros", hideZeros)
|
self.optState.setValue("GuiWritingStats", "hideZeros", hideZeros)
|
||||||
self.optState.setValue("GuiWritingStats", "hideNegative", hideNegative)
|
self.optState.setValue("GuiWritingStats", "hideNegative", hideNegative)
|
||||||
self.optState.setValue("GuiWritingStats", "groupByDay", groupByDay)
|
self.optState.setValue("GuiWritingStats", "groupByDay", groupByDay)
|
||||||
|
self.optState.setValue("GuiWritingStats", "histMax", histMax)
|
||||||
|
|
||||||
self.optState.saveSettings()
|
self.optState.saveSettings()
|
||||||
self.close()
|
self.close()
|
||||||
@@ -438,8 +461,10 @@ class GuiWritingStats(QDialog):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _updateListBox(self):
|
def _updateListBox(self, dummyVar=None):
|
||||||
"""Load/reload the content of the list box.
|
"""Load/reload the content of the list box. The dummyVar
|
||||||
|
variable captures the variable sent from the widgets connecting
|
||||||
|
to it and discards it.
|
||||||
"""
|
"""
|
||||||
self.listBox.clear()
|
self.listBox.clear()
|
||||||
self.timeFilter = 0.0
|
self.timeFilter = 0.0
|
||||||
@@ -449,6 +474,7 @@ class GuiWritingStats(QDialog):
|
|||||||
hideZeros = self.hideZeros.isChecked()
|
hideZeros = self.hideZeros.isChecked()
|
||||||
hideNegative = self.hideNegative.isChecked()
|
hideNegative = self.hideNegative.isChecked()
|
||||||
groupByDay = self.groupByDay.isChecked()
|
groupByDay = self.groupByDay.isChecked()
|
||||||
|
histMax = self.histMax.value()
|
||||||
|
|
||||||
# Group the data
|
# Group the data
|
||||||
if groupByDay:
|
if groupByDay:
|
||||||
@@ -509,7 +535,7 @@ class GuiWritingStats(QDialog):
|
|||||||
sStart = dStart.strftime(nwConst.tStampFmt)
|
sStart = dStart.strftime(nwConst.tStampFmt)
|
||||||
|
|
||||||
self.filterData.append((dStart, sStart, sDiff, dwTotal, wcNovel, wcNotes))
|
self.filterData.append((dStart, sStart, sDiff, dwTotal, wcNovel, wcNotes))
|
||||||
listMax = max(listMax, dwTotal)
|
listMax = min(max(listMax, dwTotal), histMax)
|
||||||
pcTotal = wcTotal
|
pcTotal = wcTotal
|
||||||
|
|
||||||
# Populate the list
|
# Populate the list
|
||||||
@@ -522,7 +548,7 @@ class GuiWritingStats(QDialog):
|
|||||||
|
|
||||||
if nWords > 0 and listMax > 0:
|
if nWords > 0 and listMax > 0:
|
||||||
theBar = self.barImage.scaled(
|
theBar = self.barImage.scaled(
|
||||||
int(200*nWords/listMax),
|
int(200*min(nWords, histMax)/listMax),
|
||||||
self.barHeight,
|
self.barHeight,
|
||||||
Qt.IgnoreAspectRatio,
|
Qt.IgnoreAspectRatio,
|
||||||
Qt.FastTransformation
|
Qt.FastTransformation
|
||||||
|
|||||||
Reference in New Issue
Block a user