Brand new session stats log with saved counts for novel and notes seperately, and new parsing code
This commit is contained in:
@@ -51,7 +51,7 @@ class nwFiles():
|
|||||||
PROJ_LOCK = "nwProject.lock"
|
PROJ_LOCK = "nwProject.lock"
|
||||||
TOC_TXT = "ToC.txt"
|
TOC_TXT = "ToC.txt"
|
||||||
TOC_JSON = "ToC.json"
|
TOC_JSON = "ToC.json"
|
||||||
SESS_INFO = "sessionInfo.log"
|
SESS_STATS = "sessionStats.log"
|
||||||
INDEX_FILE = "tagsIndex.json"
|
INDEX_FILE = "tagsIndex.json"
|
||||||
OPTS_FILE = "guiOptions.json"
|
OPTS_FILE = "guiOptions.json"
|
||||||
RECENT_FILE = "recentProjects.json"
|
RECENT_FILE = "recentProjects.json"
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ class OptionState():
|
|||||||
"widthCol2",
|
"widthCol2",
|
||||||
"sortCol",
|
"sortCol",
|
||||||
"sortOrder",
|
"sortOrder",
|
||||||
|
"incNovel",
|
||||||
|
"incNotes",
|
||||||
"hideZeros",
|
"hideZeros",
|
||||||
"hideNegative",
|
"hideNegative",
|
||||||
"groupByDay",
|
"groupByDay",
|
||||||
|
|||||||
+28
-10
@@ -93,6 +93,8 @@ class NWProject():
|
|||||||
self.lastViewed = None # The handle of the last file to be viewed
|
self.lastViewed = None # The handle of the last file to be viewed
|
||||||
self.lastWCount = 0 # The project word count from last session
|
self.lastWCount = 0 # The project word count from last session
|
||||||
self.currWCount = 0 # The project word count in current session
|
self.currWCount = 0 # The project word count in current session
|
||||||
|
self.novelWCount = 0 # Total number of words in novel files
|
||||||
|
self.notesWCount = 0 # Total number of words in note files
|
||||||
self.doBackup = True # Run project backup on exit
|
self.doBackup = True # Run project backup on exit
|
||||||
|
|
||||||
# Set Defaults
|
# Set Defaults
|
||||||
@@ -231,6 +233,8 @@ class NWProject():
|
|||||||
self.lastViewed = None
|
self.lastViewed = None
|
||||||
self.lastWCount = 0
|
self.lastWCount = 0
|
||||||
self.currWCount = 0
|
self.currWCount = 0
|
||||||
|
self.novelWCount = 0
|
||||||
|
self.notesWCount = 0
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -435,6 +439,10 @@ class NWProject():
|
|||||||
self.lastViewed = checkString(xItem.text, None, True)
|
self.lastViewed = checkString(xItem.text, None, True)
|
||||||
elif xItem.tag == "lastWordCount":
|
elif xItem.tag == "lastWordCount":
|
||||||
self.lastWCount = checkInt(xItem.text, 0, False)
|
self.lastWCount = checkInt(xItem.text, 0, False)
|
||||||
|
elif xItem.tag == "novelWordCount":
|
||||||
|
self.novelWCount = checkInt(xItem.text, 0, False)
|
||||||
|
elif xItem.tag == "notesWordCount":
|
||||||
|
self.notesWCount = checkInt(xItem.text, 0, False)
|
||||||
elif xItem.tag == "status":
|
elif xItem.tag == "status":
|
||||||
self.statusItems.unpackEntries(xItem)
|
self.statusItems.unpackEntries(xItem)
|
||||||
elif xItem.tag == "importance":
|
elif xItem.tag == "importance":
|
||||||
@@ -501,6 +509,10 @@ class NWProject():
|
|||||||
})
|
})
|
||||||
|
|
||||||
editTime = int(self.editTime + saveTime - self.projOpened)
|
editTime = int(self.editTime + saveTime - self.projOpened)
|
||||||
|
wcNovel, wcNotes = self.projTree.sumWords()
|
||||||
|
self.novelWCount = wcNovel
|
||||||
|
self.notesWCount = wcNotes
|
||||||
|
self.setProjectWordCount(wcNovel + wcNotes)
|
||||||
|
|
||||||
# Save Project Meta
|
# Save Project Meta
|
||||||
xProject = etree.SubElement(nwXML, "project")
|
xProject = etree.SubElement(nwXML, "project")
|
||||||
@@ -519,6 +531,8 @@ class NWProject():
|
|||||||
self._packProjectValue(xSettings, "lastEdited", self.lastEdited)
|
self._packProjectValue(xSettings, "lastEdited", self.lastEdited)
|
||||||
self._packProjectValue(xSettings, "lastViewed", self.lastViewed)
|
self._packProjectValue(xSettings, "lastViewed", self.lastViewed)
|
||||||
self._packProjectValue(xSettings, "lastWordCount", self.currWCount)
|
self._packProjectValue(xSettings, "lastWordCount", self.currWCount)
|
||||||
|
self._packProjectValue(xSettings, "novelWordCount", wcNovel)
|
||||||
|
self._packProjectValue(xSettings, "notesWordCount", wcNotes)
|
||||||
|
|
||||||
xAutoRep = etree.SubElement(xSettings, "autoReplace")
|
xAutoRep = etree.SubElement(xSettings, "autoReplace")
|
||||||
for aKey, aValue in self.autoReplace.items():
|
for aKey, aValue in self.autoReplace.items():
|
||||||
@@ -1101,18 +1115,22 @@ class NWProject():
|
|||||||
if not self.ensureFolderStructure():
|
if not self.ensureFolderStructure():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
sessionFile = path.join(self.projMeta, nwFiles.SESS_INFO)
|
sessionFile = path.join(self.projMeta, nwFiles.SESS_STATS)
|
||||||
|
isFile = path.isfile(sessionFile)
|
||||||
|
|
||||||
with open(sessionFile, mode="a+", encoding="utf8") as outFile:
|
with open(sessionFile, mode="a+", encoding="utf8") as outFile:
|
||||||
print((
|
if not isFile:
|
||||||
"Start: {opened:s} "
|
# It's a new file, so add a header
|
||||||
"End: {closed:s} "
|
outFile.write("# Initial: %d\n# %-17s %-19s %8s %8s\n" % (
|
||||||
"Words: {words:8d}"
|
self.lastWCount, "Start Time", "End Time", "Novel", "Notes"
|
||||||
).format(
|
))
|
||||||
opened = formatTimeStamp(self.projOpened),
|
|
||||||
closed = formatTimeStamp(time()),
|
outFile.write("%-19s %-19s %8d %8d\n" % (
|
||||||
words = self.getSessionWordCount(),
|
formatTimeStamp(self.projOpened),
|
||||||
), file=outFile)
|
formatTimeStamp(time()),
|
||||||
|
self.novelWCount,
|
||||||
|
self.notesWCount,
|
||||||
|
))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
+18
-1
@@ -36,7 +36,7 @@ from time import time
|
|||||||
|
|
||||||
from nw.core.item import NWItem
|
from nw.core.item import NWItem
|
||||||
from nw.common import checkString
|
from nw.common import checkString
|
||||||
from nw.constants import nwFiles, nwItemType, nwItemClass
|
from nw.constants import nwFiles, nwItemType, nwItemClass, nwItemLayout
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -182,6 +182,23 @@ class NWTree():
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def sumWords(self):
|
||||||
|
"""Loops over all entries and adds up the word counts.
|
||||||
|
"""
|
||||||
|
noteWords = 0
|
||||||
|
novelWords = 0
|
||||||
|
for tHandle in self._treeOrder:
|
||||||
|
tItem = self.__getitem__(tHandle)
|
||||||
|
if tItem is None:
|
||||||
|
continue
|
||||||
|
if tItem.itemLayout == nwItemLayout.NO_LAYOUT:
|
||||||
|
pass
|
||||||
|
elif tItem.itemLayout == nwItemLayout.NOTE:
|
||||||
|
noteWords += tItem.wordCount
|
||||||
|
else:
|
||||||
|
novelWords += tItem.wordCount
|
||||||
|
return novelWords, noteWords
|
||||||
|
|
||||||
##
|
##
|
||||||
# Tree Structure Methods
|
# Tree Structure Methods
|
||||||
##
|
##
|
||||||
|
|||||||
+134
-47
@@ -64,7 +64,7 @@ class GuiSessionLog(QDialog):
|
|||||||
self.logData = []
|
self.logData = []
|
||||||
self.timeFilter = 0.0
|
self.timeFilter = 0.0
|
||||||
self.timeTotal = 0.0
|
self.timeTotal = 0.0
|
||||||
self.maxWords = 0
|
self.wordOffset = 0
|
||||||
|
|
||||||
self.setWindowTitle("Session Log")
|
self.setWindowTitle("Session Log")
|
||||||
self.setMinimumWidth(self.mainConf.pxInt(420))
|
self.setMinimumWidth(self.mainConf.pxInt(420))
|
||||||
@@ -114,6 +114,7 @@ class GuiSessionLog(QDialog):
|
|||||||
|
|
||||||
# Word Bar
|
# Word Bar
|
||||||
self.barHeight = int(round(0.5*self.theTheme.fontPixelSize))
|
self.barHeight = int(round(0.5*self.theTheme.fontPixelSize))
|
||||||
|
self.barWidth = self.mainConf.pxInt(200)
|
||||||
self.barImage = QPixmap(self.barHeight, self.barHeight)
|
self.barImage = QPixmap(self.barHeight, self.barHeight)
|
||||||
self.barImage.fill(self.palette().highlight().color())
|
self.barImage.fill(self.palette().highlight().color())
|
||||||
|
|
||||||
@@ -130,11 +131,29 @@ class GuiSessionLog(QDialog):
|
|||||||
self.labelFilter.setFont(self.monoFont)
|
self.labelFilter.setFont(self.monoFont)
|
||||||
self.labelFilter.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
|
self.labelFilter.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
|
||||||
|
|
||||||
self.infoForm.addWidget(QLabel("Total Time:"), 0, 0)
|
self.novelWords = QLabel("0")
|
||||||
self.infoForm.addWidget(self.labelTotal, 0, 1)
|
self.novelWords.setFont(self.monoFont)
|
||||||
self.infoForm.addWidget(QLabel("Filtered Time:"), 1, 0)
|
self.novelWords.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
|
||||||
self.infoForm.addWidget(self.labelFilter, 1, 1)
|
|
||||||
self.infoForm.setRowStretch(2, 1)
|
self.notesWords = QLabel("0")
|
||||||
|
self.notesWords.setFont(self.monoFont)
|
||||||
|
self.notesWords.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
|
||||||
|
|
||||||
|
self.totalWords = QLabel("0")
|
||||||
|
self.totalWords.setFont(self.monoFont)
|
||||||
|
self.totalWords.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
|
||||||
|
|
||||||
|
self.infoForm.addWidget(QLabel("Total Time:"), 0, 0)
|
||||||
|
self.infoForm.addWidget(self.labelTotal, 0, 1)
|
||||||
|
self.infoForm.addWidget(QLabel("Filtered Time:"), 1, 0)
|
||||||
|
self.infoForm.addWidget(self.labelFilter, 1, 1)
|
||||||
|
self.infoForm.addWidget(QLabel("Novel Word Count:"), 2, 0)
|
||||||
|
self.infoForm.addWidget(self.novelWords, 2, 1)
|
||||||
|
self.infoForm.addWidget(QLabel("Notes Word Count:"), 3, 0)
|
||||||
|
self.infoForm.addWidget(self.notesWords, 3, 1)
|
||||||
|
self.infoForm.addWidget(QLabel("Total Word Count:"), 4, 0)
|
||||||
|
self.infoForm.addWidget(self.totalWords, 4, 1)
|
||||||
|
self.infoForm.setRowStretch(5, 1)
|
||||||
|
|
||||||
# Filter Options
|
# Filter Options
|
||||||
sPx = self.theTheme.baseIconSize
|
sPx = self.theTheme.baseIconSize
|
||||||
@@ -143,6 +162,20 @@ class GuiSessionLog(QDialog):
|
|||||||
self.filterForm = QGridLayout(self)
|
self.filterForm = QGridLayout(self)
|
||||||
self.filterBox.setLayout(self.filterForm)
|
self.filterBox.setLayout(self.filterForm)
|
||||||
|
|
||||||
|
self.labelNovel = QLabel("Count novel files")
|
||||||
|
self.incNovel = QSwitch(width=2*sPx, height=sPx)
|
||||||
|
self.incNovel.setChecked(
|
||||||
|
self.optState.getBool("GuiSessionLog", "incNovel", True)
|
||||||
|
)
|
||||||
|
self.incNovel.clicked.connect(self._updateListBox)
|
||||||
|
|
||||||
|
self.labelNotes = QLabel("Count note files")
|
||||||
|
self.incNotes = QSwitch(width=2*sPx, height=sPx)
|
||||||
|
self.incNotes.setChecked(
|
||||||
|
self.optState.getBool("GuiSessionLog", "incNotes", True)
|
||||||
|
)
|
||||||
|
self.incNotes.clicked.connect(self._updateListBox)
|
||||||
|
|
||||||
self.labelZeros = QLabel("Hide zero word count")
|
self.labelZeros = QLabel("Hide zero word count")
|
||||||
self.hideZeros = QSwitch(width=2*sPx, height=sPx)
|
self.hideZeros = QSwitch(width=2*sPx, height=sPx)
|
||||||
self.hideZeros.setChecked(
|
self.hideZeros.setChecked(
|
||||||
@@ -164,12 +197,16 @@ class GuiSessionLog(QDialog):
|
|||||||
)
|
)
|
||||||
self.groupByDay.clicked.connect(self._updateListBox)
|
self.groupByDay.clicked.connect(self._updateListBox)
|
||||||
|
|
||||||
self.filterForm.addWidget(self.labelZeros, 0, 0)
|
self.filterForm.addWidget(self.labelNovel, 0, 0)
|
||||||
self.filterForm.addWidget(self.hideZeros, 0, 1)
|
self.filterForm.addWidget(self.incNovel, 0, 1)
|
||||||
self.filterForm.addWidget(self.labelNegative, 1, 0)
|
self.filterForm.addWidget(self.labelNotes, 1, 0)
|
||||||
self.filterForm.addWidget(self.hideNegative, 1, 1)
|
self.filterForm.addWidget(self.incNotes, 1, 1)
|
||||||
self.filterForm.addWidget(self.labelByDay, 2, 0)
|
self.filterForm.addWidget(self.labelZeros, 2, 0)
|
||||||
self.filterForm.addWidget(self.groupByDay, 2, 1)
|
self.filterForm.addWidget(self.hideZeros, 2, 1)
|
||||||
|
self.filterForm.addWidget(self.labelNegative, 3, 0)
|
||||||
|
self.filterForm.addWidget(self.hideNegative, 3, 1)
|
||||||
|
self.filterForm.addWidget(self.labelByDay, 4, 0)
|
||||||
|
self.filterForm.addWidget(self.groupByDay, 4, 1)
|
||||||
|
|
||||||
# Buttons
|
# Buttons
|
||||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
|
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
|
||||||
@@ -209,6 +246,8 @@ class GuiSessionLog(QDialog):
|
|||||||
widthCol2 = self.mainConf.rpxInt(self.listBox.columnWidth(2))
|
widthCol2 = self.mainConf.rpxInt(self.listBox.columnWidth(2))
|
||||||
sortCol = self.listBox.sortColumn()
|
sortCol = self.listBox.sortColumn()
|
||||||
sortOrder = self.listBox.header().sortIndicatorOrder()
|
sortOrder = self.listBox.header().sortIndicatorOrder()
|
||||||
|
incNovel = self.incNovel.isChecked()
|
||||||
|
incNotes = self.incNotes.isChecked()
|
||||||
hideZeros = self.hideZeros.isChecked()
|
hideZeros = self.hideZeros.isChecked()
|
||||||
hideNegative = self.hideNegative.isChecked()
|
hideNegative = self.hideNegative.isChecked()
|
||||||
groupByDay = self.groupByDay.isChecked()
|
groupByDay = self.groupByDay.isChecked()
|
||||||
@@ -220,6 +259,8 @@ class GuiSessionLog(QDialog):
|
|||||||
self.optState.setValue("GuiSessionLog", "widthCol2", widthCol2)
|
self.optState.setValue("GuiSessionLog", "widthCol2", widthCol2)
|
||||||
self.optState.setValue("GuiSessionLog", "sortCol", sortCol)
|
self.optState.setValue("GuiSessionLog", "sortCol", sortCol)
|
||||||
self.optState.setValue("GuiSessionLog", "sortOrder", sortOrder)
|
self.optState.setValue("GuiSessionLog", "sortOrder", sortOrder)
|
||||||
|
self.optState.setValue("GuiSessionLog", "incNovel", incNovel)
|
||||||
|
self.optState.setValue("GuiSessionLog", "incNotes", incNotes)
|
||||||
self.optState.setValue("GuiSessionLog", "hideZeros", hideZeros)
|
self.optState.setValue("GuiSessionLog", "hideZeros", hideZeros)
|
||||||
self.optState.setValue("GuiSessionLog", "hideNegative", hideNegative)
|
self.optState.setValue("GuiSessionLog", "hideNegative", hideNegative)
|
||||||
self.optState.setValue("GuiSessionLog", "groupByDay", groupByDay)
|
self.optState.setValue("GuiSessionLog", "groupByDay", groupByDay)
|
||||||
@@ -239,29 +280,55 @@ class GuiSessionLog(QDialog):
|
|||||||
self.logData = []
|
self.logData = []
|
||||||
logger.debug("Loading session log file")
|
logger.debug("Loading session log file")
|
||||||
|
|
||||||
|
ttNovel = 0
|
||||||
|
ttNotes = 0
|
||||||
|
|
||||||
|
isFirst = True
|
||||||
|
osNovel = 0
|
||||||
|
osNotes = 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logFile = path.join(self.theProject.projMeta, nwFiles.SESS_INFO)
|
logFile = path.join(self.theProject.projMeta, nwFiles.SESS_STATS)
|
||||||
with open(logFile, mode="r", encoding="utf8") as inFile:
|
with open(logFile, mode="r", encoding="utf8") as inFile:
|
||||||
for inLine in inFile:
|
for inLine in inFile:
|
||||||
|
if inLine.startswith("#"):
|
||||||
|
if inLine.startswith("# Initial:"):
|
||||||
|
self.wordOffset = int(inLine[11:].strip())
|
||||||
|
logger.verbose(
|
||||||
|
"Initial word count when log was started is %d" % self.wordOffset
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
inData = inLine.split()
|
inData = inLine.split()
|
||||||
if len(inData) != 8:
|
if len(inData) != 6:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
dStart = datetime.strptime(
|
dStart = datetime.strptime(
|
||||||
"%s %s" % (inData[1], inData[2]), nwConst.tStampFmt
|
"%s %s" % (inData[0], inData[1]), nwConst.tStampFmt
|
||||||
)
|
)
|
||||||
dEnd = datetime.strptime(
|
dEnd = datetime.strptime(
|
||||||
"%s %s" % (inData[4], inData[5]), nwConst.tStampFmt
|
"%s %s" % (inData[2], inData[3]), nwConst.tStampFmt
|
||||||
)
|
)
|
||||||
|
|
||||||
nWords = int(inData[7])
|
|
||||||
tDiff = dEnd - dStart
|
tDiff = dEnd - dStart
|
||||||
sDiff = tDiff.total_seconds()
|
sDiff = tDiff.total_seconds()
|
||||||
self.timeTotal += sDiff
|
self.timeTotal += sDiff
|
||||||
|
|
||||||
self.logData.append((dStart, sDiff, nWords))
|
wcNovel = int(inData[4])
|
||||||
self.maxWords = max(self.maxWords, nWords)
|
wcNotes = int(inData[5])
|
||||||
|
ttNovel = wcNovel
|
||||||
|
ttNotes = wcNotes
|
||||||
|
|
||||||
|
if isFirst:
|
||||||
|
isFirst = False
|
||||||
|
if self.wordOffset > 0:
|
||||||
|
# First entry is used as the reference word
|
||||||
|
# count, and the data is then discarded.
|
||||||
|
osNovel = wcNovel
|
||||||
|
osNotes = wcNotes
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.logData.append((dStart, sDiff, wcNovel-osNovel, wcNotes-osNotes))
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.theParent.makeAlert(
|
self.theParent.makeAlert(
|
||||||
@@ -270,6 +337,9 @@ class GuiSessionLog(QDialog):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
self.labelTotal.setText(self._formatTime(self.timeTotal))
|
self.labelTotal.setText(self._formatTime(self.timeTotal))
|
||||||
|
self.novelWords.setText("{:n}".format(ttNovel))
|
||||||
|
self.notesWords.setText("{:n}".format(ttNotes))
|
||||||
|
self.totalWords.setText("{:n}".format(ttNovel + ttNotes))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -279,49 +349,65 @@ class GuiSessionLog(QDialog):
|
|||||||
self.listBox.clear()
|
self.listBox.clear()
|
||||||
self.timeFilter = 0.0
|
self.timeFilter = 0.0
|
||||||
|
|
||||||
|
incNovel = self.incNovel.isChecked()
|
||||||
|
incNotes = self.incNotes.isChecked()
|
||||||
hideZeros = self.hideZeros.isChecked()
|
hideZeros = self.hideZeros.isChecked()
|
||||||
hideNegative = self.hideNegative.isChecked()
|
hideNegative = self.hideNegative.isChecked()
|
||||||
groupByDay = self.groupByDay.isChecked()
|
groupByDay = self.groupByDay.isChecked()
|
||||||
|
|
||||||
# Group the data
|
# Group the data
|
||||||
if groupByDay:
|
if groupByDay:
|
||||||
listData = []
|
tempData = []
|
||||||
listMax = 0
|
sessDate = None
|
||||||
|
sessTime = 0
|
||||||
|
lstNovel = 0
|
||||||
|
lstNotes = 0
|
||||||
|
|
||||||
dayDate = None
|
for n, (dStart, sDiff, wcNovel, wcNotes) in enumerate(self.logData):
|
||||||
daySDiff = 0
|
|
||||||
dayWords = 0
|
|
||||||
|
|
||||||
for n, (dStart, sDiff, nWords) in enumerate(self.logData):
|
|
||||||
if n == 0:
|
if n == 0:
|
||||||
dayDate = dStart.date()
|
sessDate = dStart.date()
|
||||||
if dayDate != dStart.date():
|
if sessDate != dStart.date():
|
||||||
listData.append((dayDate, daySDiff, dayWords))
|
tempData.append((sessDate, sessTime, lstNovel, lstNotes))
|
||||||
listMax = max(listMax, dayWords)
|
sessDate = dStart.date()
|
||||||
dayDate = dStart.date()
|
sessTime = sDiff
|
||||||
daySDiff = sDiff
|
lstNovel = wcNovel
|
||||||
dayWords = nWords
|
lstNotes = wcNotes
|
||||||
else:
|
else:
|
||||||
daySDiff += sDiff
|
sessTime += sDiff
|
||||||
dayWords += nWords
|
lstNovel = wcNovel
|
||||||
|
lstNotes = wcNotes
|
||||||
|
|
||||||
if dayDate is not None:
|
if sessDate is not None:
|
||||||
listData.append((dayDate, daySDiff, dayWords))
|
tempData.append((sessDate, sessTime, lstNovel, lstNotes))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
listData = self.logData
|
tempData = self.logData
|
||||||
listMax = self.maxWords
|
|
||||||
|
# Calculate Word Diff
|
||||||
|
listData = []
|
||||||
|
pcTotal = 0
|
||||||
|
listMax = 0
|
||||||
|
for dStart, sDiff, wcNovel, wcNotes in tempData:
|
||||||
|
|
||||||
|
wcTotal = 0
|
||||||
|
if incNovel:
|
||||||
|
wcTotal += wcNovel
|
||||||
|
if incNotes:
|
||||||
|
wcTotal += wcNotes
|
||||||
|
|
||||||
|
dwTotal = wcTotal - pcTotal
|
||||||
|
if hideZeros and dwTotal == 0:
|
||||||
|
continue
|
||||||
|
if hideNegative and dwTotal < 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
listData.append((dStart, sDiff, dwTotal))
|
||||||
|
listMax = max(listMax, dwTotal)
|
||||||
|
pcTotal = wcTotal
|
||||||
|
|
||||||
# Populate the list
|
# Populate the list
|
||||||
for dStart, sDiff, nWords in listData:
|
for dStart, sDiff, nWords in listData:
|
||||||
|
|
||||||
if hideZeros and nWords == 0:
|
|
||||||
continue
|
|
||||||
if hideNegative and nWords < 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.timeFilter += sDiff
|
|
||||||
|
|
||||||
if groupByDay:
|
if groupByDay:
|
||||||
sStart = dStart.strftime(nwConst.dStampFmt)
|
sStart = dStart.strftime(nwConst.dStampFmt)
|
||||||
else:
|
else:
|
||||||
@@ -332,7 +418,7 @@ class GuiSessionLog(QDialog):
|
|||||||
newItem.setText(self.C_LENGTH, self._formatTime(sDiff))
|
newItem.setText(self.C_LENGTH, self._formatTime(sDiff))
|
||||||
newItem.setText(self.C_COUNT, str(nWords))
|
newItem.setText(self.C_COUNT, str(nWords))
|
||||||
|
|
||||||
if nWords > 0:
|
if nWords > 0 and listMax > 0:
|
||||||
theBar = self.barImage.scaled(
|
theBar = self.barImage.scaled(
|
||||||
int(200*nWords/listMax),
|
int(200*nWords/listMax),
|
||||||
self.barHeight,
|
self.barHeight,
|
||||||
@@ -350,6 +436,7 @@ class GuiSessionLog(QDialog):
|
|||||||
newItem.setFont(self.C_COUNT, self.monoFont)
|
newItem.setFont(self.C_COUNT, self.monoFont)
|
||||||
|
|
||||||
self.listBox.addTopLevelItem(newItem)
|
self.listBox.addTopLevelItem(newItem)
|
||||||
|
self.timeFilter += sDiff
|
||||||
|
|
||||||
self.labelFilter.setText(self._formatTime(self.timeFilter))
|
self.labelFilter.setText(self._formatTime(self.timeFilter))
|
||||||
|
|
||||||
|
|||||||
@@ -21,4 +21,4 @@ Thin spaces and thin non-breaking spaces are also supported from the Insert menu
|
|||||||
|
|
||||||
If you need to split a scene file up into further pieces, you can do so with the level four heading, like above. This is referred to as a section.
|
If you need to split a scene file up into further pieces, you can do so with the level four heading, like above. This is referred to as a section.
|
||||||
|
|
||||||
Both scene and section titles can be left out of the final exported document. The formatting of titles can be selected from the export dialog.
|
Both scene and section titles can be left out of the final exported document. The formatting of titles can be selected from the Build Novel Project dialog. You can also have them replaced with scene separators like “* * *”.
|
||||||
|
|||||||
+11
-9
@@ -1,21 +1,23 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<novelWriterXML appVersion="0.9.0rc1" hexVersion="0x000900c1" fileVersion="1.1" timeStamp="2020-06-19 19:50:54">
|
<novelWriterXML appVersion="0.10.0-rc1" hexVersion="0x001000c1" fileVersion="1.1" timeStamp="2020-06-25 21:09:22">
|
||||||
<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>407</saveCount>
|
<saveCount>565</saveCount>
|
||||||
<autoCount>71</autoCount>
|
<autoCount>99</autoCount>
|
||||||
<editTime>15118</editTime>
|
<editTime>23298</editTime>
|
||||||
</project>
|
</project>
|
||||||
<settings>
|
<settings>
|
||||||
<doBackup>False</doBackup>
|
<doBackup>False</doBackup>
|
||||||
<spellCheck>True</spellCheck>
|
<spellCheck>True</spellCheck>
|
||||||
<autoOutline>True</autoOutline>
|
<autoOutline>True</autoOutline>
|
||||||
<lastEdited>636b6aa9b697b</lastEdited>
|
<lastEdited>636b6aa9b697b</lastEdited>
|
||||||
<lastViewed>bb2c23b3c42cc</lastViewed>
|
<lastViewed>b3e74dbc1f584</lastViewed>
|
||||||
<lastWordCount>967</lastWordCount>
|
<lastWordCount>982</lastWordCount>
|
||||||
|
<novelWordCount>606</novelWordCount>
|
||||||
|
<notesWordCount>376</notesWordCount>
|
||||||
<autoReplace>
|
<autoReplace>
|
||||||
<A>B</A>
|
<A>B</A>
|
||||||
<B>E</B>
|
<B>E</B>
|
||||||
@@ -114,10 +116,10 @@
|
|||||||
<status>1st Draft</status>
|
<status>1st Draft</status>
|
||||||
<exported>True</exported>
|
<exported>True</exported>
|
||||||
<layout>SCENE</layout>
|
<layout>SCENE</layout>
|
||||||
<charCount>1483</charCount>
|
<charCount>1564</charCount>
|
||||||
<wordCount>263</wordCount>
|
<wordCount>278</wordCount>
|
||||||
<paraCount>8</paraCount>
|
<paraCount>8</paraCount>
|
||||||
<cursorPos>1086</cursorPos>
|
<cursorPos>1633</cursorPos>
|
||||||
</item>
|
</item>
|
||||||
<item handle="bc0cbd2a407f3" order="2" parent="e7ded148d6e4a">
|
<item handle="bc0cbd2a407f3" order="2" parent="e7ded148d6e4a">
|
||||||
<name>Another Scene</name>
|
<name>Another Scene</name>
|
||||||
|
|||||||
Reference in New Issue
Block a user