Merge branch 'main' into doc_meta

This commit is contained in:
Veronica K. B. Olsen
2020-10-24 18:32:49 +02:00
27 changed files with 118 additions and 94 deletions
+15 -4
View File
@@ -152,13 +152,13 @@ def formatInt(theInt):
theVal /= 1000.0 theVal /= 1000.0
if theVal < 1000.0: if theVal < 1000.0:
if theVal < 10.0: if theVal < 10.0:
return "%4.2f%s%s" % (theVal, nwUnicode.U_THNSP, pF) return f"{theVal:4.2f}{nwUnicode.U_THNSP}{pF}"
elif theVal < 100.0: elif theVal < 100.0:
return "%4.1f%s%s" % (theVal, nwUnicode.U_THNSP, pF) return f"{theVal:4.1f}{nwUnicode.U_THNSP}{pF}"
else: else:
return "%3.0f%s%s" % (theVal, nwUnicode.U_THNSP, pF) return f"{theVal:3.0f}{nwUnicode.U_THNSP}{pF}"
return "%d" % theInt return str(theInt)
def formatTimeStamp(theTime, fileSafe=False): def formatTimeStamp(theTime, fileSafe=False):
"""Take a number (on the format returned by time.time()) and convert """Take a number (on the format returned by time.time()) and convert
@@ -169,6 +169,17 @@ def formatTimeStamp(theTime, fileSafe=False):
else: else:
return datetime.fromtimestamp(theTime).strftime(nwConst.tStampFmt) return datetime.fromtimestamp(theTime).strftime(nwConst.tStampFmt)
def formatTime(tS):
"""Format a time in seconds in HH:MM:SS format or d-HH:MM:SS format
if a full day or longer.
"""
if isinstance(tS, int):
if tS >= 86400:
return f"{tS//86400:d}-{tS%86400//3600:02d}:{tS%3600//60:02d}:{tS%60:02d}"
else:
return f"{tS//3600:02d}:{tS%3600//60:02d}:{tS%60:02d}"
return "ERROR"
def splitVersionNumber(vString): def splitVersionNumber(vString):
""" Splits a version string on the form aa.bb.cc into major, minor """ Splits a version string on the form aa.bb.cc into major, minor
and patch, and computes an integer value aabbcc. and patch, and computes an integer value aabbcc.
+2 -2
View File
@@ -3,7 +3,7 @@
novelWriter Config Class novelWriter Config Class
============================ ============================
This class reads and store the main preferences of the application Class reading and holding the preferences of the application
File History: File History:
Created: 2018-09-22 [0.0.1] Created: 2018-09-22 [0.0.1]
@@ -911,7 +911,7 @@ class Config:
def _packList(self, inData): def _packList(self, inData):
"""Pack a list of items into a comma separated string. """Pack a list of items into a comma separated string.
""" """
return ", ".join(str(inVal) for inVal in inData) return ", ".join([str(inVal) for inVal in inData])
def _parseLine(self, cnfParse, cnfSec, cnfName, cnfType, cnfDefault): def _parseLine(self, cnfParse, cnfSec, cnfName, cnfType, cnfDefault):
"""Parse a line and return the correct datatype. """Parse a line and return the correct datatype.
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter Project Document novelWriter Project Document
================================ ================================
Class holding a document Class holding a single novelWriter document
File History: File History:
Created: 2018-09-29 [0.0.1] Created: 2018-09-29 [0.0.1]
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter Project Index novelWriter Project Index
============================= =============================
Class holding the index of tags Class holding the project index of tags, headers and references
File History: File History:
Created: 2019-05-27 [0.1.4] Created: 2019-05-27 [0.1.4]
+30 -20
View File
@@ -29,7 +29,7 @@ import logging
from lxml import etree from lxml import etree
from nw.common import checkInt from nw.common import checkInt, isHandle
from nw.constants import nwItemType, nwItemClass, nwItemLayout from nw.constants import nwItemType, nwItemClass, nwItemLayout
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -104,27 +104,37 @@ class NWItem():
if "parent" in xItem.attrib: if "parent" in xItem.attrib:
self.itemParent = xItem.attrib["parent"] self.itemParent = xItem.attrib["parent"]
setMap = { retStatus = True
"name" : self.setName,
"order" : self.setOrder,
"type" : self.setType,
"class" : self.setClass,
"layout" : self.setLayout,
"status" : self.setStatus,
"expanded" : self.setExpanded,
"exported" : self.setExported,
"charCount" : self.setCharCount,
"wordCount" : self.setWordCount,
"paraCount" : self.setParaCount,
"cursorPos" : self.setCursorPos,
}
for xValue in xItem: for xValue in xItem:
if xValue.tag in setMap: if xValue.tag == "name":
setMap[xValue.tag](xValue.text) self.setName(xValue.text)
elif xValue.tag == "order":
self.setOrder(xValue.text)
elif xValue.tag == "type":
self.setType(xValue.text)
elif xValue.tag == "class":
self.setClass(xValue.text)
elif xValue.tag == "layout":
self.setLayout(xValue.text)
elif xValue.tag == "status":
self.setStatus(xValue.text)
elif xValue.tag == "expanded":
self.setExpanded(xValue.text)
elif xValue.tag == "exported":
self.setExported(xValue.text)
elif xValue.tag == "charCount":
self.setCharCount(xValue.text)
elif xValue.tag == "wordCount":
self.setWordCount(xValue.text)
elif xValue.tag == "paraCount":
self.setParaCount(xValue.text)
elif xValue.tag == "cursorPos":
self.setCursorPos(xValue.text)
else: else:
logger.error("Unknown tag '%s'" % xValue.tag) logger.error("Unknown tag '%s'" % xValue.tag)
retStatus = False
return True return retStatus
@staticmethod @staticmethod
def _subPack(xParent, name, attrib=None, text=None, none=True): def _subPack(xParent, name, attrib=None, text=None, none=True):
@@ -153,7 +163,7 @@ class NWItem():
"""Set the item handle, and ensure it is valid. """Set the item handle, and ensure it is valid.
""" """
if isinstance(theHandle, str): if isinstance(theHandle, str):
if len(theHandle) == 13: if isHandle(theHandle):
self.itemHandle = theHandle self.itemHandle = theHandle
else: else:
self.itemHandle = None self.itemHandle = None
@@ -167,7 +177,7 @@ class NWItem():
if theParent is None: if theParent is None:
self.itemParent = None self.itemParent = None
elif isinstance(theParent, str): elif isinstance(theParent, str):
if len(theParent) == 13: if isHandle(theParent):
self.itemParent = theParent self.itemParent = theParent
else: else:
self.itemParent = None self.itemParent = None
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter Spell Check Classes novelWriter Spell Check Classes
=================================== ===================================
Wrapper class for spell checking Wrapper class for spell checking tools
File History: File History:
Created: 2019-06-11 [0.1.5] Created: 2019-06-11 [0.1.5]
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter Project Item Status Class novelWriter Project Item Status Class
========================================= =========================================
Class holding the status elements of a project item Class holding the status/importance elements of a project item
File History: File History:
Created: 2019-05-19 [0.1.3] Created: 2019-05-19 [0.1.3]
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter Text Tokenizer novelWriter Text Tokenizer
============================== ==============================
Splits a piece of nW markdown text into its elements Splits a piece of novelWriter markdown text into its elements
File History: File History:
Created: 2019-05-05 [0.0.1] Created: 2019-05-05 [0.0.1]
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter Project Tree Class novelWriter Project Tree Class
================================== ==================================
Class holding the data of the project tree Class holding the project's tree of project items
File History: File History:
Created: 2020-05-07 [0.4.5] Created: 2020-05-07 [0.4.5]
+6 -7
View File
@@ -55,14 +55,14 @@ class GuiAbout(QDialog):
self.innerBox = QHBoxLayout() self.innerBox = QHBoxLayout()
self.innerBox.setSpacing(self.mainConf.pxInt(16)) self.innerBox.setSpacing(self.mainConf.pxInt(16))
self.setWindowTitle("About %s" % self.mainConf.appName) self.setWindowTitle("About novelWriter")
self.setMinimumWidth(self.mainConf.pxInt(650)) self.setMinimumWidth(self.mainConf.pxInt(650))
self.setMinimumHeight(self.mainConf.pxInt(600)) self.setMinimumHeight(self.mainConf.pxInt(600))
nPx = self.mainConf.pxInt(96) nPx = self.mainConf.pxInt(96)
self.nwIcon = QLabel() self.nwIcon = QLabel()
self.nwIcon.setPixmap(self.theParent.theTheme.getPixmap("novelwriter", (nPx, nPx))) self.nwIcon.setPixmap(self.theParent.theTheme.getPixmap("novelwriter", (nPx, nPx)))
self.lblName = QLabel("<b>%s</b>" % self.mainConf.appName) self.lblName = QLabel("<b>novelWriter</b>")
self.lblVers = QLabel("v%s" % nw.__version__) self.lblVers = QLabel("v%s" % nw.__version__)
self.lblDate = QLabel(datetime.strptime(nw.__date__, "%Y-%m-%d").strftime("%x")) self.lblDate = QLabel(datetime.strptime(nw.__date__, "%Y-%m-%d").strftime("%x"))
@@ -115,17 +115,17 @@ class GuiAbout(QDialog):
""" """
listPrefix = "&nbsp;&nbsp;&bull;&nbsp;&nbsp;" listPrefix = "&nbsp;&nbsp;&bull;&nbsp;&nbsp;"
aboutMsg = ( aboutMsg = (
"<h2>About {name:s}</h2>" "<h2>About novelWriter</h2>"
"<p>{copyright:s}.</p>" "<p>{copyright:s}.</p>"
"<p>Website: <a href='{website:s}'>{domain:s}</a></p>" "<p>Website: <a href='{website:s}'>{domain:s}</a></p>"
"<p>{name:s} is a markdown-like text editor designed for " "<p>novelWriter is a markdown-like text editor designed for "
"organising and writing novels. It is written in Python 3 with a " "organising and writing novels. It is written in Python 3 with a "
"Qt5 GUI, using PyQt5.</p>" "Qt5 GUI, using PyQt5.</p>"
"<p>{name:s} is free software: you can redistribute it and/or " "<p>novelWriter is free software: you can redistribute it and/or "
"modify it under the terms of the GNU General Public License as " "modify it under the terms of the GNU General Public License as "
"published by the Free Software Foundation, either version 3 of " "published by the Free Software Foundation, either version 3 of "
"the License, or (at your option) any later version.</p>" "the License, or (at your option) any later version.</p>"
"<p>{name:s} is distributed in the hope that it will be useful, " "<p>novelWriter is distributed in the hope that it will be useful, "
"but WITHOUT ANY WARRANTY; without even the implied warranty of " "but WITHOUT ANY WARRANTY; without even the implied warranty of "
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p>" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p>"
"<p>See the License tab for the full text, or visit the GNU website " "<p>See the License tab for the full text, or visit the GNU website "
@@ -134,7 +134,6 @@ class GuiAbout(QDialog):
"<h3>Credits</h3>" "<h3>Credits</h3>"
"<p>{credits:s}</p>" "<p>{credits:s}</p>"
).format( ).format(
name = self.mainConf.appName,
copyright = nw.__copyright__, copyright = nw.__copyright__,
website = nw.__url__, website = nw.__url__,
domain = nw.__domain__, domain = nw.__domain__,
+8 -8
View File
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""novelWriter GUI Build Novel """novelWriter GUI Build Novel Project
novelWriter GUI Build Novel novelWriter GUI Build Novel Project
=============================== =======================================
Class holding the build novel window Class holding the build novel project dialog
File History: File History:
Created: 2020-05-09 [0.5] Created: 2020-05-09 [0.5]
@@ -391,11 +391,11 @@ class GuiBuildNovel(QDialog):
self.savePDF.triggered.connect(lambda: self._saveDocument(self.FMT_PDF)) self.savePDF.triggered.connect(lambda: self._saveDocument(self.FMT_PDF))
self.saveMenu.addAction(self.savePDF) self.saveMenu.addAction(self.savePDF)
self.saveHTM = QAction("%s HTML (.htm)" % self.mainConf.appName, self) self.saveHTM = QAction("novelWriter HTML (.htm)", self)
self.saveHTM.triggered.connect(lambda: self._saveDocument(self.FMT_HTM)) self.saveHTM.triggered.connect(lambda: self._saveDocument(self.FMT_HTM))
self.saveMenu.addAction(self.saveHTM) self.saveMenu.addAction(self.saveHTM)
self.saveNWD = QAction("%s Markdown (.nwd)" % self.mainConf.appName, self) self.saveNWD = QAction("novelWriter Markdown (.nwd)", self)
self.saveNWD.triggered.connect(lambda: self._saveDocument(self.FMT_NWD)) self.saveNWD.triggered.connect(lambda: self._saveDocument(self.FMT_NWD))
self.saveMenu.addAction(self.saveNWD) self.saveMenu.addAction(self.saveNWD)
@@ -408,11 +408,11 @@ class GuiBuildNovel(QDialog):
self.saveTXT.triggered.connect(lambda: self._saveDocument(self.FMT_TXT)) self.saveTXT.triggered.connect(lambda: self._saveDocument(self.FMT_TXT))
self.saveMenu.addAction(self.saveTXT) self.saveMenu.addAction(self.saveTXT)
self.saveJsonH = QAction("JSON + %s HTML (.json)" % self.mainConf.appName, self) self.saveJsonH = QAction("JSON + novelWriter HTML (.json)", self)
self.saveJsonH.triggered.connect(lambda: self._saveDocument(self.FMT_JSON_H)) self.saveJsonH.triggered.connect(lambda: self._saveDocument(self.FMT_JSON_H))
self.saveMenu.addAction(self.saveJsonH) self.saveMenu.addAction(self.saveJsonH)
self.saveJsonM = QAction("JSON + %s Markdown (.json)" % self.mainConf.appName, self) self.saveJsonM = QAction("JSON + novelWriters Markdown (.json)", self)
self.saveJsonM.triggered.connect(lambda: self._saveDocument(self.FMT_JSON_M)) self.saveJsonM.triggered.connect(lambda: self._saveDocument(self.FMT_JSON_M))
self.saveMenu.addAction(self.saveJsonM) self.saveMenu.addAction(self.saveJsonM)
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter GUI Document Editor novelWriter GUI Document Editor
=================================== ===================================
Class holding the document editor Class holding the main document editor
File History: File History:
Created: 2018-09-29 [0.0.1] GuiDocEditor Created: 2018-09-29 [0.0.1] GuiDocEditor
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter GUI Document Highlighter novelWriter GUI Document Highlighter
======================================== ========================================
Syntax highlighting for MarkDown Subclass for the main editor syntax highlighting
File History: File History:
Created: 2019-04-06 [0.0.1] Created: 2019-04-06 [0.0.1]
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter GUI Doc Merge novelWriter GUI Doc Merge
============================= =============================
Tool for merging multiple documents to one Tool for merging multiple documents to one document
File History: File History:
Created: 2020-01-23 [0.4.3] Created: 2020-01-23 [0.4.3]
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter GUI Document Viewer novelWriter GUI Document Viewer
=================================== ===================================
Class holding the document html viewer Class holding the main document viewer
File History: File History:
Created: 2019-05-10 [0.0.1] GuiDocViewer Created: 2019-05-10 [0.0.1] GuiDocViewer
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter GUI Document Details novelWriter GUI Document Details
==================================== ====================================
Class holding the left side document details panel Class holding the project tree item details panel
File History: File History:
Created: 2019-04-24 [0.0.1] Created: 2019-04-24 [0.0.1]
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter GUI Item Editor novelWriter GUI Item Editor
=============================== ===============================
Class holding the item editor Class holding the item editor dialog
File History: File History:
Created: 2019-04-27 [0.0.1] Created: 2019-04-27 [0.0.1]
+5 -5
View File
@@ -3,10 +3,10 @@
novelWriter GUI Main Menu novelWriter GUI Main Menu
============================= =============================
Class holding the main window Class holding the main window menu
File History: File History:
Created: 2019-04-27 [0.0.1] (Split from winmain) Created: 2019-04-27 [0.0.1]
This file is a part of novelWriter This file is a part of novelWriter
Copyright 20182020, Veronica Berglyd Olsen Copyright 20182020, Veronica Berglyd Olsen
@@ -274,7 +274,7 @@ class GuiMainMenu(QMenuBar):
# Project > Exit # Project > Exit
self.aExitNW = QAction("Exit", self) self.aExitNW = QAction("Exit", self)
self.aExitNW.setStatusTip("Exit %s" % self.mainConf.appName) self.aExitNW.setStatusTip("Exit novelWriter")
self.aExitNW.setShortcut("Ctrl+Q") self.aExitNW.setShortcut("Ctrl+Q")
self.aExitNW.setMenuRole(QAction.QuitRole) self.aExitNW.setMenuRole(QAction.QuitRole)
self.aExitNW.triggered.connect(lambda: self.theParent.closeMain()) self.aExitNW.triggered.connect(lambda: self.theParent.closeMain())
@@ -857,8 +857,8 @@ class GuiMainMenu(QMenuBar):
self.helpMenu = self.addMenu("&Help") self.helpMenu = self.addMenu("&Help")
# Help > About # Help > About
self.aAboutNW = QAction("About %s" % self.mainConf.appName, self) self.aAboutNW = QAction("About novelWriter", self)
self.aAboutNW.setStatusTip("About %s" % self.mainConf.appName) self.aAboutNW.setStatusTip("About novelWriter")
self.aAboutNW.setMenuRole(QAction.AboutRole) self.aAboutNW.setMenuRole(QAction.AboutRole)
self.aAboutNW.triggered.connect(lambda: self.theParent.showAboutNWDialog()) self.aAboutNW.triggered.connect(lambda: self.theParent.showAboutNWDialog())
self.helpMenu.addAction(self.aAboutNW) self.helpMenu.addAction(self.aAboutNW)
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter GUI Project Outline Details novelWriter GUI Project Outline Details
=========================================== ===========================================
Class holding the project outline details view Class holding the project outline details panel
File History: File History:
Created: 2020-06-02 [0.7.0] Created: 2020-06-02 [0.7.0]
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter GUI Open Project novelWriter GUI Open Project
================================ ================================
The open project dialog Class holding the load/browse/new project dialog
File History: File History:
Created: 2020-02-26 [0.4.5] Created: 2020-02-26 [0.4.5]
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter GUI project Tree novelWriter GUI project Tree
================================ ================================
Class holding the left side project tree view Class holding the project tree view
File History: File History:
Created: 2018-09-29 [0.0.1] GuiProjectTree Created: 2018-09-29 [0.0.1] GuiProjectTree
+2 -4
View File
@@ -35,6 +35,7 @@ from PyQt5.QtGui import QColor, QPainter
from PyQt5.QtWidgets import qApp, QStatusBar, QLabel, QAbstractButton from PyQt5.QtWidgets import qApp, QStatusBar, QLabel, QAbstractButton
from nw.core import NWSpellCheck from nw.core import NWSpellCheck
from nw.common import formatTime
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -206,10 +207,7 @@ class GuiMainStatus(QStatusBar):
if self.refTime is None: if self.refTime is None:
self.timeText.setText("00:00:00") self.timeText.setText("00:00:00")
else: else:
tS = int(time() - self.refTime) self.timeText.setText(formatTime(round(time() - self.refTime)))
self.timeText.setText(
f"{tS//3600:02d}:{tS%3600//60:02d}:{tS%60:02d}"
)
return return
# END Class GuiMainStatus # END Class GuiMainStatus
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter Theme and Icons Classs novelWriter Theme and Icons Classs
====================================== ======================================
This class reads and stores the themes and the icons Class managing and caching themes and icons
File History: File History:
Created: 2019-05-18 [0.1.3] GuiTheme Created: 2019-05-18 [0.1.3] GuiTheme
+12 -24
View File
@@ -3,7 +3,7 @@
novelWriter GUI Writing Statistics novelWriter GUI Writing Statistics
====================================== ======================================
Class showing the word count and session statistics Class holding the word count and session statistics dialog
File History: File History:
Created: 2019-10-20 [0.3] Created: 2019-10-20 [0.3]
@@ -39,6 +39,7 @@ from PyQt5.QtWidgets import (
QLabel, QGroupBox, QMenu, QAction, QFileDialog, QSpinBox, QHBoxLayout QLabel, QGroupBox, QMenu, QAction, QFileDialog, QSpinBox, QHBoxLayout
) )
from nw.common import formatTime
from nw.constants import nwConst, nwFiles, nwAlert from nw.constants import nwConst, nwFiles, nwAlert
from nw.gui.custom import QSwitch from nw.gui.custom import QSwitch
@@ -123,11 +124,11 @@ class GuiWritingStats(QDialog):
self.infoForm = QGridLayout(self) self.infoForm = QGridLayout(self)
self.infoBox.setLayout(self.infoForm) self.infoBox.setLayout(self.infoForm)
self.labelTotal = QLabel(self._formatTime(0)) self.labelTotal = QLabel(formatTime(0))
self.labelTotal.setFont(self.theTheme.guiFontFixed) self.labelTotal.setFont(self.theTheme.guiFontFixed)
self.labelTotal.setAlignment(Qt.AlignVCenter | Qt.AlignRight) self.labelTotal.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
self.labelFilter = QLabel(self._formatTime(0)) self.labelFilter = QLabel(formatTime(0))
self.labelFilter.setFont(self.theTheme.guiFontFixed) self.labelFilter.setFont(self.theTheme.guiFontFixed)
self.labelFilter.setAlignment(Qt.AlignVCenter | Qt.AlignRight) self.labelFilter.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
@@ -367,32 +368,28 @@ class GuiWritingStats(QDialog):
elif dataFmt == self.FMT_CSV: elif dataFmt == self.FMT_CSV:
outFile.write( outFile.write(
"\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n" % ( '"Date","Length (sec)","Words Changed","Novel Words","Note Words"\n'
"Date", "Length (sec)", "Words Changed", "Novel Words", "Note Words"
)
) )
for _, sD, tT, wD, wA, wB in self.filterData: for _, sD, tT, wD, wA, wB in self.filterData:
outFile.write( outFile.write(f'"{sD}",{tT:.0f},{wD},{wA},{wB}\n')
"\"%s\",%d,%d,%d,%d\n" % (sD, tT, wD, wA, wB)
)
wSuccess = True wSuccess = True
else: else:
errMsg = "Unknown format" errMsg = "Unknown format"
except Exception as e: except Exception as e:
errMsg = str(e) errMsg = str(e).replace("\n", "<br>")
# Report to user # Report to user
if wSuccess: if wSuccess:
self.theParent.makeAlert( self.theParent.makeAlert(
"%s file successfully written to:<br> %s" % ( "%s file successfully written to:<br>%s" % (
textFmt, savePath textFmt, savePath
), nwAlert.INFO ), nwAlert.INFO
) )
else: else:
self.theParent.makeAlert( self.theParent.makeAlert(
"Failed to write %s file. %s" % ( "Failed to write %s file.<br>%s" % (
textFmt, errMsg textFmt, errMsg
), nwAlert.ERROR ), nwAlert.ERROR
) )
@@ -455,7 +452,7 @@ class GuiWritingStats(QDialog):
return False return False
ttWords = ttNovel + ttNotes ttWords = ttNovel + ttNotes
self.labelTotal.setText(self._formatTime(ttTime)) self.labelTotal.setText(formatTime(round(ttTime)))
self.novelWords.setText(f"{ttNovel:n}") self.novelWords.setText(f"{ttNovel:n}")
self.notesWords.setText(f"{ttNotes:n}") self.notesWords.setText(f"{ttNotes:n}")
self.totalWords.setText(f"{ttWords:n}") self.totalWords.setText(f"{ttWords:n}")
@@ -544,7 +541,7 @@ class GuiWritingStats(QDialog):
newItem = QTreeWidgetItem() newItem = QTreeWidgetItem()
newItem.setText(self.C_TIME, sStart) newItem.setText(self.C_TIME, sStart)
newItem.setText(self.C_LENGTH, self._formatTime(sDiff)) newItem.setText(self.C_LENGTH, formatTime(round(sDiff)))
newItem.setText(self.C_COUNT, f"{nWords:n}") newItem.setText(self.C_COUNT, f"{nWords:n}")
if nWords > 0 and listMax > 0: if nWords > 0 and listMax > 0:
@@ -567,17 +564,8 @@ class GuiWritingStats(QDialog):
self.listBox.addTopLevelItem(newItem) self.listBox.addTopLevelItem(newItem)
self.timeFilter += sDiff self.timeFilter += sDiff
self.labelFilter.setText(self._formatTime(self.timeFilter)) self.labelFilter.setText(formatTime(round(self.timeFilter)))
return True return True
def _formatTime(self, tS):
"""Format the time spent in 00:00:00 format.
"""
tM = int(tS/60)
tH = int(tM/60)
tM = tM - tH*60
tS = tS - tM*60 - tH*3600
return "%02d:%02d:%02d" % (tH, tM, tS)
# END Class GuiWritingStats # END Class GuiWritingStats
+1 -1
View File
@@ -3,7 +3,7 @@
novelWriter GUI Main Window novelWriter GUI Main Window
=============================== ===============================
Class holding the main window Class holding the main application window
File History: File History:
Created: 2018-09-22 [0.0.1] Created: 2018-09-22 [0.0.1]
+20 -2
View File
@@ -7,7 +7,7 @@ import pytest
from nw.common import ( from nw.common import (
checkString, checkBool, checkInt, colRange, formatInt, transferCase, checkString, checkBool, checkInt, colRange, formatInt, transferCase,
fuzzyTime, checkHandle, formatTimeStamp fuzzyTime, checkHandle, formatTimeStamp, formatTime
) )
from nwtools import cmpList from nwtools import cmpList
@@ -78,11 +78,29 @@ def testColRange():
) )
@pytest.mark.core @pytest.mark.core
def testFormatTime(): def testFormatTimeStamp():
tTime = time.mktime(time.gmtime(0)) tTime = time.mktime(time.gmtime(0))
assert formatTimeStamp(tTime, False) == "1970-01-01 00:00:00" assert formatTimeStamp(tTime, False) == "1970-01-01 00:00:00"
assert formatTimeStamp(tTime, True) == "1970-01-01 00.00.00" assert formatTimeStamp(tTime, True) == "1970-01-01 00.00.00"
@pytest.mark.core
def testFormatTime():
assert formatTime("1") == "ERROR"
assert formatTime(1.0) == "ERROR"
assert formatTime(1) == "00:00:01"
assert formatTime(59) == "00:00:59"
assert formatTime(60) == "00:01:00"
assert formatTime(180) == "00:03:00"
assert formatTime(194) == "00:03:14"
assert formatTime(3540) == "00:59:00"
assert formatTime(3599) == "00:59:59"
assert formatTime(3600) == "01:00:00"
assert formatTime(11640) == "03:14:00"
assert formatTime(11655) == "03:14:15"
assert formatTime(86399) == "23:59:59"
assert formatTime(86400) == "1-00:00:00"
assert formatTime(360000) == "4-04:00:00"
@pytest.mark.core @pytest.mark.core
def testFormatInt(): def testFormatInt():
assert formatInt(1000) == "1000" assert formatInt(1000) == "1000"
+1 -1
View File
@@ -252,7 +252,7 @@ def testItemXMLPackUnpack(nwDummy):
xDummy = etree.SubElement(nwXML, "item", attrib={"handle": "0123456789abc"}) xDummy = etree.SubElement(nwXML, "item", attrib={"handle": "0123456789abc"})
xParam = etree.SubElement(xDummy, "invalid") xParam = etree.SubElement(xDummy, "invalid")
xParam.text = "stuff" xParam.text = "stuff"
assert theItem.unpackXML(xDummy) # Passes, but not saved assert not theItem.unpackXML(xDummy)
# Pack Valid Item # Pack Valid Item
xDummy = etree.SubElement(nwXML, "group") xDummy = etree.SubElement(nwXML, "group")