Merge pull request #478 from vkbo/code_cleanup
Code Cleanup and Improvements
This commit is contained in:
@@ -25,5 +25,5 @@ jobs:
|
|||||||
flake8 tests --count --select=E9,F63,F7,F82 --show-source --statistics
|
flake8 tests --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||||
- name: Coding Style Violations
|
- name: Coding Style Violations
|
||||||
run: |
|
run: |
|
||||||
flake8 nw --count --max-line-length=99 --ignore E203,E221,E226,E241,E251,E261,E266,E302,E305 --show-source --statistics
|
flake8 nw --count --max-line-length=99 --ignore E203,E221,E226,E228,E241,E251,E261,E266,E302,E305 --show-source --statistics
|
||||||
flake8 tests --count --max-line-length=99 --ignore E203,E221,E226,E241,E251,E261,E266,E302,E305 --show-source --statistics
|
flake8 tests --count --max-line-length=99 --ignore E203,E221,E226,E228,E241,E251,E261,E266,E302,E305 --show-source --statistics
|
||||||
|
|||||||
+9
-6
@@ -67,7 +67,9 @@ class NWDoc():
|
|||||||
|
|
||||||
def openDocument(self, tHandle, showStatus=True, isOrphan=False):
|
def openDocument(self, tHandle, showStatus=True, isOrphan=False):
|
||||||
"""Open a document from handle, capturing potential file system
|
"""Open a document from handle, capturing potential file system
|
||||||
errors and parse meta data.
|
errors and parse meta data. If the document doesn't exist on
|
||||||
|
disk, return an empty string. If something went wrong, return
|
||||||
|
None.
|
||||||
"""
|
"""
|
||||||
if not isHandle(tHandle):
|
if not isHandle(tHandle):
|
||||||
return None
|
return None
|
||||||
@@ -120,13 +122,13 @@ class NWDoc():
|
|||||||
logger.verbose("DocMeta: '%s'" % self._docMeta)
|
logger.verbose("DocMeta: '%s'" % self._docMeta)
|
||||||
|
|
||||||
if showStatus and not isOrphan:
|
if showStatus and not isOrphan:
|
||||||
self.theParent.statusBar.setStatus("Opened Document: %s" % self._theItem.itemName)
|
self.theParent.setStatus("Opened Document: %s" % self._theItem.itemName)
|
||||||
|
|
||||||
return theText
|
return theText
|
||||||
|
|
||||||
def saveDocument(self, docText):
|
def saveDocument(self, docText):
|
||||||
"""Save the document via temp file in case of save failure, and
|
"""Save the document. The file is saved via a temp file in case
|
||||||
in any case keep a backup of the file.
|
of save failure. Returns True if successful, False if not.
|
||||||
"""
|
"""
|
||||||
if self._docHandle is None:
|
if self._docHandle is None:
|
||||||
return False
|
return False
|
||||||
@@ -139,6 +141,7 @@ class NWDoc():
|
|||||||
docPath = os.path.join(self.theProject.projContent, docFile)
|
docPath = os.path.join(self.theProject.projContent, docFile)
|
||||||
docTemp = os.path.join(self.theProject.projContent, docFile+"~")
|
docTemp = os.path.join(self.theProject.projContent, docFile+"~")
|
||||||
|
|
||||||
|
# DocMeta line
|
||||||
if self._theItem is None:
|
if self._theItem is None:
|
||||||
docMeta = ""
|
docMeta = ""
|
||||||
else:
|
else:
|
||||||
@@ -166,12 +169,12 @@ class NWDoc():
|
|||||||
os.unlink(docPath)
|
os.unlink(docPath)
|
||||||
os.rename(docTemp, docPath)
|
os.rename(docTemp, docPath)
|
||||||
|
|
||||||
self.theParent.statusBar.setStatus("Saved Document: %s" % self._theItem.itemName)
|
self.theParent.setStatus("Saved Document: %s" % self._theItem.itemName)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def deleteDocument(self, tHandle):
|
def deleteDocument(self, tHandle):
|
||||||
"""Permanently delete a document source file and its backups
|
"""Permanently delete a document source file and related files
|
||||||
from the project data folder.
|
from the project data folder.
|
||||||
"""
|
"""
|
||||||
if not isHandle(tHandle):
|
if not isHandle(tHandle):
|
||||||
|
|||||||
+3
-3
@@ -279,7 +279,7 @@ class NWIndex():
|
|||||||
if theItem.itemLayout == nwItemLayout.NO_LAYOUT:
|
if theItem.itemLayout == nwItemLayout.NO_LAYOUT:
|
||||||
logger.info("Not indexing no-layout item %s" % tHandle)
|
logger.info("Not indexing no-layout item %s" % tHandle)
|
||||||
return False
|
return False
|
||||||
if theItem.parHandle is None:
|
if theItem.itemParent is None:
|
||||||
logger.info("Not indexing orphaned item %s" % tHandle)
|
logger.info("Not indexing orphaned item %s" % tHandle)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ class NWIndex():
|
|||||||
self.textCounts[tHandle] = [cC, wC, pC]
|
self.textCounts[tHandle] = [cC, wC, pC]
|
||||||
|
|
||||||
# If the file is archived or trashed, we don't index the file itself
|
# If the file is archived or trashed, we don't index the file itself
|
||||||
if self.theProject.projTree.isTrashRoot(theItem.parHandle):
|
if self.theProject.projTree.isTrashRoot(theItem.itemParent):
|
||||||
logger.info("Not indexing trash item %s" % tHandle)
|
logger.info("Not indexing trash item %s" % tHandle)
|
||||||
return False
|
return False
|
||||||
if theRoot.itemClass == nwItemClass.ARCHIVE:
|
if theRoot.itemClass == nwItemClass.ARCHIVE:
|
||||||
@@ -583,7 +583,7 @@ class NWIndex():
|
|||||||
|
|
||||||
def getCounts(self, tHandle, sTitle=None):
|
def getCounts(self, tHandle, sTitle=None):
|
||||||
"""Returns the counts for a file, or a section of a file
|
"""Returns the counts for a file, or a section of a file
|
||||||
starting at title nTitle.
|
starting at title sTitle if it is provided.
|
||||||
"""
|
"""
|
||||||
cC = 0
|
cC = 0
|
||||||
wC = 0
|
wC = 0
|
||||||
|
|||||||
+11
-8
@@ -42,7 +42,7 @@ class NWItem():
|
|||||||
|
|
||||||
self.itemName = ""
|
self.itemName = ""
|
||||||
self.itemHandle = None
|
self.itemHandle = None
|
||||||
self.parHandle = None
|
self.itemParent = None
|
||||||
self.itemOrder = None
|
self.itemOrder = None
|
||||||
self.itemType = nwItemType.NO_TYPE
|
self.itemType = nwItemType.NO_TYPE
|
||||||
self.itemClass = nwItemClass.NO_CLASS
|
self.itemClass = nwItemClass.NO_CLASS
|
||||||
@@ -70,7 +70,7 @@ class NWItem():
|
|||||||
xPack = etree.SubElement(xParent, "item", attrib={
|
xPack = etree.SubElement(xParent, "item", attrib={
|
||||||
"handle" : str(self.itemHandle),
|
"handle" : str(self.itemHandle),
|
||||||
"order" : str(self.itemOrder),
|
"order" : str(self.itemOrder),
|
||||||
"parent" : str(self.parHandle),
|
"parent" : str(self.itemParent),
|
||||||
})
|
})
|
||||||
self._subPack(xPack, "name", text=str(self.itemName))
|
self._subPack(xPack, "name", text=str(self.itemName))
|
||||||
self._subPack(xPack, "type", text=str(self.itemType.name))
|
self._subPack(xPack, "type", text=str(self.itemType.name))
|
||||||
@@ -85,6 +85,7 @@ class NWItem():
|
|||||||
self._subPack(xPack, "cursorPos", text=str(self.cursorPos), none=False)
|
self._subPack(xPack, "cursorPos", text=str(self.cursorPos), none=False)
|
||||||
else:
|
else:
|
||||||
self._subPack(xPack, "expanded", text=str(self.isExpanded))
|
self._subPack(xPack, "expanded", text=str(self.isExpanded))
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def unpackXML(self, xItem):
|
def unpackXML(self, xItem):
|
||||||
@@ -101,7 +102,7 @@ class NWItem():
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
if "parent" in xItem.attrib:
|
if "parent" in xItem.attrib:
|
||||||
self.parHandle = xItem.attrib["parent"]
|
self.itemParent = xItem.attrib["parent"]
|
||||||
|
|
||||||
setMap = {
|
setMap = {
|
||||||
"name" : self.setName,
|
"name" : self.setName,
|
||||||
@@ -131,9 +132,11 @@ class NWItem():
|
|||||||
"""
|
"""
|
||||||
if not none and (text is None or text == "None"):
|
if not none and (text is None or text == "None"):
|
||||||
return None
|
return None
|
||||||
xSub = etree.SubElement(xParent, name, attrib=attrib)
|
xAttr = {} if attrib is None else attrib
|
||||||
|
xSub = etree.SubElement(xParent, name, attrib=xAttr)
|
||||||
if text is not None:
|
if text is not None:
|
||||||
xSub.text = text
|
xSub.text = text
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -162,14 +165,14 @@ class NWItem():
|
|||||||
"""Set the parent handle, and ensure that it is valid.
|
"""Set the parent handle, and ensure that it is valid.
|
||||||
"""
|
"""
|
||||||
if theParent is None:
|
if theParent is None:
|
||||||
self.parHandle = None
|
self.itemParent = None
|
||||||
elif isinstance(theParent, str):
|
elif isinstance(theParent, str):
|
||||||
if len(theParent) == 13:
|
if len(theParent) == 13:
|
||||||
self.parHandle = theParent
|
self.itemParent = theParent
|
||||||
else:
|
else:
|
||||||
self.parHandle = None
|
self.itemParent = None
|
||||||
else:
|
else:
|
||||||
self.parHandle = None
|
self.itemParent = None
|
||||||
return
|
return
|
||||||
|
|
||||||
def setOrder(self, theOrder):
|
def setOrder(self, theOrder):
|
||||||
|
|||||||
+5
-5
@@ -782,7 +782,7 @@ class NWProject():
|
|||||||
"""Create a zip file of the entire project.
|
"""Create a zip file of the entire project.
|
||||||
"""
|
"""
|
||||||
logger.info("Backing up project")
|
logger.info("Backing up project")
|
||||||
self.theParent.statusBar.setStatus("Backing up project ...")
|
self.theParent.setStatus("Backing up project ...")
|
||||||
|
|
||||||
if self.mainConf.backupPath is None or self.mainConf.backupPath == "":
|
if self.mainConf.backupPath is None or self.mainConf.backupPath == "":
|
||||||
self.theParent.makeAlert((
|
self.theParent.makeAlert((
|
||||||
@@ -847,7 +847,7 @@ class NWProject():
|
|||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.theParent.statusBar.setStatus("Project backed up to '%s.zip'" % baseName)
|
self.theParent.setStatus("Project backed up to '%s.zip'" % baseName)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -1139,16 +1139,16 @@ class NWProject():
|
|||||||
# Technically a bug since treeOrder is built from the
|
# Technically a bug since treeOrder is built from the
|
||||||
# same data as projTree
|
# same data as projTree
|
||||||
continue
|
continue
|
||||||
elif tItem.parHandle is None:
|
elif tItem.itemParent is None:
|
||||||
# Item is a root, or already been identified as an
|
# Item is a root, or already been identified as an
|
||||||
# orphaned item
|
# orphaned item
|
||||||
sentItems.append(tHandle)
|
sentItems.append(tHandle)
|
||||||
yield tItem
|
yield tItem
|
||||||
elif tItem.parHandle in sentItems:
|
elif tItem.itemParent in sentItems:
|
||||||
# Item's parent has been sent, so all is fine
|
# Item's parent has been sent, so all is fine
|
||||||
sentItems.append(tHandle)
|
sentItems.append(tHandle)
|
||||||
yield tItem
|
yield tItem
|
||||||
elif tItem.parHandle in iterItems:
|
elif tItem.itemParent in iterItems:
|
||||||
# Item's parent exists, but hasn't been sent yet, so add
|
# Item's parent exists, but hasn't been sent yet, so add
|
||||||
# it again to the end
|
# it again to the end
|
||||||
logger.warning("Item %s found before its parent" % tHandle)
|
logger.warning("Item %s found before its parent" % tHandle)
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class ToHtml(Tokenizer):
|
|||||||
|
|
||||||
def __init__(self, theProject, theParent):
|
def __init__(self, theProject, theParent):
|
||||||
Tokenizer.__init__(self, theProject, theParent)
|
Tokenizer.__init__(self, theProject, theParent)
|
||||||
|
|
||||||
self.genMode = self.M_EXPORT
|
self.genMode = self.M_EXPORT
|
||||||
self.cssStyles = True
|
self.cssStyles = True
|
||||||
|
|
||||||
|
|||||||
+8
-9
@@ -136,7 +136,6 @@ def numberToWord(numVal, theLanguage):
|
|||||||
def _numberToWordEN(numVal):
|
def _numberToWordEN(numVal):
|
||||||
"""Convert numbers to English words.
|
"""Convert numbers to English words.
|
||||||
"""
|
"""
|
||||||
numWord = ""
|
|
||||||
oneWord = ""
|
oneWord = ""
|
||||||
tenWord = ""
|
tenWord = ""
|
||||||
hunWord = ""
|
hunWord = ""
|
||||||
@@ -145,8 +144,8 @@ def _numberToWordEN(numVal):
|
|||||||
return "Zero"
|
return "Zero"
|
||||||
|
|
||||||
oneVal = numVal % 10
|
oneVal = numVal % 10
|
||||||
tenVal = (numVal-oneVal) % 100
|
tenVal = (numVal - oneVal) % 100
|
||||||
hunVal = (numVal-tenVal-oneVal) % 1000
|
hunVal = (numVal - tenVal - oneVal) % 1000
|
||||||
|
|
||||||
theHundreds = {
|
theHundreds = {
|
||||||
100: "One Hundred", 200: "Two Hundred", 300: "Three Hundred",
|
100: "One Hundred", 200: "Two Hundred", 300: "Three Hundred",
|
||||||
@@ -167,18 +166,18 @@ def _numberToWordEN(numVal):
|
|||||||
}
|
}
|
||||||
|
|
||||||
hunWord = theHundreds.get(hunVal, "")
|
hunWord = theHundreds.get(hunVal, "")
|
||||||
tenWord = theTens.get(tenVal, "")
|
|
||||||
if tenVal == 10:
|
if tenVal == 10:
|
||||||
oneWord = theTeens.get(oneVal, "")
|
oneWord = theTeens.get(oneVal, "")
|
||||||
numWord = ("%s %s" % (hunWord, oneWord)).strip()
|
return f"{hunWord} {oneWord}".strip()
|
||||||
else:
|
else:
|
||||||
oneWord = theOnes.get(oneVal, "")
|
oneWord = theOnes.get(oneVal, "")
|
||||||
if tenVal == 0:
|
if tenVal == 0:
|
||||||
numWord = ("%s %s" % (hunWord, oneWord)).strip()
|
return f"{hunWord} {oneWord}".strip()
|
||||||
else:
|
else:
|
||||||
|
tenWord = theTens.get(tenVal, "")
|
||||||
if oneVal == 0:
|
if oneVal == 0:
|
||||||
numWord = ("%s %s" % (hunWord, tenWord)).strip()
|
return f"{hunWord} {tenWord}".strip()
|
||||||
else:
|
else:
|
||||||
numWord = ("%s %s-%s" % (hunWord, tenWord, oneWord)).strip()
|
return f"{hunWord} {tenWord}-{oneWord}".strip()
|
||||||
|
|
||||||
return numWord
|
return ""
|
||||||
|
|||||||
+5
-5
@@ -134,7 +134,7 @@ class NWTree():
|
|||||||
for xItem in xContent:
|
for xItem in xContent:
|
||||||
nwItem = NWItem(self.theProject)
|
nwItem = NWItem(self.theProject)
|
||||||
if nwItem.unpackXML(xItem):
|
if nwItem.unpackXML(xItem):
|
||||||
self.append(nwItem.itemHandle, nwItem.parHandle, nwItem)
|
self.append(nwItem.itemHandle, nwItem.itemParent, nwItem)
|
||||||
nwItem.saveInitialCount()
|
nwItem.saveInitialCount()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@@ -261,10 +261,10 @@ class NWTree():
|
|||||||
tItem = self.__getitem__(tHandle)
|
tItem = self.__getitem__(tHandle)
|
||||||
if tItem is not None:
|
if tItem is not None:
|
||||||
for i in range(nwConst.maxDepth + 1):
|
for i in range(nwConst.maxDepth + 1):
|
||||||
if tItem.parHandle is None:
|
if tItem.itemParent is None:
|
||||||
return tItem
|
return tItem
|
||||||
else:
|
else:
|
||||||
tHandle = tItem.parHandle
|
tHandle = tItem.itemParent
|
||||||
tItem = self.__getitem__(tHandle)
|
tItem = self.__getitem__(tHandle)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -279,10 +279,10 @@ class NWTree():
|
|||||||
if tItem is not None:
|
if tItem is not None:
|
||||||
tTree.append(tHandle)
|
tTree.append(tHandle)
|
||||||
for i in range(nwConst.maxDepth + 1):
|
for i in range(nwConst.maxDepth + 1):
|
||||||
if tItem.parHandle is None:
|
if tItem.itemParent is None:
|
||||||
return tTree
|
return tTree
|
||||||
else:
|
else:
|
||||||
tHandle = tItem.parHandle
|
tHandle = tItem.itemParent
|
||||||
tItem = self.__getitem__(tHandle)
|
tItem = self.__getitem__(tHandle)
|
||||||
if tItem is None:
|
if tItem is None:
|
||||||
return tTree
|
return tTree
|
||||||
|
|||||||
@@ -222,7 +222,6 @@ class GuiAbout(QDialog):
|
|||||||
hColB = self.theParent.theTheme.colHead[2],
|
hColB = self.theParent.theTheme.colHead[2],
|
||||||
)
|
)
|
||||||
self.pageAbout.document().setDefaultStyleSheet(styleSheet)
|
self.pageAbout.document().setDefaultStyleSheet(styleSheet)
|
||||||
# self.pageCredit.document().setDefaultStyleSheet(styleSheet)
|
|
||||||
self.pageLicense.document().setDefaultStyleSheet(styleSheet)
|
self.pageLicense.document().setDefaultStyleSheet(styleSheet)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|||||||
+2
-2
@@ -684,8 +684,8 @@ class GuiBuildNovel(QDialog):
|
|||||||
isNone |= theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
isNone |= theItem.itemLayout == nwItemLayout.NO_LAYOUT
|
||||||
isNone |= theItem.itemClass == nwItemClass.NO_CLASS
|
isNone |= theItem.itemClass == nwItemClass.NO_CLASS
|
||||||
isNone |= theItem.itemClass == nwItemClass.TRASH
|
isNone |= theItem.itemClass == nwItemClass.TRASH
|
||||||
isNone |= theItem.parHandle == self.theProject.projTree.trashRoot()
|
isNone |= theItem.itemParent == self.theProject.projTree.trashRoot()
|
||||||
isNone |= theItem.parHandle is None
|
isNone |= theItem.itemParent is None
|
||||||
isNote = theItem.itemLayout == nwItemLayout.NOTE
|
isNote = theItem.itemLayout == nwItemLayout.NOTE
|
||||||
isNovel = not isNone and not isNote
|
isNovel = not isNone and not isNote
|
||||||
|
|
||||||
|
|||||||
+9
-10
@@ -807,16 +807,16 @@ class GuiDocEditor(QTextEdit):
|
|||||||
return self.docSearch.cycleFocus(toNext)
|
return self.docSearch.cycleFocus(toNext)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def mouseReleaseEvent(self, mEvent):
|
def mouseReleaseEvent(self, theEvent):
|
||||||
"""If the mouse button is released and the control key is
|
"""If the mouse button is released and the control key is
|
||||||
pressed, check if we're clicking on a tag, and trigger the
|
pressed, check if we're clicking on a tag, and trigger the
|
||||||
follow tag function.
|
follow tag function.
|
||||||
"""
|
"""
|
||||||
if qApp.keyboardModifiers() == Qt.ControlModifier:
|
if qApp.keyboardModifiers() == Qt.ControlModifier:
|
||||||
theCursor = self.cursorForPosition(mEvent.pos())
|
theCursor = self.cursorForPosition(theEvent.pos())
|
||||||
self._followTag(theCursor)
|
self._followTag(theCursor)
|
||||||
|
|
||||||
QTextEdit.mouseReleaseEvent(self, mEvent)
|
QTextEdit.mouseReleaseEvent(self, theEvent)
|
||||||
self.docFooter.updateLineCount()
|
self.docFooter.updateLineCount()
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -1203,20 +1203,19 @@ class GuiDocEditor(QTextEdit):
|
|||||||
"""Check if document size crosses the big document limit set in
|
"""Check if document size crosses the big document limit set in
|
||||||
config. If so, we will set the big document flag to True.
|
config. If so, we will set the big document flag to True.
|
||||||
"""
|
"""
|
||||||
newState = theSize > self.mainConf.bigDocLimit*1000
|
bigLim = self.mainConf.bigDocLimit*1000
|
||||||
|
newState = theSize > bigLim
|
||||||
|
|
||||||
if newState != self.bigDoc:
|
if newState != self.bigDoc:
|
||||||
if newState:
|
if newState:
|
||||||
logger.info(
|
logger.info(
|
||||||
"The document size is {:n} > {:n}, big doc mode has been enabled".format(
|
f"The document size is {theSize:n} > {bigLim:n}, "
|
||||||
theSize, self.mainConf.bigDocLimit*1000
|
f"big doc mode has been enabled"
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logger.info(
|
logger.info(
|
||||||
"The document size is {:n} <= {:n}, big doc mode has been disabled".format(
|
f"The document size is {theSize:n} <= {bigLim:n}, "
|
||||||
theSize, self.mainConf.bigDocLimit*1000
|
f"big doc mode has been disabled"
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.bigDoc = newState
|
self.bigDoc = newState
|
||||||
|
|||||||
@@ -149,18 +149,22 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
|
|
||||||
# Quoted Strings
|
# Quoted Strings
|
||||||
if self.mainConf.highlightQuotes:
|
if self.mainConf.highlightQuotes:
|
||||||
|
fmtDO = self.mainConf.fmtDoubleQuotes[0]
|
||||||
|
fmtDC = self.mainConf.fmtDoubleQuotes[1]
|
||||||
|
fmtSO = self.mainConf.fmtSingleQuotes[0]
|
||||||
|
fmtSC = self.mainConf.fmtSingleQuotes[1]
|
||||||
self.hRules.append((
|
self.hRules.append((
|
||||||
"\\B{:s}(.*?){:s}\\B".format('"', '"'), {
|
"\\B\"(.*?)\"\\B", {
|
||||||
0 : self.hStyles["dialogue1"],
|
0 : self.hStyles["dialogue1"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
self.hRules.append((
|
self.hRules.append((
|
||||||
"\\B{:s}(.*?){:s}\\B".format(*self.mainConf.fmtDoubleQuotes), {
|
f"\\B{fmtDO:s}(.*?){fmtDC:s}\\B", {
|
||||||
0 : self.hStyles["dialogue2"],
|
0 : self.hStyles["dialogue2"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
self.hRules.append((
|
self.hRules.append((
|
||||||
"\\B{:s}(.*?){:s}\\B".format(*self.mainConf.fmtSingleQuotes), {
|
f"\\B{fmtSO:s}(.*?){fmtSC:s}\\B", {
|
||||||
0 : self.hStyles["dialogue3"],
|
0 : self.hStyles["dialogue3"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|||||||
+1
-1
@@ -127,7 +127,7 @@ class GuiDocMerge(QDialog):
|
|||||||
), nwAlert.ERROR)
|
), nwAlert.ERROR)
|
||||||
return
|
return
|
||||||
|
|
||||||
nHandle = self.theProject.newFile(srcItem.itemName, srcItem.itemClass, srcItem.parHandle)
|
nHandle = self.theProject.newFile(srcItem.itemName, srcItem.itemClass, srcItem.itemParent)
|
||||||
newItem = self.theProject.projTree[nHandle]
|
newItem = self.theProject.projTree[nHandle]
|
||||||
newItem.setStatus(srcItem.itemStatus)
|
newItem.setStatus(srcItem.itemStatus)
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -154,7 +154,7 @@ class GuiDocSplit(QDialog):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Check that another folder can be created
|
# Check that another folder can be created
|
||||||
parTree = self.theProject.projTree.getItemPath(srcItem.parHandle)
|
parTree = self.theProject.projTree.getItemPath(srcItem.itemParent)
|
||||||
if len(parTree) >= nwConst.maxDepth - 1:
|
if len(parTree) >= nwConst.maxDepth - 1:
|
||||||
self.theParent.makeAlert((
|
self.theParent.makeAlert((
|
||||||
"Cannot add new folder for the document split. "
|
"Cannot add new folder for the document split. "
|
||||||
@@ -176,7 +176,7 @@ class GuiDocSplit(QDialog):
|
|||||||
|
|
||||||
# Create the folder
|
# Create the folder
|
||||||
fHandle = self.theProject.newFolder(
|
fHandle = self.theProject.newFolder(
|
||||||
srcItem.itemName, srcItem.itemClass, srcItem.parHandle
|
srcItem.itemName, srcItem.itemClass, srcItem.itemParent
|
||||||
)
|
)
|
||||||
self.theParent.treeView.revealNewTreeItem(fHandle)
|
self.theParent.treeView.revealNewTreeItem(fHandle)
|
||||||
logger.verbose("Creating folder %s" % fHandle)
|
logger.verbose("Creating folder %s" % fHandle)
|
||||||
|
|||||||
+7
-3
@@ -439,6 +439,10 @@ class GuiOutline(QTreeWidget):
|
|||||||
newItem = QTreeWidgetItem()
|
newItem = QTreeWidgetItem()
|
||||||
hIcon = "doc_%s" % tLevel.lower()
|
hIcon = "doc_%s" % tLevel.lower()
|
||||||
|
|
||||||
|
cC = int(novIdx["cCount"])
|
||||||
|
wC = int(novIdx["wCount"])
|
||||||
|
pC = int(novIdx["pCount"])
|
||||||
|
|
||||||
newItem.setText(self.colIndex[nwOutline.TITLE], novIdx["title"])
|
newItem.setText(self.colIndex[nwOutline.TITLE], novIdx["title"])
|
||||||
newItem.setData(self.colIndex[nwOutline.TITLE], Qt.UserRole, tHandle)
|
newItem.setData(self.colIndex[nwOutline.TITLE], Qt.UserRole, tHandle)
|
||||||
newItem.setIcon(self.colIndex[nwOutline.TITLE], self.theTheme.getIcon(hIcon))
|
newItem.setIcon(self.colIndex[nwOutline.TITLE], self.theTheme.getIcon(hIcon))
|
||||||
@@ -448,9 +452,9 @@ class GuiOutline(QTreeWidget):
|
|||||||
newItem.setText(self.colIndex[nwOutline.LINE], sTitle[1:].lstrip("0"))
|
newItem.setText(self.colIndex[nwOutline.LINE], sTitle[1:].lstrip("0"))
|
||||||
newItem.setData(self.colIndex[nwOutline.LINE], Qt.UserRole, sTitle)
|
newItem.setData(self.colIndex[nwOutline.LINE], Qt.UserRole, sTitle)
|
||||||
newItem.setText(self.colIndex[nwOutline.SYNOP], novIdx["synopsis"])
|
newItem.setText(self.colIndex[nwOutline.SYNOP], novIdx["synopsis"])
|
||||||
newItem.setText(self.colIndex[nwOutline.CCOUNT], "{:n}".format(novIdx["cCount"]))
|
newItem.setText(self.colIndex[nwOutline.CCOUNT], f"{cC:n}")
|
||||||
newItem.setText(self.colIndex[nwOutline.WCOUNT], "{:n}".format(novIdx["wCount"]))
|
newItem.setText(self.colIndex[nwOutline.WCOUNT], f"{wC:n}")
|
||||||
newItem.setText(self.colIndex[nwOutline.PCOUNT], "{:n}".format(novIdx["pCount"]))
|
newItem.setText(self.colIndex[nwOutline.PCOUNT], f"{pC:n}")
|
||||||
newItem.setTextAlignment(self.colIndex[nwOutline.CCOUNT], Qt.AlignRight)
|
newItem.setTextAlignment(self.colIndex[nwOutline.CCOUNT], Qt.AlignRight)
|
||||||
newItem.setTextAlignment(self.colIndex[nwOutline.WCOUNT], Qt.AlignRight)
|
newItem.setTextAlignment(self.colIndex[nwOutline.WCOUNT], Qt.AlignRight)
|
||||||
newItem.setTextAlignment(self.colIndex[nwOutline.PCOUNT], Qt.AlignRight)
|
newItem.setTextAlignment(self.colIndex[nwOutline.PCOUNT], Qt.AlignRight)
|
||||||
|
|||||||
@@ -266,9 +266,13 @@ class GuiOutlineDetails(QScrollArea):
|
|||||||
self.fileValue.setText(nwItem.itemName)
|
self.fileValue.setText(nwItem.itemName)
|
||||||
self.itemValue.setText(nwItem.itemStatus)
|
self.itemValue.setText(nwItem.itemStatus)
|
||||||
|
|
||||||
self.cCValue.setText("{:n}".format(checkInt(novIdx["cCount"], 0)))
|
cC = checkInt(novIdx["cCount"], 0)
|
||||||
self.wCValue.setText("{:n}".format(checkInt(novIdx["wCount"], 0)))
|
wC = checkInt(novIdx["wCount"], 0)
|
||||||
self.pCValue.setText("{:n}".format(checkInt(novIdx["pCount"], 0)))
|
pC = checkInt(novIdx["pCount"], 0)
|
||||||
|
|
||||||
|
self.cCValue.setText(f"{cC:n}")
|
||||||
|
self.wCValue.setText(f"{wC:n}")
|
||||||
|
self.pCValue.setText(f"{pC:n}")
|
||||||
|
|
||||||
self.synopValue.setText(novIdx["synopsis"])
|
self.synopValue.setText(novIdx["synopsis"])
|
||||||
|
|
||||||
|
|||||||
@@ -270,11 +270,12 @@ class GuiProjectEditMeta(QWidget):
|
|||||||
|
|
||||||
self.revLabel = QLabel("Revision count:")
|
self.revLabel = QLabel("Revision count:")
|
||||||
self.revLabel.setIndent(xInd)
|
self.revLabel.setIndent(xInd)
|
||||||
self.revValue = QLabel("{:n}".format(self.theProject.saveCount))
|
self.revValue = QLabel(f"{self.theProject.saveCount:n}")
|
||||||
|
|
||||||
|
editHours = self.theProject.editTime/3600
|
||||||
self.editLabel = QLabel("Edit time:")
|
self.editLabel = QLabel("Edit time:")
|
||||||
self.editLabel.setIndent(xInd)
|
self.editLabel.setIndent(xInd)
|
||||||
self.editValue = QLabel("{:.2f} hours".format(self.theProject.editTime/3600))
|
self.editValue = QLabel(f"{editHours:.2f} hours")
|
||||||
|
|
||||||
self.statsLabel = QLabel("<b>Project Stats</b>")
|
self.statsLabel = QLabel("<b>Project Stats</b>")
|
||||||
|
|
||||||
@@ -294,7 +295,7 @@ class GuiProjectEditMeta(QWidget):
|
|||||||
|
|
||||||
self.wordsLabel = QLabel("Word count:")
|
self.wordsLabel = QLabel("Word count:")
|
||||||
self.wordsLabel.setIndent(xInd)
|
self.wordsLabel.setIndent(xInd)
|
||||||
self.wordsValue = QLabel("{:n}".format(self.theProject.currWCount))
|
self.wordsValue = QLabel(f"{self.theProject.currWCount:n}")
|
||||||
|
|
||||||
self.mainForm.addWidget(self.headLabel, 0, 0, 1, 2, Qt.AlignTop)
|
self.mainForm.addWidget(self.headLabel, 0, 0, 1, 2, Qt.AlignTop)
|
||||||
self.mainForm.addWidget(self.nameLabel, 1, 0, 1, 1, Qt.AlignTop)
|
self.mainForm.addWidget(self.nameLabel, 1, 0, 1, 1, Qt.AlignTop)
|
||||||
|
|||||||
+6
-6
@@ -219,7 +219,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
pItem = self.theProject.projTree[pHandle]
|
pItem = self.theProject.projTree[pHandle]
|
||||||
if pItem.itemType == nwItemType.FILE:
|
if pItem.itemType == nwItemType.FILE:
|
||||||
nHandle = pHandle
|
nHandle = pHandle
|
||||||
pHandle = pItem.parHandle
|
pHandle = pItem.itemParent
|
||||||
|
|
||||||
# If we again have no home, give up
|
# If we again have no home, give up
|
||||||
if pHandle is None:
|
if pHandle is None:
|
||||||
@@ -270,7 +270,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
"""
|
"""
|
||||||
nwItem = self.theProject.projTree[tHandle]
|
nwItem = self.theProject.projTree[tHandle]
|
||||||
trItem = self._addTreeItem(nwItem, nHandle)
|
trItem = self._addTreeItem(nwItem, nHandle)
|
||||||
pHandle = nwItem.parHandle
|
pHandle = nwItem.itemParent
|
||||||
if pHandle is not None and pHandle in self.theMap:
|
if pHandle is not None and pHandle in self.theMap:
|
||||||
self.theMap[pHandle].setExpanded(True)
|
self.theMap[pHandle].setExpanded(True)
|
||||||
self.clearSelection()
|
self.clearSelection()
|
||||||
@@ -430,7 +430,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
logger.error("Could not delete item")
|
logger.error("Could not delete item")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
pHandle = nwItemS.parHandle
|
pHandle = nwItemS.itemParent
|
||||||
if self.theProject.projTree.isTrashRoot(pHandle):
|
if self.theProject.projTree.isTrashRoot(pHandle):
|
||||||
# If the file is in the trash folder already, as the
|
# If the file is in the trash folder already, as the
|
||||||
# user if they want to permanently delete the file.
|
# user if they want to permanently delete the file.
|
||||||
@@ -815,7 +815,7 @@ class GuiProjectTree(QTreeWidget):
|
|||||||
project tree.
|
project tree.
|
||||||
"""
|
"""
|
||||||
tHandle = nwItem.itemHandle
|
tHandle = nwItem.itemHandle
|
||||||
pHandle = nwItem.parHandle
|
pHandle = nwItem.itemParent
|
||||||
tClass = nwItem.itemClass
|
tClass = nwItem.itemClass
|
||||||
newItem = QTreeWidgetItem([""]*4)
|
newItem = QTreeWidgetItem([""]*4)
|
||||||
|
|
||||||
@@ -1022,11 +1022,11 @@ class GuiProjectTreeMenu(QMenu):
|
|||||||
|
|
||||||
trashHandle = self.theTree.theProject.projTree.trashRoot()
|
trashHandle = self.theTree.theProject.projTree.trashRoot()
|
||||||
|
|
||||||
inTrash = theItem.parHandle == trashHandle and trashHandle is not None
|
inTrash = theItem.itemParent == trashHandle and trashHandle is not None
|
||||||
isTrash = theItem.itemHandle == trashHandle and trashHandle is not None
|
isTrash = theItem.itemHandle == trashHandle and trashHandle is not None
|
||||||
isFile = theItem.itemType == nwItemType.FILE
|
isFile = theItem.itemType == nwItemType.FILE
|
||||||
isArch = theRoot.itemClass == nwItemClass.ARCHIVE
|
isArch = theRoot.itemClass == nwItemClass.ARCHIVE
|
||||||
isOrph = isFile and theItem.parHandle is None
|
isOrph = isFile and theItem.itemParent is None
|
||||||
|
|
||||||
showOpen = isFile
|
showOpen = isFile
|
||||||
showView = isFile
|
showView = isFile
|
||||||
|
|||||||
+8
-15
@@ -195,28 +195,21 @@ class GuiMainStatus(QStatusBar):
|
|||||||
self.statsText.setToolTip(
|
self.statsText.setToolTip(
|
||||||
"Project word count (session change)"
|
"Project word count (session change)"
|
||||||
)
|
)
|
||||||
self.statsText.setText((
|
self.statsText.setText(
|
||||||
"Words: {pWC:n} ({sWC:+n})"
|
f"Words: {self.projWords:n} ({self.sessWords:+n})"
|
||||||
).format(
|
)
|
||||||
pWC = self.projWords,
|
|
||||||
sWC = self.sessWords,
|
|
||||||
))
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def _updateTime(self):
|
def _updateTime(self):
|
||||||
"""Update the session clock.
|
"""Update the session clock.
|
||||||
"""
|
"""
|
||||||
if self.refTime is None:
|
if self.refTime is None:
|
||||||
theTime = "00:00:00"
|
self.timeText.setText("00:00:00")
|
||||||
else:
|
else:
|
||||||
# This is much faster than using datetime format
|
|
||||||
tS = int(time() - self.refTime)
|
tS = int(time() - self.refTime)
|
||||||
tM = int(tS/60)
|
self.timeText.setText(
|
||||||
tH = int(tM/60)
|
f"{tS//3600:02d}:{tS%3600//60:02d}:{tS%60:02d}"
|
||||||
tM = tM - tH*60
|
)
|
||||||
tS = tS - tM*60 - tH*3600
|
|
||||||
theTime = "%02d:%02d:%02d" % (tH, tM, tS)
|
|
||||||
self.timeText.setText(theTime)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# END Class GuiMainStatus
|
# END Class GuiMainStatus
|
||||||
@@ -237,7 +230,7 @@ class StatusLED(QAbstractButton):
|
|||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
# Getters and Setters
|
# Setters
|
||||||
##
|
##
|
||||||
|
|
||||||
def setState(self, theState):
|
def setState(self, theState):
|
||||||
|
|||||||
+42
-25
@@ -62,7 +62,9 @@ class GuiMain(QMainWindow):
|
|||||||
self.mainConf = nw.CONFIG
|
self.mainConf = nw.CONFIG
|
||||||
self.threadPool = QThreadPool()
|
self.threadPool = QThreadPool()
|
||||||
|
|
||||||
# Some runtime info useful for debugging
|
# System Info
|
||||||
|
# ===========
|
||||||
|
|
||||||
logger.info("OS: %s" % self.mainConf.osType)
|
logger.info("OS: %s" % self.mainConf.osType)
|
||||||
logger.info("Kernel: %s" % self.mainConf.kernelVer)
|
logger.info("Kernel: %s" % self.mainConf.kernelVer)
|
||||||
logger.info("Host: %s" % self.mainConf.hostName)
|
logger.info("Host: %s" % self.mainConf.hostName)
|
||||||
@@ -76,6 +78,9 @@ class GuiMain(QMainWindow):
|
|||||||
self.mainConf.verPyString, self.mainConf.verPyHexVal)
|
self.mainConf.verPyString, self.mainConf.verPyHexVal)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Core Classes
|
||||||
|
# ============
|
||||||
|
|
||||||
# Core Classes and settings
|
# Core Classes and settings
|
||||||
self.theTheme = GuiTheme(self)
|
self.theTheme = GuiTheme(self)
|
||||||
self.theProject = NWProject(self)
|
self.theProject = NWProject(self)
|
||||||
@@ -89,7 +94,7 @@ class GuiMain(QMainWindow):
|
|||||||
self.setWindowIcon(QIcon(self.mainConf.appIcon))
|
self.setWindowIcon(QIcon(self.mainConf.appIcon))
|
||||||
|
|
||||||
# Build the GUI
|
# Build the GUI
|
||||||
################
|
# =============
|
||||||
|
|
||||||
# Main GUI Elements
|
# Main GUI Elements
|
||||||
self.statusBar = GuiMainStatus(self)
|
self.statusBar = GuiMainStatus(self)
|
||||||
@@ -106,7 +111,7 @@ class GuiMain(QMainWindow):
|
|||||||
self.statusIcons = []
|
self.statusIcons = []
|
||||||
self.importIcons = []
|
self.importIcons = []
|
||||||
|
|
||||||
# Assemble Main Window
|
# Project Tree View
|
||||||
self.treePane = QWidget()
|
self.treePane = QWidget()
|
||||||
self.treeBox = QVBoxLayout()
|
self.treeBox = QVBoxLayout()
|
||||||
self.treeBox.setContentsMargins(0, 0, 0, 0)
|
self.treeBox.setContentsMargins(0, 0, 0, 0)
|
||||||
@@ -114,20 +119,24 @@ class GuiMain(QMainWindow):
|
|||||||
self.treeBox.addWidget(self.treeMeta)
|
self.treeBox.addWidget(self.treeMeta)
|
||||||
self.treePane.setLayout(self.treeBox)
|
self.treePane.setLayout(self.treeBox)
|
||||||
|
|
||||||
|
# Splitter : Document Viewer / Document Meta
|
||||||
self.splitView = QSplitter(Qt.Vertical)
|
self.splitView = QSplitter(Qt.Vertical)
|
||||||
self.splitView.addWidget(self.docViewer)
|
self.splitView.addWidget(self.docViewer)
|
||||||
self.splitView.addWidget(self.viewMeta)
|
self.splitView.addWidget(self.viewMeta)
|
||||||
self.splitView.setSizes(self.mainConf.getViewPanePos())
|
self.splitView.setSizes(self.mainConf.getViewPanePos())
|
||||||
|
|
||||||
|
# Splitter : Document Editor / Document Viewer
|
||||||
self.splitDocs = QSplitter(Qt.Horizontal)
|
self.splitDocs = QSplitter(Qt.Horizontal)
|
||||||
self.splitDocs.addWidget(self.docEditor)
|
self.splitDocs.addWidget(self.docEditor)
|
||||||
self.splitDocs.addWidget(self.splitView)
|
self.splitDocs.addWidget(self.splitView)
|
||||||
|
|
||||||
|
# Splitter : Project Outlie / Outline Details
|
||||||
self.splitOutline = QSplitter(Qt.Vertical)
|
self.splitOutline = QSplitter(Qt.Vertical)
|
||||||
self.splitOutline.addWidget(self.projView)
|
self.splitOutline.addWidget(self.projView)
|
||||||
self.splitOutline.addWidget(self.projMeta)
|
self.splitOutline.addWidget(self.projMeta)
|
||||||
self.splitOutline.setSizes(self.mainConf.getOutlinePanePos())
|
self.splitOutline.setSizes(self.mainConf.getOutlinePanePos())
|
||||||
|
|
||||||
|
# Main Tabs : Edirot / Outline
|
||||||
self.tabWidget = QTabWidget()
|
self.tabWidget = QTabWidget()
|
||||||
self.tabWidget.setTabPosition(QTabWidget.East)
|
self.tabWidget.setTabPosition(QTabWidget.East)
|
||||||
self.tabWidget.setStyleSheet("QTabWidget::pane {border: 0;}")
|
self.tabWidget.setStyleSheet("QTabWidget::pane {border: 0;}")
|
||||||
@@ -135,6 +144,7 @@ class GuiMain(QMainWindow):
|
|||||||
self.tabWidget.addTab(self.splitOutline, "Outline")
|
self.tabWidget.addTab(self.splitOutline, "Outline")
|
||||||
self.tabWidget.currentChanged.connect(self._mainTabChanged)
|
self.tabWidget.currentChanged.connect(self._mainTabChanged)
|
||||||
|
|
||||||
|
# Splitter : Project Tree / Main Tabs
|
||||||
xCM = self.mainConf.pxInt(4)
|
xCM = self.mainConf.pxInt(4)
|
||||||
self.splitMain = QSplitter(Qt.Horizontal)
|
self.splitMain = QSplitter(Qt.Horizontal)
|
||||||
self.splitMain.setContentsMargins(xCM, xCM, xCM, xCM)
|
self.splitMain.setContentsMargins(xCM, xCM, xCM, xCM)
|
||||||
@@ -142,6 +152,7 @@ class GuiMain(QMainWindow):
|
|||||||
self.splitMain.addWidget(self.tabWidget)
|
self.splitMain.addWidget(self.tabWidget)
|
||||||
self.splitMain.setSizes(self.mainConf.getMainPanePos())
|
self.splitMain.setSizes(self.mainConf.getMainPanePos())
|
||||||
|
|
||||||
|
# Indices of All Splitter Widgets
|
||||||
self.idxTree = self.splitMain.indexOf(self.treePane)
|
self.idxTree = self.splitMain.indexOf(self.treePane)
|
||||||
self.idxMain = self.splitMain.indexOf(self.tabWidget)
|
self.idxMain = self.splitMain.indexOf(self.tabWidget)
|
||||||
self.idxEditor = self.splitDocs.indexOf(self.docEditor)
|
self.idxEditor = self.splitDocs.indexOf(self.docEditor)
|
||||||
@@ -151,6 +162,7 @@ class GuiMain(QMainWindow):
|
|||||||
self.idxTabEdit = self.tabWidget.indexOf(self.splitDocs)
|
self.idxTabEdit = self.tabWidget.indexOf(self.splitDocs)
|
||||||
self.idxTabProj = self.tabWidget.indexOf(self.splitOutline)
|
self.idxTabProj = self.tabWidget.indexOf(self.splitOutline)
|
||||||
|
|
||||||
|
# Splitter Behaviour
|
||||||
self.splitMain.setCollapsible(self.idxTree, False)
|
self.splitMain.setCollapsible(self.idxTree, False)
|
||||||
self.splitMain.setCollapsible(self.idxMain, False)
|
self.splitMain.setCollapsible(self.idxMain, False)
|
||||||
self.splitDocs.setCollapsible(self.idxEditor, False)
|
self.splitDocs.setCollapsible(self.idxEditor, False)
|
||||||
@@ -158,10 +170,11 @@ class GuiMain(QMainWindow):
|
|||||||
self.splitView.setCollapsible(self.idxViewDoc, False)
|
self.splitView.setCollapsible(self.idxViewDoc, False)
|
||||||
self.splitView.setCollapsible(self.idxViewMeta, False)
|
self.splitView.setCollapsible(self.idxViewMeta, False)
|
||||||
|
|
||||||
|
# Editor / Viewer Default State
|
||||||
self.splitView.setVisible(False)
|
self.splitView.setVisible(False)
|
||||||
self.docEditor.closeSearch()
|
self.docEditor.closeSearch()
|
||||||
|
|
||||||
# Build the Tree View
|
# Initialise the Project Tree
|
||||||
self.treeView.itemSelectionChanged.connect(self._treeSingleClick)
|
self.treeView.itemSelectionChanged.connect(self._treeSingleClick)
|
||||||
self.treeView.itemDoubleClicked.connect(self._treeDoubleClick)
|
self.treeView.itemDoubleClicked.connect(self._treeDoubleClick)
|
||||||
self.rebuildTree()
|
self.rebuildTree()
|
||||||
@@ -172,13 +185,13 @@ class GuiMain(QMainWindow):
|
|||||||
self.setStatusBar(self.statusBar)
|
self.setStatusBar(self.statusBar)
|
||||||
|
|
||||||
# Finalise Initialisation
|
# Finalise Initialisation
|
||||||
##########################
|
# =======================
|
||||||
|
|
||||||
# Set Up Autosaving Project Timer
|
# Set Up Auto-Save Project Timer
|
||||||
self.asProjTimer = QTimer()
|
self.asProjTimer = QTimer()
|
||||||
self.asProjTimer.timeout.connect(self._autoSaveProject)
|
self.asProjTimer.timeout.connect(self._autoSaveProject)
|
||||||
|
|
||||||
# Set Up Autosaving Document Timer
|
# Set Up Auto-Save Document Timer
|
||||||
self.asDocTimer = QTimer()
|
self.asDocTimer = QTimer()
|
||||||
self.asDocTimer.timeout.connect(self._autoSaveDocument)
|
self.asDocTimer.timeout.connect(self._autoSaveDocument)
|
||||||
|
|
||||||
@@ -203,11 +216,13 @@ class GuiMain(QMainWindow):
|
|||||||
# Check that config loaded fine
|
# Check that config loaded fine
|
||||||
self.reportConfErr()
|
self.reportConfErr()
|
||||||
|
|
||||||
|
# Initialise Main GUI
|
||||||
self.initMain()
|
self.initMain()
|
||||||
self.asProjTimer.start()
|
self.asProjTimer.start()
|
||||||
self.asDocTimer.start()
|
self.asDocTimer.start()
|
||||||
self.statusBar.clearStatus()
|
self.statusBar.clearStatus()
|
||||||
|
|
||||||
|
# Handle Windows Mode
|
||||||
self.showNormal()
|
self.showNormal()
|
||||||
if self.mainConf.isFullScreen:
|
if self.mainConf.isFullScreen:
|
||||||
self.toggleFullScreenMode()
|
self.toggleFullScreenMode()
|
||||||
@@ -224,7 +239,7 @@ class GuiMain(QMainWindow):
|
|||||||
self.showProjectLoadDialog()
|
self.showProjectLoadDialog()
|
||||||
|
|
||||||
logger.debug("novelWriter is ready ...")
|
logger.debug("novelWriter is ready ...")
|
||||||
self.statusBar.setStatus("novelWriter is ready ...")
|
self.setStatus("novelWriter is ready ...")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -249,8 +264,7 @@ class GuiMain(QMainWindow):
|
|||||||
##
|
##
|
||||||
|
|
||||||
def newProject(self, projData=None):
|
def newProject(self, projData=None):
|
||||||
"""Create new project with a few default files and folders.
|
"""Create new project via the new project wizard.
|
||||||
The variable forceNew is used for testing.
|
|
||||||
"""
|
"""
|
||||||
if self.hasProject:
|
if self.hasProject:
|
||||||
self.makeAlert(
|
self.makeAlert(
|
||||||
@@ -293,7 +307,7 @@ class GuiMain(QMainWindow):
|
|||||||
def closeProject(self, isYes=False):
|
def closeProject(self, isYes=False):
|
||||||
"""Closes the project if one is open. isYes is passed on from
|
"""Closes the project if one is open. isYes is passed on from
|
||||||
the close application event so the user doesn't get prompted
|
the close application event so the user doesn't get prompted
|
||||||
twice.
|
twice to confirm.
|
||||||
"""
|
"""
|
||||||
if not self.hasProject:
|
if not self.hasProject:
|
||||||
# There is no project loaded, everything OK
|
# There is no project loaded, everything OK
|
||||||
@@ -302,7 +316,7 @@ class GuiMain(QMainWindow):
|
|||||||
if not isYes:
|
if not isYes:
|
||||||
msgBox = QMessageBox()
|
msgBox = QMessageBox()
|
||||||
msgRes = msgBox.question(
|
msgRes = msgBox.question(
|
||||||
self, "Close Project", "Save changes and close current project?"
|
self, "Close Project", "Save changes and close the current project?"
|
||||||
)
|
)
|
||||||
if msgRes != QMessageBox.Yes:
|
if msgRes != QMessageBox.Yes:
|
||||||
return False
|
return False
|
||||||
@@ -318,7 +332,7 @@ class GuiMain(QMainWindow):
|
|||||||
if self.mainConf.askBeforeBackup:
|
if self.mainConf.askBeforeBackup:
|
||||||
msgBox = QMessageBox()
|
msgBox = QMessageBox()
|
||||||
msgRes = msgBox.question(
|
msgRes = msgBox.question(
|
||||||
self, "Backup Project", "Backup current project?"
|
self, "Backup Project", "Backup the current project?"
|
||||||
)
|
)
|
||||||
if msgRes != QMessageBox.Yes:
|
if msgRes != QMessageBox.Yes:
|
||||||
doBackup = False
|
doBackup = False
|
||||||
@@ -433,6 +447,7 @@ class GuiMain(QMainWindow):
|
|||||||
if self.theProject.projPath is None:
|
if self.theProject.projPath is None:
|
||||||
projPath = self.selectProjectPath()
|
projPath = self.selectProjectPath()
|
||||||
self.theProject.setProjectPath(projPath)
|
self.theProject.setProjectPath(projPath)
|
||||||
|
|
||||||
if self.theProject.projPath is None:
|
if self.theProject.projPath is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -454,6 +469,7 @@ class GuiMain(QMainWindow):
|
|||||||
if self.docEditor.docChanged:
|
if self.docEditor.docChanged:
|
||||||
self.saveDocument()
|
self.saveDocument()
|
||||||
self.docEditor.clearEditor()
|
self.docEditor.clearEditor()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def openDocument(self, tHandle, tLine=None, changeFocus=True, doScroll=False):
|
def openDocument(self, tHandle, tLine=None, changeFocus=True, doScroll=False):
|
||||||
@@ -469,6 +485,7 @@ class GuiMain(QMainWindow):
|
|||||||
self.treeView.setSelectedHandle(tHandle, doScroll=doScroll)
|
self.treeView.setSelectedHandle(tHandle, doScroll=doScroll)
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def openNextDocument(self, tHandle, wrapAround=False):
|
def openNextDocument(self, tHandle, wrapAround=False):
|
||||||
@@ -546,6 +563,7 @@ class GuiMain(QMainWindow):
|
|||||||
vPos[1] = bPos[1] - vPos[0]
|
vPos[1] = bPos[1] - vPos[0]
|
||||||
self.splitDocs.setSizes(vPos)
|
self.splitDocs.setSizes(vPos)
|
||||||
self.viewMeta.setVisible(self.mainConf.showRefPanel)
|
self.viewMeta.setVisible(self.mainConf.showRefPanel)
|
||||||
|
|
||||||
self.docViewer.navigateTo(tAnchor)
|
self.docViewer.navigateTo(tAnchor)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@@ -697,9 +715,9 @@ class GuiMain(QMainWindow):
|
|||||||
for nDone, tItem in enumerate(self.theProject.projTree):
|
for nDone, tItem in enumerate(self.theProject.projTree):
|
||||||
|
|
||||||
if tItem is not None:
|
if tItem is not None:
|
||||||
self.statusBar.setStatus("Indexing: '%s'" % tItem.itemName)
|
self.setStatus("Indexing: '%s'" % tItem.itemName)
|
||||||
else:
|
else:
|
||||||
self.statusBar.setStatus("Indexing: Unknown item")
|
self.setStatus("Indexing: Unknown item")
|
||||||
|
|
||||||
if tItem is not None and tItem.itemType == nwItemType.FILE:
|
if tItem is not None and tItem.itemType == nwItemType.FILE:
|
||||||
logger.verbose("Scanning: %s" % tItem.itemName)
|
logger.verbose("Scanning: %s" % tItem.itemName)
|
||||||
@@ -717,7 +735,7 @@ class GuiMain(QMainWindow):
|
|||||||
self.treeView.projectWordCount()
|
self.treeView.projectWordCount()
|
||||||
|
|
||||||
tEnd = time()
|
tEnd = time()
|
||||||
self.statusBar.setStatus("Indexing completed in %.1f ms" % ((tEnd - tStart)*1000.0))
|
self.setStatus("Indexing completed in %.1f ms" % ((tEnd - tStart)*1000.0))
|
||||||
self.docEditor.updateTagHighLighting()
|
self.docEditor.updateTagHighLighting()
|
||||||
qApp.restoreOverrideCursor()
|
qApp.restoreOverrideCursor()
|
||||||
|
|
||||||
@@ -754,7 +772,8 @@ class GuiMain(QMainWindow):
|
|||||||
def showProjectLoadDialog(self):
|
def showProjectLoadDialog(self):
|
||||||
"""Opens the projects dialog for selecting either existing
|
"""Opens the projects dialog for selecting either existing
|
||||||
projects from a cache of recently opened projects, or provide a
|
projects from a cache of recently opened projects, or provide a
|
||||||
browse button for projects not yet cached.
|
browse button for projects not yet cached. Selecting to create a
|
||||||
|
new project is forwarded to the new project wizard.
|
||||||
"""
|
"""
|
||||||
dlgProj = GuiProjectLoad(self)
|
dlgProj = GuiProjectLoad(self)
|
||||||
dlgProj.exec_()
|
dlgProj.exec_()
|
||||||
@@ -767,7 +786,7 @@ class GuiMain(QMainWindow):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def showNewProjectDialog(self):
|
def showNewProjectDialog(self):
|
||||||
"""Open the wizard and assemble the project options dict.
|
"""Open the wizard and assemble a project options dict.
|
||||||
"""
|
"""
|
||||||
newProj = GuiProjectWizard(self)
|
newProj = GuiProjectWizard(self)
|
||||||
newProj.exec_()
|
newProj.exec_()
|
||||||
@@ -865,8 +884,7 @@ class GuiMain(QMainWindow):
|
|||||||
|
|
||||||
def makeAlert(self, theMessage, theLevel=nwAlert.INFO):
|
def makeAlert(self, theMessage, theLevel=nwAlert.INFO):
|
||||||
"""Alert both the user and the logger at the same time. Message
|
"""Alert both the user and the logger at the same time. Message
|
||||||
can be either a string or an array of strings. Severity level is
|
can be either a string or an array of strings.
|
||||||
0 = info, 1 = warning, and 2 = error.
|
|
||||||
"""
|
"""
|
||||||
if isinstance(theMessage, list):
|
if isinstance(theMessage, list):
|
||||||
popMsg = "<br>".join(theMessage)
|
popMsg = "<br>".join(theMessage)
|
||||||
@@ -955,7 +973,7 @@ class GuiMain(QMainWindow):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def setFocus(self, paneNo):
|
def setFocus(self, paneNo):
|
||||||
"""Switch focus to one of the three main gUi panes.
|
"""Switch focus to one of the three main GUI panes.
|
||||||
"""
|
"""
|
||||||
if paneNo == 1:
|
if paneNo == 1:
|
||||||
self.treeView.setFocus()
|
self.treeView.setFocus()
|
||||||
@@ -1236,9 +1254,9 @@ class GuiMain(QMainWindow):
|
|||||||
return
|
return
|
||||||
|
|
||||||
def _treeKeyPressReturn(self):
|
def _treeKeyPressReturn(self):
|
||||||
"""The user pressed return an item in the tree. If it is a file,
|
"""The user pressed return on an item in the tree. If it is a
|
||||||
we open it. Otherwise, we do nothing. Pressing return does not
|
file, we open it. Otherwise, we do nothing. Pressing return does
|
||||||
change focus to the editor as double click does.
|
not change focus to the editor as double click does.
|
||||||
"""
|
"""
|
||||||
tHandle = self.treeView.getSelectedHandle()
|
tHandle = self.treeView.getSelectedHandle()
|
||||||
logger.verbose("User pressed return on tree item with handle %s" % tHandle)
|
logger.verbose("User pressed return on tree item with handle %s" % tHandle)
|
||||||
@@ -1257,7 +1275,6 @@ class GuiMain(QMainWindow):
|
|||||||
"""
|
"""
|
||||||
if self.docEditor.docSearch.isVisible():
|
if self.docEditor.docSearch.isVisible():
|
||||||
self.docEditor.closeSearch()
|
self.docEditor.closeSearch()
|
||||||
return
|
|
||||||
elif self.isFocusMode:
|
elif self.isFocusMode:
|
||||||
self.toggleFocusMode()
|
self.toggleFocusMode()
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ version = attr: nw.__version__
|
|||||||
universal = 0
|
universal = 0
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
ignore = E203,E221,E226,E241,E251,E261,E266,E302,E305
|
ignore = E203,E221,E226,E228,E241,E251,E261,E266,E302,E305
|
||||||
max-line-length = 99
|
max-line-length = 99
|
||||||
exclude = docs/*
|
exclude = docs/*
|
||||||
|
|||||||
+5
-5
@@ -31,13 +31,13 @@ def testItemSettersSimple(nwDummy):
|
|||||||
|
|
||||||
# Parent
|
# Parent
|
||||||
theItem.setParent(None)
|
theItem.setParent(None)
|
||||||
assert theItem.parHandle is None
|
assert theItem.itemParent is None
|
||||||
theItem.setParent(123)
|
theItem.setParent(123)
|
||||||
assert theItem.parHandle is None
|
assert theItem.itemParent is None
|
||||||
theItem.setParent("0123456789abcdef")
|
theItem.setParent("0123456789abcdef")
|
||||||
assert theItem.parHandle is None
|
assert theItem.itemParent is None
|
||||||
theItem.setParent("0123456789abc")
|
theItem.setParent("0123456789abc")
|
||||||
assert theItem.parHandle == "0123456789abc"
|
assert theItem.itemParent == "0123456789abc"
|
||||||
|
|
||||||
# Order
|
# Order
|
||||||
theItem.setOrder(None)
|
theItem.setOrder(None)
|
||||||
@@ -227,7 +227,7 @@ def testItemXMLPackUnpack(nwDummy):
|
|||||||
# Unpack
|
# Unpack
|
||||||
assert theItem.unpackXML(xContent[0])
|
assert theItem.unpackXML(xContent[0])
|
||||||
assert theItem.itemHandle == "0123456789abc"
|
assert theItem.itemHandle == "0123456789abc"
|
||||||
assert theItem.parHandle == "0123456789abc"
|
assert theItem.itemParent == "0123456789abc"
|
||||||
assert theItem.itemOrder == 1
|
assert theItem.itemOrder == 1
|
||||||
assert theItem.isExpanded
|
assert theItem.isExpanded
|
||||||
assert theItem.paraCount == 3
|
assert theItem.paraCount == 3
|
||||||
|
|||||||
@@ -521,7 +521,7 @@ def testProjectOrphanedFiles(nwDummy, nwLipsum):
|
|||||||
assert oItem is not None
|
assert oItem is not None
|
||||||
assert oItem.itemName == "Mars"
|
assert oItem.itemName == "Mars"
|
||||||
assert oItem.itemHandle == "636b6aa9b697b"
|
assert oItem.itemHandle == "636b6aa9b697b"
|
||||||
assert oItem.parHandle is None
|
assert oItem.itemParent is None
|
||||||
assert oItem.itemClass == nwItemClass.WORLD
|
assert oItem.itemClass == nwItemClass.WORLD
|
||||||
assert oItem.itemType == nwItemType.FILE
|
assert oItem.itemType == nwItemType.FILE
|
||||||
assert oItem.itemLayout == nwItemLayout.NOTE
|
assert oItem.itemLayout == nwItemLayout.NOTE
|
||||||
@@ -531,7 +531,7 @@ def testProjectOrphanedFiles(nwDummy, nwLipsum):
|
|||||||
assert oItem is not None
|
assert oItem is not None
|
||||||
assert oItem.itemName == "Orphaned File 1"
|
assert oItem.itemName == "Orphaned File 1"
|
||||||
assert oItem.itemHandle == "736b6aa9b697b"
|
assert oItem.itemHandle == "736b6aa9b697b"
|
||||||
assert oItem.parHandle is None
|
assert oItem.itemParent is None
|
||||||
assert oItem.itemClass == nwItemClass.NO_CLASS
|
assert oItem.itemClass == nwItemClass.NO_CLASS
|
||||||
assert oItem.itemType == nwItemType.FILE
|
assert oItem.itemType == nwItemType.FILE
|
||||||
assert oItem.itemLayout == nwItemLayout.NO_LAYOUT
|
assert oItem.itemLayout == nwItemLayout.NO_LAYOUT
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ def testNumberWords():
|
|||||||
assert numberToWord(21, "en") == "Twenty-One"
|
assert numberToWord(21, "en") == "Twenty-One"
|
||||||
assert numberToWord(29, "en") == "Twenty-Nine"
|
assert numberToWord(29, "en") == "Twenty-Nine"
|
||||||
assert numberToWord(42, "en") == "Forty-Two"
|
assert numberToWord(42, "en") == "Forty-Two"
|
||||||
|
assert numberToWord(114, "en") == "One Hundred Fourteen"
|
||||||
assert numberToWord(142, "en") == "One Hundred Forty-Two"
|
assert numberToWord(142, "en") == "One Hundred Forty-Two"
|
||||||
assert numberToWord(999, "en") == "Nine Hundred Ninety-Nine"
|
assert numberToWord(999, "en") == "Nine Hundred Ninety-Nine"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user