diff --git a/.codecov.yml b/.codecov.yml index 9166a2e1..45ebc6c7 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -10,9 +10,7 @@ coverage: project: default: threshold: 1% - patch: - default: - threshold: 1% + patch: no changes: no parsers: diff --git a/.github/workflows/syntax.yml b/.github/workflows/syntax.yml index d3ddecdd..f75369fe 100644 --- a/.github/workflows/syntax.yml +++ b/.github/workflows/syntax.yml @@ -19,5 +19,9 @@ jobs: uses: actions/checkout@v2 - name: Install flake8 run: pip install flake8 - - name: Check for Syntax Error + - name: Check for Syntax Error on novelWriter run: flake8 nw --count --select=E9,F63,F7,F82 --show-source --statistics + - name: Check for Syntax Error on Tests + run: flake8 tests --count --select=E9,F63,F7,F82 --show-source --statistics + - name: Check for Code Style on novelWriter + run: flake8 nw --count --max-line-length=99 --select E1,E231,E27,E4,E5,E7,E9,W,F --show-source --statistics diff --git a/nw/__init__.py b/nw/__init__.py index c3fbf7c0..603ded31 100644 --- a/nw/__init__.py +++ b/nw/__init__.py @@ -153,7 +153,7 @@ def main(sysArgs=None): # Parse Options try: - inOpts, inRemain = getopt.getopt(sysArgs,shortOpt,longOpt) + inOpts, inRemain = getopt.getopt(sysArgs, shortOpt, longOpt) except getopt.GetoptError as E: print(helpMsg) print("ERROR: %s" % str(E)) @@ -163,7 +163,7 @@ def main(sysArgs=None): cmdOpen = inRemain[0] for inOpt, inArg in inOpts: - if inOpt in ("-h","--help"): + if inOpt in ("-h", "--help"): print(helpMsg) sys.exit() elif inOpt in ("-v", "--version"): @@ -179,7 +179,7 @@ def main(sysArgs=None): elif inOpt == "--logfile": logFile = inArg toFile = True - elif inOpt in ("-q","--quiet"): + elif inOpt in ("-q", "--quiet"): toStd = False elif inOpt == "--verbose": debugLevel = VERBOSE @@ -205,7 +205,7 @@ def main(sysArgs=None): if path.isfile(logFile+".bak"): remove(logFile+".bak") if path.isfile(logFile): - rename(logFile,logFile+".bak") + rename(logFile, logFile+".bak") fHandle = logging.FileHandler(logFile) fHandle.setLevel(debugLevel) @@ -239,13 +239,13 @@ def main(sysArgs=None): ) try: - import PyQt5.QtSvg - except: + import PyQt5.QtSvg # noqa: F401 + except ImportError: errorData.append("Python module 'PyQt5.QtSvg' is missing.") try: - import lxml - except: + import lxml # noqa: F401 + except ImportError: errorData.append("Python module 'lxml' is missing.") if errorData: diff --git a/nw/common.py b/nw/common.py index 0f4d6ef4..71aa4873 100644 --- a/nw/common.py +++ b/nw/common.py @@ -26,7 +26,6 @@ """ import logging -import nw from datetime import datetime @@ -38,11 +37,11 @@ def checkString(checkValue, defaultValue, allowNone=False): """Check if a variable is a string or a none. """ if allowNone: - if checkValue == None: + if checkValue is None: return None if checkValue == "None": return None - if isinstance(checkValue,str): + if isinstance(checkValue, str): return str(checkValue) return defaultValue @@ -50,20 +49,20 @@ def checkInt(checkValue, defaultValue, allowNone=False): """Check if a variable is an integer or a none. """ if allowNone: - if checkValue == None: + if checkValue is None: return None if checkValue == "None": return None try: return int(checkValue) - except: + except Exception: return defaultValue def checkBool(checkValue, defaultValue, allowNone=False): """Check if a variable is a boolean or a none. """ if allowNone: - if checkValue == None: + if checkValue is None: return None if checkValue == "None": return None @@ -109,7 +108,7 @@ def colRange(rgbStart, rgbEnd, nStep): elif nStep == 2: return [rgbStart, rgbEnd] - dC = [0,0,0] + dC = [0, 0, 0] for c in range(3): cA = rgbStart[c] cB = rgbEnd[c] @@ -139,11 +138,11 @@ def formatInt(theInt): theVal /= 1000.0 if theVal < 1000.0: if theVal < 10.0: - return "%4.2f%s" % (theVal,pF) + return "%4.2f%s" % (theVal, pF) elif theVal < 100.0: - return "%4.1f%s" % (theVal,pF) + return "%4.1f%s" % (theVal, pF) else: - return "%3.0f%s" % (theVal,pF) + return "%3.0f%s" % (theVal, pF) return "%d" % theInt @@ -169,11 +168,11 @@ def splitVersionNumber(vString): nBits = len(vBits) if nBits > 0: - vMajor = checkInt(vBits[0],0) + vMajor = checkInt(vBits[0], 0) if nBits > 1: - vMinor = checkInt(vBits[1],0) + vMinor = checkInt(vBits[1], 0) if nBits > 2: - vPatch = checkInt(vBits[2],0) + vPatch = checkInt(vBits[2], 0) vInt = vMajor*10000 + vMinor*100 + vPatch diff --git a/nw/config.py b/nw/config.py index 97e78c90..3c3915b7 100644 --- a/nw/config.py +++ b/nw/config.py @@ -29,7 +29,6 @@ import logging import configparser import json import sys -import nw from os import path, mkdir, unlink, rename from time import time @@ -260,12 +259,12 @@ class Config: self.homePath = path.expanduser("~") self.lastPath = self.homePath self.appPath = getattr(sys, "_MEIPASS", path.abspath(path.dirname(__file__))) - self.appRoot = path.join(self.appPath,path.pardir) - self.assetPath = path.join(self.appPath,"assets") - self.themeRoot = path.join(self.assetPath,"themes") - self.graphPath = path.join(self.assetPath,"graphics") - self.dictPath = path.join(self.assetPath,"dict") - self.iconPath = path.join(self.assetPath,"icons") + self.appRoot = path.join(self.appPath, path.pardir) + self.assetPath = path.join(self.appPath, "assets") + self.themeRoot = path.join(self.assetPath, "themes") + self.graphPath = path.join(self.assetPath, "graphics") + self.dictPath = path.join(self.assetPath, "dict") + self.iconPath = path.join(self.assetPath, "icons") self.appIcon = path.join(self.iconPath, "novelwriter.svg") logger.verbose("App path: %s" % self.appPath) @@ -549,85 +548,85 @@ class Config: ## Main cnfSec = "Main" cnfParse.add_section(cnfSec) - cnfParse.set(cnfSec,"timestamp", formatTimeStamp(time())) - cnfParse.set(cnfSec,"theme", str(self.guiTheme)) - cnfParse.set(cnfSec,"syntax", str(self.guiSyntax)) - cnfParse.set(cnfSec,"icons", str(self.guiIcons)) - cnfParse.set(cnfSec,"guidark", str(self.guiDark)) - cnfParse.set(cnfSec,"guifont", str(self.guiFont)) - cnfParse.set(cnfSec,"guifontsize", str(self.guiFontSize)) + cnfParse.set(cnfSec, "timestamp", formatTimeStamp(time())) + cnfParse.set(cnfSec, "theme", str(self.guiTheme)) + cnfParse.set(cnfSec, "syntax", str(self.guiSyntax)) + cnfParse.set(cnfSec, "icons", str(self.guiIcons)) + cnfParse.set(cnfSec, "guidark", str(self.guiDark)) + cnfParse.set(cnfSec, "guifont", str(self.guiFont)) + cnfParse.set(cnfSec, "guifontsize", str(self.guiFontSize)) ## Sizes cnfSec = "Sizes" cnfParse.add_section(cnfSec) - cnfParse.set(cnfSec,"geometry", self._packList(self.winGeometry)) - cnfParse.set(cnfSec,"treecols", self._packList(self.treeColWidth)) - cnfParse.set(cnfSec,"projcols", self._packList(self.projColWidth)) - cnfParse.set(cnfSec,"mainpane", self._packList(self.mainPanePos)) - cnfParse.set(cnfSec,"docpane", self._packList(self.docPanePos)) - cnfParse.set(cnfSec,"viewpane", self._packList(self.viewPanePos)) - cnfParse.set(cnfSec,"outlinepane", self._packList(self.outlnPanePos)) - cnfParse.set(cnfSec,"fullscreen", str(self.isFullScreen)) + cnfParse.set(cnfSec, "geometry", self._packList(self.winGeometry)) + cnfParse.set(cnfSec, "treecols", self._packList(self.treeColWidth)) + cnfParse.set(cnfSec, "projcols", self._packList(self.projColWidth)) + cnfParse.set(cnfSec, "mainpane", self._packList(self.mainPanePos)) + cnfParse.set(cnfSec, "docpane", self._packList(self.docPanePos)) + cnfParse.set(cnfSec, "viewpane", self._packList(self.viewPanePos)) + cnfParse.set(cnfSec, "outlinepane", self._packList(self.outlnPanePos)) + cnfParse.set(cnfSec, "fullscreen", str(self.isFullScreen)) ## Project cnfSec = "Project" cnfParse.add_section(cnfSec) - cnfParse.set(cnfSec,"autosaveproject", str(self.autoSaveProj)) - cnfParse.set(cnfSec,"autosavedoc", str(self.autoSaveDoc)) + cnfParse.set(cnfSec, "autosaveproject", str(self.autoSaveProj)) + cnfParse.set(cnfSec, "autosavedoc", str(self.autoSaveDoc)) ## Editor cnfSec = "Editor" cnfParse.add_section(cnfSec) - cnfParse.set(cnfSec,"textfont", str(self.textFont)) - cnfParse.set(cnfSec,"textsize", str(self.textSize)) - cnfParse.set(cnfSec,"fixedwidth", str(self.textFixedW)) - cnfParse.set(cnfSec,"width", str(self.textWidth)) - cnfParse.set(cnfSec,"margin", str(self.textMargin)) - cnfParse.set(cnfSec,"tabwidth", str(self.tabWidth)) - cnfParse.set(cnfSec,"focuswidth", str(self.focusWidth)) - cnfParse.set(cnfSec,"hidefocusfooter", str(self.hideFocusFooter)) - cnfParse.set(cnfSec,"justify", str(self.doJustify)) - cnfParse.set(cnfSec,"autoselect", str(self.autoSelect)) - cnfParse.set(cnfSec,"autoreplace", str(self.doReplace)) - cnfParse.set(cnfSec,"repsquotes", str(self.doReplaceSQuote)) - cnfParse.set(cnfSec,"repdquotes", str(self.doReplaceDQuote)) - cnfParse.set(cnfSec,"repdash", str(self.doReplaceDash)) - cnfParse.set(cnfSec,"repdots", str(self.doReplaceDots)) - cnfParse.set(cnfSec,"fmtsinglequote", self._packList(self.fmtSingleQuotes)) - cnfParse.set(cnfSec,"fmtdoublequote", self._packList(self.fmtDoubleQuotes)) - cnfParse.set(cnfSec,"spelltool", str(self.spellTool)) - cnfParse.set(cnfSec,"spellcheck", str(self.spellLanguage)) - cnfParse.set(cnfSec,"showtabsnspaces", str(self.showTabsNSpaces)) - cnfParse.set(cnfSec,"showlineendings", str(self.showLineEndings)) - cnfParse.set(cnfSec,"bigdoclimit", str(self.bigDocLimit)) - cnfParse.set(cnfSec,"showfullpath", str(self.showFullPath)) - cnfParse.set(cnfSec,"highlightquotes", str(self.highlightQuotes)) - cnfParse.set(cnfSec,"highlightemph", str(self.highlightEmph)) + cnfParse.set(cnfSec, "textfont", str(self.textFont)) + cnfParse.set(cnfSec, "textsize", str(self.textSize)) + cnfParse.set(cnfSec, "fixedwidth", str(self.textFixedW)) + cnfParse.set(cnfSec, "width", str(self.textWidth)) + cnfParse.set(cnfSec, "margin", str(self.textMargin)) + cnfParse.set(cnfSec, "tabwidth", str(self.tabWidth)) + cnfParse.set(cnfSec, "focuswidth", str(self.focusWidth)) + cnfParse.set(cnfSec, "hidefocusfooter", str(self.hideFocusFooter)) + cnfParse.set(cnfSec, "justify", str(self.doJustify)) + cnfParse.set(cnfSec, "autoselect", str(self.autoSelect)) + cnfParse.set(cnfSec, "autoreplace", str(self.doReplace)) + cnfParse.set(cnfSec, "repsquotes", str(self.doReplaceSQuote)) + cnfParse.set(cnfSec, "repdquotes", str(self.doReplaceDQuote)) + cnfParse.set(cnfSec, "repdash", str(self.doReplaceDash)) + cnfParse.set(cnfSec, "repdots", str(self.doReplaceDots)) + cnfParse.set(cnfSec, "fmtsinglequote", self._packList(self.fmtSingleQuotes)) + cnfParse.set(cnfSec, "fmtdoublequote", self._packList(self.fmtDoubleQuotes)) + cnfParse.set(cnfSec, "spelltool", str(self.spellTool)) + cnfParse.set(cnfSec, "spellcheck", str(self.spellLanguage)) + cnfParse.set(cnfSec, "showtabsnspaces", str(self.showTabsNSpaces)) + cnfParse.set(cnfSec, "showlineendings", str(self.showLineEndings)) + cnfParse.set(cnfSec, "bigdoclimit", str(self.bigDocLimit)) + cnfParse.set(cnfSec, "showfullpath", str(self.showFullPath)) + cnfParse.set(cnfSec, "highlightquotes", str(self.highlightQuotes)) + cnfParse.set(cnfSec, "highlightemph", str(self.highlightEmph)) ## Backup cnfSec = "Backup" cnfParse.add_section(cnfSec) - cnfParse.set(cnfSec,"backuppath", str(self.backupPath)) - cnfParse.set(cnfSec,"backuponclose", str(self.backupOnClose)) - cnfParse.set(cnfSec,"askbeforebackup",str(self.askBeforeBackup)) + cnfParse.set(cnfSec, "backuppath", str(self.backupPath)) + cnfParse.set(cnfSec, "backuponclose", str(self.backupOnClose)) + cnfParse.set(cnfSec, "askbeforebackup", str(self.askBeforeBackup)) ## State cnfSec = "State" cnfParse.add_section(cnfSec) - cnfParse.set(cnfSec,"showrefpanel", str(self.showRefPanel)) - cnfParse.set(cnfSec,"viewcomments", str(self.viewComments)) - cnfParse.set(cnfSec,"viewsynopsis", str(self.viewSynopsis)) - cnfParse.set(cnfSec,"searchcase", str(self.searchCase)) - cnfParse.set(cnfSec,"searchword", str(self.searchWord)) - cnfParse.set(cnfSec,"searchregex", str(self.searchRegEx)) - cnfParse.set(cnfSec,"searchloop", str(self.searchLoop)) - cnfParse.set(cnfSec,"searchnextfile", str(self.searchNextFile)) - cnfParse.set(cnfSec,"searchmatchcap", str(self.searchMatchCap)) + cnfParse.set(cnfSec, "showrefpanel", str(self.showRefPanel)) + cnfParse.set(cnfSec, "viewcomments", str(self.viewComments)) + cnfParse.set(cnfSec, "viewsynopsis", str(self.viewSynopsis)) + cnfParse.set(cnfSec, "searchcase", str(self.searchCase)) + cnfParse.set(cnfSec, "searchword", str(self.searchWord)) + cnfParse.set(cnfSec, "searchregex", str(self.searchRegEx)) + cnfParse.set(cnfSec, "searchloop", str(self.searchLoop)) + cnfParse.set(cnfSec, "searchnextfile", str(self.searchNextFile)) + cnfParse.set(cnfSec, "searchmatchcap", str(self.searchMatchCap)) ## Path cnfSec = "Path" cnfParse.add_section(cnfSec) - cnfParse.set(cnfSec,"lastpath", str(self.lastPath)) + cnfParse.set(cnfSec, "lastpath", str(self.lastPath)) # Write config file cnfPath = path.join(self.confPath, self.confFile) @@ -862,7 +861,7 @@ class Config: for i in range(listLen): try: outData.append(castTo(inData[i])) - except: + except Exception: outData.append(listDefault[i]) return outData @@ -902,16 +901,16 @@ class Config: """Cheks if we have the optional packages used by some features. """ try: - import enchant + import enchant # noqa: F401 self.hasEnchant = True logger.debug("Checking package 'pyenchant': Ok") - except: + except Exception: self.hasEnchant = False logger.debug("Checking package 'pyenchant': Missing") try: self.hasAssistant = which("assistant") - except: + except Exception: self.hasAssistant = False if self.hasAssistant: logger.debug("Checking executable 'assistant': Ok") diff --git a/nw/core/document.py b/nw/core/document.py index 0c29f995..022e608e 100644 --- a/nw/core/document.py +++ b/nw/core/document.py @@ -192,7 +192,7 @@ class NWDoc(): unlink(chkFile) logger.debug("Deleted: %s" % chkFile) except Exception as e: - self.makeAlert(["Could not delete document file.",str(e)], nwAlert.ERROR) + self.makeAlert(["Could not delete document file.", str(e)], nwAlert.ERROR) return False return True diff --git a/nw/core/index.py b/nw/core/index.py index b32c8f38..c542a459 100644 --- a/nw/core/index.py +++ b/nw/core/index.py @@ -27,7 +27,6 @@ import logging import json -import nw from os import path from time import time @@ -135,7 +134,7 @@ class NWIndex(): if path.isfile(indexFile): logger.debug("Loading index file") try: - with open(indexFile,mode="r",encoding="utf8") as inFile: + with open(indexFile, mode="r", encoding="utf8") as inFile: theJson = inFile.read() theData = json.loads(theJson) except Exception as e: @@ -222,7 +221,7 @@ class NWIndex(): if len(self.textCounts[tHandle]) != 3: self.indexBroken = True - except: + except Exception: self.indexBroken = True if self.indexBroken: @@ -520,7 +519,7 @@ class NWIndex(): return isGood # If we're still here, we better check that the references exist - for n in range(1,nBits): + for n in range(1, nBits): if theBits[n] in self.tagIndex: isGood[n] = self.TAG_CLASS[theBits[0]].name == self.tagIndex[theBits[n]][2] @@ -603,8 +602,6 @@ class NWIndex(): by tHandle. """ theRefs = {} - - tItem = self.theProject.projTree[tHandle] if tHandle is None: return theRefs diff --git a/nw/core/item.py b/nw/core/item.py index 0eb4ef26..6e8048f1 100644 --- a/nw/core/item.py +++ b/nw/core/item.py @@ -26,7 +26,6 @@ """ import logging -import nw from lxml import etree @@ -68,24 +67,24 @@ class NWItem(): def packXML(self, xParent): """Packs all the data in the class instance into an XML object. """ - xPack = etree.SubElement(xParent,"item",attrib={ + xPack = etree.SubElement(xParent, "item", attrib={ "handle" : str(self.itemHandle), "order" : str(self.itemOrder), "parent" : str(self.parHandle), }) - xSub = self._subPack(xPack,"name", text=str(self.itemName)) - xSub = self._subPack(xPack,"type", text=str(self.itemType.name)) - xSub = self._subPack(xPack,"class", text=str(self.itemClass.name)) - xSub = self._subPack(xPack,"status", text=str(self.itemStatus)) + self._subPack(xPack, "name", text=str(self.itemName)) + self._subPack(xPack, "type", text=str(self.itemType.name)) + self._subPack(xPack, "class", text=str(self.itemClass.name)) + self._subPack(xPack, "status", text=str(self.itemStatus)) if self.itemType == nwItemType.FILE: - xSub = self._subPack(xPack,"exported", text=str(self.isExported)) - xSub = self._subPack(xPack,"layout", text=str(self.itemLayout.name)) - xSub = self._subPack(xPack,"charCount", text=str(self.charCount), none=False) - xSub = self._subPack(xPack,"wordCount", text=str(self.wordCount), none=False) - xSub = self._subPack(xPack,"paraCount", text=str(self.paraCount), none=False) - xSub = self._subPack(xPack,"cursorPos", text=str(self.cursorPos), none=False) + self._subPack(xPack, "exported", text=str(self.isExported)) + self._subPack(xPack, "layout", text=str(self.itemLayout.name)) + self._subPack(xPack, "charCount", text=str(self.charCount), none=False) + self._subPack(xPack, "wordCount", text=str(self.wordCount), none=False) + self._subPack(xPack, "paraCount", text=str(self.paraCount), none=False) + self._subPack(xPack, "cursorPos", text=str(self.cursorPos), none=False) else: - xSub = self._subPack(xPack,"expanded", text=str(self.isExpanded)) + self._subPack(xPack, "expanded", text=str(self.isExpanded)) return def unpackXML(self, xItem): @@ -130,12 +129,12 @@ class NWItem(): def _subPack(xParent, name, attrib=None, text=None, none=True): """Packs the values into an xml element. """ - if not none and (text == None or text == "None"): + if not none and (text is None or text == "None"): return None xSub = etree.SubElement(xParent, name, attrib=attrib) if text is not None: xSub.text = text - return xSub + return ## # Set Item Values @@ -233,18 +232,18 @@ class NWItem(): """Save the expanded status of an item in the project tree. """ if isinstance(expState, str): - self.isExpanded = expState == str(True) + self.isExpanded = (expState == str(True)) else: - self.isExpanded = expState == True + self.isExpanded = (expState == True) # noqa: E712 return def setExported(self, expState): """Save the export flag. """ if isinstance(expState, str): - self.isExported = expState == str(True) + self.isExported = (expState == str(True)) else: - self.isExported = expState == True + self.isExported = (expState == True) # noqa: E712 return ## diff --git a/nw/core/options.py b/nw/core/options.py index a91f6f68..9a58bf7c 100644 --- a/nw/core/options.py +++ b/nw/core/options.py @@ -153,15 +153,15 @@ class OptionState(): def setValue(self, setGroup, setName, setValue): """Saves a value, with a given group and name. """ - if not setGroup in self.validMap: + if setGroup not in self.validMap: logger.error("Unknown option group '%s'" % setGroup) return False - if not setName in self.validMap[setGroup]: + if setName not in self.validMap[setGroup]: logger.error("Unknown option name '%s'" % setName) return False - if not setGroup in self.theState: + if setGroup not in self.theState: self.theState[setGroup] = {} self.theState[setGroup][setName] = setValue diff --git a/nw/core/project.py b/nw/core/project.py index 3404370e..1844c9cb 100644 --- a/nw/core/project.py +++ b/nw/core/project.py @@ -26,7 +26,6 @@ """ import logging -import json import nw from os import path, mkdir, listdir, unlink, rename, rmdir @@ -206,15 +205,15 @@ class NWProject(): self.spellCheck = False self.autoOutline = True self.statusItems = NWStatus() - self.statusItems.addEntry("New", (100, 100, 100)) - self.statusItems.addEntry("Note", (200, 50, 0)) - self.statusItems.addEntry("Draft", (200, 150, 0)) - self.statusItems.addEntry("Finished",( 50, 200, 0)) + self.statusItems.addEntry("New", (100, 100, 100)) + self.statusItems.addEntry("Note", (200, 50, 0)) + self.statusItems.addEntry("Draft", (200, 150, 0)) + self.statusItems.addEntry("Finished", ( 50, 200, 0)) self.importItems = NWStatus() - self.importItems.addEntry("New", (100, 100, 100)) - self.importItems.addEntry("Minor", (200, 50, 0)) - self.importItems.addEntry("Major", (200, 150, 0)) - self.importItems.addEntry("Main", ( 50, 200, 0)) + self.importItems.addEntry("New", (100, 100, 100)) + self.importItems.addEntry("Minor", (200, 50, 0)) + self.importItems.addEntry("Major", (200, 150, 0)) + self.importItems.addEntry("Main", ( 50, 200, 0)) self.lastEdited = None self.lastViewed = None self.lastWCount = 0 @@ -265,27 +264,28 @@ class NWProject(): if popMinimal: # Creating a minimal project with a few root folders and a # single chapter folder with a single file. - nHandle = self.newRoot("Novel", nwItemClass.NOVEL) - xHandle = self.newRoot("Plot", nwItemClass.PLOT) - xHandle = self.newRoot("Characters", nwItemClass.CHARACTER) - xHandle = self.newRoot("World", nwItemClass.WORLD) - tHandle = self.newFile("Title Page", nwItemClass.NOVEL, nHandle) - dHandle = self.newFolder("New Chapter", nwItemClass.NOVEL, nHandle) - cHandle = self.newFile("New Chapter", nwItemClass.NOVEL, dHandle) - sHandle = self.newFile("New Scene", nwItemClass.NOVEL, dHandle) + xHandle = {} + xHandle[1] = self.newRoot("Novel", nwItemClass.NOVEL) + xHandle[2] = self.newRoot("Plot", nwItemClass.PLOT) + xHandle[3] = self.newRoot("Characters", nwItemClass.CHARACTER) + xHandle[4] = self.newRoot("World", nwItemClass.WORLD) + xHandle[5] = self.newFile("Title Page", nwItemClass.NOVEL, xHandle[1]) + xHandle[6] = self.newFolder("New Chapter", nwItemClass.NOVEL, xHandle[1]) + xHandle[7] = self.newFile("New Chapter", nwItemClass.NOVEL, xHandle[6]) + xHandle[8] = self.newFile("New Scene", nwItemClass.NOVEL, xHandle[6]) - self.projTree.setFileItemLayout(tHandle, nwItemLayout.TITLE) - self.projTree.setFileItemLayout(cHandle, nwItemLayout.CHAPTER) + self.projTree.setFileItemLayout(xHandle[5], nwItemLayout.TITLE) + self.projTree.setFileItemLayout(xHandle[7], nwItemLayout.CHAPTER) - aDoc.openDocument(tHandle, showStatus=False) + aDoc.openDocument(xHandle[5], showStatus=False) aDoc.saveDocument(titlePage) aDoc.clearDocument() - aDoc.openDocument(cHandle, showStatus=False) + aDoc.openDocument(xHandle[7], showStatus=False) aDoc.saveDocument("## New Chapter\n\n") aDoc.clearDocument() - aDoc.openDocument(sHandle, showStatus=False) + aDoc.openDocument(xHandle[8], showStatus=False) aDoc.saveDocument("### New Scene\n\n") aDoc.clearDocument() @@ -421,7 +421,7 @@ class NWProject(): try: nwXML = etree.parse(fileName) except Exception as e: - self.makeAlert(["Failed to parse project xml.",str(e)], nwAlert.ERROR) + self.makeAlert(["Failed to parse project xml.", str(e)], nwAlert.ERROR) # Trying to open backup file instead backFile = fileName[:-3]+"bak" @@ -430,7 +430,7 @@ class NWProject(): try: nwXML = etree.parse(backFile) except Exception as e: - self.makeAlert(["Failed to parse project xml.",str(e)], nwAlert.ERROR) + self.makeAlert(["Failed to parse project xml.", str(e)], nwAlert.ERROR) self.clearProject() return False else: @@ -794,7 +794,7 @@ class NWProject(): logger.debug("Created folder %s" % baseDir) except Exception as e: self.theParent.makeAlert( - ["Could not create backup folder.",str(e)], + ["Could not create backup folder.", str(e)], nwAlert.ERROR ) return False @@ -823,7 +823,7 @@ class NWProject(): logger.info("Backup written to: %s" % archName) except Exception as e: self.theParent.makeAlert( - ["Could not write backup archive.",str(e)], + ["Could not write backup archive.", str(e)], nwAlert.ERROR ) return False @@ -838,7 +838,6 @@ class NWProject(): project path, or if the folder doesn't exist, look for the zip file in the assets folder. """ - projName = projData.get("projName", "Sample Project") projPath = projData.get("projPath", None) if projPath is None: logger.error("No project path set for the example project") @@ -1231,7 +1230,7 @@ class NWProject(): mkdir(thePath) logger.debug("Created folder %s" % thePath) except Exception as e: - self.makeAlert(["Could not create folder.",str(e)], nwAlert.ERROR) + self.makeAlert(["Could not create folder.", str(e)], nwAlert.ERROR) return False return True @@ -1243,7 +1242,8 @@ class NWProject(): for aValue in theValue: if not isinstance(aValue, str): aValue = str(aValue) - if aValue == "" and not allowNone: continue + if aValue == "" and not allowNone: + continue xItem = etree.SubElement(xParent, theName) xItem.text = aValue return @@ -1402,7 +1402,7 @@ class NWProject(): try: rmdir(theData) logger.info("Removed folder: %s" % theFolder) - except: + except Exception: errList.append("Failed to remove: %s" % theFolder) return errList diff --git a/nw/core/spellcheck.py b/nw/core/spellcheck.py index d4740b56..e904eae5 100644 --- a/nw/core/spellcheck.py +++ b/nw/core/spellcheck.py @@ -75,7 +75,7 @@ class NWSpellCheck(): newWord = newWord.strip() self.PROJW.append(newWord) try: - with open(self.projectDict,mode="a+",encoding="utf-8") as outFile: + with open(self.projectDict, mode="a+", encoding="utf-8") as outFile: outFile.write("%s\n" % newWord) except Exception as e: logger.error("Failed to add word to project word list %s" % str(self.projectDict)) @@ -149,7 +149,7 @@ class NWSpellEnchant(NWSpellCheck): self.theDict = enchant.Dict(theLang) self.spellLanguage = theLang logger.debug("Enchant spell checking for language %s loaded" % theLang) - except: + except Exception: logger.error("Failed to load enchant spell checking for language %s" % theLang) self.theDict = NWSpellEnchantDummy() self.spellLanguage = None @@ -186,7 +186,7 @@ class NWSpellEnchant(NWSpellCheck): for spTag, spProvider in enchant.list_dicts(): spName = "%s [%s]" % (self.expandLanguage(spTag), spProvider.name) retList.append((spTag, spName)) - except: + except Exception: logger.error("Failed to list languages for enchant spell checking") return retList @@ -197,7 +197,7 @@ class NWSpellEnchantDummy: """ def __init__(self): return - + def check(self, theWord): return True @@ -231,9 +231,9 @@ class NWSpellSimple(NWSpellCheck): """Load a dictionary as a list from the app assets folder. """ self.WORDS = [] - dictFile = path.join(self.mainConf.dictPath,theLang+".dict") + dictFile = path.join(self.mainConf.dictPath, theLang+".dict") try: - with open(dictFile,mode="r",encoding="utf-8") as wordsFile: + with open(dictFile, mode="r", encoding="utf-8") as wordsFile: for theLine in wordsFile: if len(theLine) == 0 or theLine.startswith("#"): continue @@ -258,7 +258,7 @@ class NWSpellSimple(NWSpellCheck): this function as fast as possible as it is called for every word by the syntax highlighter. """ - theWord = theWord.replace(self.mainConf.fmtApostrophe,"'").lower() + theWord = theWord.replace(self.mainConf.fmtApostrophe, "'").lower() return theWord in self.WORDS def suggestWords(self, theWord): @@ -282,7 +282,7 @@ class NWSpellSimple(NWSpellCheck): continue if firstUp: aWord = aWord[0].upper() + aWord[1:] - aWord = aWord.replace("'",self.mainConf.fmtApostrophe) + aWord = aWord.replace("'", self.mainConf.fmtApostrophe) theOptions.append(aWord) return theOptions diff --git a/nw/core/status.py b/nw/core/status.py index 3dd26b35..eac1a52a 100644 --- a/nw/core/status.py +++ b/nw/core/status.py @@ -26,7 +26,6 @@ """ import logging -import nw from lxml import etree @@ -121,7 +120,7 @@ class NWStatus(): main project file. """ for n in range(self.theLength): - xSub = etree.SubElement(xParent,"entry",attrib={ + xSub = etree.SubElement(xParent, "entry", attrib={ "blue" : str(self.theColours[n][2]), "green" : str(self.theColours[n][1]), "red" : str(self.theColours[n][0]), @@ -138,18 +137,18 @@ class NWStatus(): for xChild in xParent: theLabels.append(xChild.text) if "red" in xChild.attrib: - cR = checkInt(xChild.attrib["red"],0,False) + cR = checkInt(xChild.attrib["red"], 0, False) else: cR = 0 if "green" in xChild.attrib: - cG = checkInt(xChild.attrib["green"],0,False) + cG = checkInt(xChild.attrib["green"], 0, False) else: cG = 0 if "blue" in xChild.attrib: - cB = checkInt(xChild.attrib["blue"],0,False) + cB = checkInt(xChild.attrib["blue"], 0, False) else: cB = 0 - theColours.append((cR,cG,cB)) + theColours.append((cR, cG, cB)) if len(theLabels) > 0: self.theLabels = [] diff --git a/nw/core/tohtml.py b/nw/core/tohtml.py index 95d3089f..74c5a676 100644 --- a/nw/core/tohtml.py +++ b/nw/core/tohtml.py @@ -27,7 +27,6 @@ import logging import re -import nw from nw.core.tokenizer import Tokenizer from nw.constants import nwUnicode, nwLabels, nwKeyWords @@ -153,12 +152,6 @@ class ToHtml(Tokenizer): h3 = "h3" h4 = "h4" - alignHead = self.A_LEFT - if self.doJustify: - alignPar = self.A_JUSTIFY - else: - alignPar = self.A_LEFT - self.theResult = "" thisPar = [] diff --git a/nw/core/tokenizer.py b/nw/core/tokenizer.py index 2ea8f330..0314d9af 100644 --- a/nw/core/tokenizer.py +++ b/nw/core/tokenizer.py @@ -418,11 +418,11 @@ class Tokenizer(): rxThis = theRX.globalMatch(aLine, 0) while rxThis.hasNext(): rxMatch = rxThis.next() - for n in range(1,len(theKeys)): + for n in range(1, len(theKeys)): if theKeys[n] is not None: xPos = rxMatch.capturedStart(n) xLen = rxMatch.capturedLength(n) - fmtPos.append([xPos,xLen,theKeys[n]]) + fmtPos.append([xPos, xLen, theKeys[n]]) # Save the line as is, but append the array of formatting locations # sorted by position @@ -686,7 +686,7 @@ class Tokenizer(): theTitle = theTitle.replace(r"%sc%", str(self.numChScene)) theTitle = theTitle.replace(r"%sca%", str(self.numAbsScene)) if r"%chw%" in theTitle: - theTitle = theTitle.replace(r"%chw%", numberToWord(self.numChapter,"en")) + theTitle = theTitle.replace(r"%chw%", numberToWord(self.numChapter, "en")) if r"%chi%" in theTitle: theTitle = theTitle.replace(r"%chi%", numberToRoman(self.numChapter, True)) if r"%chI%" in theTitle: diff --git a/nw/core/tools.py b/nw/core/tools.py index b46f0db8..ff1976e9 100644 --- a/nw/core/tools.py +++ b/nw/core/tools.py @@ -28,7 +28,6 @@ """ import logging -import nw logger = logging.getLogger(__name__) @@ -73,12 +72,13 @@ def countWords(theText): charCount -= 2 countPara = False - theBuff = aLine.replace("–"," ").replace("—"," ") + theBuff = aLine.replace("–", " ").replace("—", " ") wordCount += len(theBuff.split()) charCount += theLen if countPara and prevEmpty: paraCount += 1 - prevEmpty = countPara == False + + prevEmpty = not countPara return charCount, wordCount, paraCount @@ -139,48 +139,31 @@ def _numberToWordEN(numVal): tenVal = (numVal-oneVal) % 100 hunVal = (numVal-tenVal-oneVal) % 1000 - if hunVal == 100: hunWord = "One Hundred" - if hunVal == 200: hunWord = "Two Hundred" - if hunVal == 300: hunWord = "Three Hundred" - if hunVal == 400: hunWord = "Four Hundred" - if hunVal == 500: hunWord = "Five Hundred" - if hunVal == 600: hunWord = "Six Hundred" - if hunVal == 700: hunWord = "Seven Hundred" - if hunVal == 800: hunWord = "Eight Hundred" - if hunVal == 900: hunWord = "Nine Hundred" - - if tenVal == 20: tenWord = "Twenty" - if tenVal == 30: tenWord = "Thirty" - if tenVal == 40: tenWord = "Forty" - if tenVal == 50: tenWord = "Fifty" - if tenVal == 60: tenWord = "Sixty" - if tenVal == 70: tenWord = "Seventy" - if tenVal == 80: tenWord = "Eighty" - if tenVal == 90: tenWord = "Ninety" + theHundreds = { + 100: "One Hundred", 200: "Two Hundred", 300: "Three Hundred", + 400: "Four Hundred", 500: "Five Hundred", 600: "Six Hundred", + 700: "Seven Hundred", 800: "Eight Hundred", 900: "Nine Hundred", + } + theTens = { + 20: "Twenty", 30: "Thirty", 40: "Forty", 50: "Fifty", + 60: "Sixty", 70: "Seventy", 80: "Eighty", 90: "Ninety", + } + theTeens = { + 0: "Ten", 1: "Eleven", 2: "Twelve", 3: "Thirteen", 4: "Fourteen", + 5: "Fifteen", 6: "Sixteen", 7: "Seventeen", 8: "Eighteen", 9: "Nineteen", + } + theOnes = { + 0: "", 1: "One", 2: "Two", 3: "Three", 4: "Four", + 5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine", + } + hunWord = theHundreds.get(hunVal, "") + tenWord = theTens.get(tenVal, "") if tenVal == 10: - if oneVal == 0: oneWord = "Ten" - if oneVal == 1: oneWord = "Eleven" - if oneVal == 2: oneWord = "Twelve" - if oneVal == 3: oneWord = "Thirteen" - if oneVal == 4: oneWord = "Fourteen" - if oneVal == 5: oneWord = "Fifteen" - if oneVal == 6: oneWord = "Sixteen" - if oneVal == 7: oneWord = "Seventeen" - if oneVal == 8: oneWord = "Eighteen" - if oneVal == 9: oneWord = "Nineteen" + oneWord = theTeens.get(oneVal, "") numWord = ("%s %s" % (hunWord, oneWord)).strip() else: - if oneVal == 0: oneWord = "" - if oneVal == 1: oneWord = "One" - if oneVal == 2: oneWord = "Two" - if oneVal == 3: oneWord = "Three" - if oneVal == 4: oneWord = "Four" - if oneVal == 5: oneWord = "Five" - if oneVal == 6: oneWord = "Six" - if oneVal == 7: oneWord = "Seven" - if oneVal == 8: oneWord = "Eight" - if oneVal == 9: oneWord = "Nine" + oneWord = theOnes.get(oneVal, "") if tenVal == 0: numWord = ("%s %s" % (hunWord, oneWord)).strip() else: diff --git a/nw/core/tree.py b/nw/core/tree.py index bafb5306..a9e77326 100644 --- a/nw/core/tree.py +++ b/nw/core/tree.py @@ -27,7 +27,6 @@ import logging import json -import nw from os import path from lxml import etree @@ -114,7 +113,7 @@ class NWTree(): """Pack the content of the tree into an XML object. """ xContent = etree.SubElement(xParent, "content", attrib={ - "count":str(self._theLength)} + "count": str(self._theLength)} ) for tHandle in self._treeOrder: tItem = self.__getitem__(tHandle) @@ -154,7 +153,7 @@ class NWTree(): outFile.write(" Table of Contents\n") outFile.write("===================\n") outFile.write("\n") - outFile.write(" %-25s %-9s %s\n" %("File Name","Class","Document Label")) + outFile.write(" %-25s %-9s %s\n" %("File Name", "Class", "Document Label")) outFile.write("-"*80+"\n") for tHandle in sorted(self._treeOrder): tItem = self.__getitem__(tHandle) diff --git a/nw/gui/about.py b/nw/gui/about.py index 02f9fa39..6a25af89 100644 --- a/nw/gui/about.py +++ b/nw/gui/about.py @@ -146,9 +146,9 @@ class GuiAbout(QDialog): aboutMsg += ( "

Theme: {name:s}

" "

" - "Author: {author:s}
" - "Credit: {credit:s}
" - "License: {license:s}" + "Author: {author:s}
" + "Credit: {credit:s}
" + "License: {license:s}" "

" ).format( name = theTheme.themeName, @@ -161,9 +161,9 @@ class GuiAbout(QDialog): aboutMsg += ( "

Icons: {name:s}

" "

" - "Author: {author:s}
" - "Credit: {credit:s}
" - "License: {license:s}" + "Author: {author:s}
" + "Credit: {credit:s}
" + "License: {license:s}" "

" ).format( name = theIcons.themeName, @@ -176,9 +176,9 @@ class GuiAbout(QDialog): aboutMsg += ( "

Syntax: {name:s}

" "

" - "Author: {author:s}
" - "Credit: {credit:s}
" - "License: {license:s}" + "Author: {author:s}
" + "Credit: {credit:s}
" + "License: {license:s}" "

" ).format( name = theTheme.syntaxName, diff --git a/nw/gui/build.py b/nw/gui/build.py index ce14db2c..336eb684 100644 --- a/nw/gui/build.py +++ b/nw/gui/build.py @@ -964,7 +964,6 @@ class GuiBuildNovelDocView(QTextBrowser): lblFont.setPointSizeF(0.9*self.theTheme.fontPointSize) fPx = int(1.1*self.theTheme.fontPixelSize) - mPx = self.mainConf.pxInt(4) self.theTitle = QLabel("Build Time: Unknown", self) self.theTitle.setIndent(0) diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index 2ec72b62..5eeef904 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -962,8 +962,9 @@ class GuiDocEditor(QTextEdit): if theSize > self.mainConf.bigDocLimit*1000: logger.info( "The document size is %d > %d, big doc mode is enabled" % ( - theSize, self.mainConf.bigDocLimit*1000 - )) + theSize, self.mainConf.bigDocLimit*1000 + ) + ) self.bigDoc = True else: self.bigDoc = False @@ -1271,7 +1272,7 @@ class GuiDocEditor(QTextEdit): try: isFind = self.lastFind[0] == theCursor.selectionStart() isFind &= self.lastFind[1] == theCursor.selectionEnd() - except: + except Exception: isFind = False if isFind: @@ -1371,7 +1372,6 @@ class GuiDocEditSearch(QFrame): self.doMatchCap = self.mainConf.searchMatchCap mPx = self.mainConf.pxInt(6) - fPx = int(0.9*self.theTheme.fontPixelSize) tPx = int(0.8*self.theTheme.fontPixelSize) boxFont = self.theTheme.guiFont boxFont.setPointSizeF(0.9*self.theTheme.fontPointSize) @@ -1474,12 +1474,12 @@ class GuiDocEditSearch(QFrame): self.showReplace.setStyleSheet(r"QToolButton {border: none; background: transparent;}") self.showReplace.toggled.connect(self._doToggleReplace) - self.searchButton = QPushButton(self.theTheme.getIcon("search"),"") + self.searchButton = QPushButton(self.theTheme.getIcon("search"), "") self.searchButton.setFixedSize(QSize(bPx, bPx)) self.searchButton.setToolTip("Find in current document") self.searchButton.clicked.connect(self._doSearch) - self.replaceButton = QPushButton(self.theTheme.getIcon("search-replace"),"") + self.replaceButton = QPushButton(self.theTheme.getIcon("search-replace"), "") self.replaceButton.setFixedSize(QSize(bPx, bPx)) self.replaceButton.setToolTip("Find and replace in current document") self.replaceButton.clicked.connect(self._doReplace) @@ -1891,7 +1891,6 @@ class GuiDocEditFooter(QWidget): self.sPx = int(round(0.9*self.theTheme.baseIconSize)) fPx = int(0.9*self.theTheme.fontPixelSize) bSp = self.mainConf.pxInt(4) - hSp = self.mainConf.pxInt(8) lblFont = self.font() lblFont.setPointSizeF(0.9*self.theTheme.fontPointSize) @@ -1901,11 +1900,6 @@ class GuiDocEditFooter(QWidget): self.setAutoFillBackground(True) self.setPalette(self.thePalette) - buttonStyle = ( - "QToolButton {{border: none; background: transparent;}} " - "QToolButton:hover {{border: none; background: rgba({0},{1},{2},0.2);}}" - ).format(*self.theTheme.colText) - # Status self.statusIcon = QLabel("") self.statusIcon.setContentsMargins(0, 0, 0, 0) diff --git a/nw/gui/dochighlight.py b/nw/gui/dochighlight.py index 8f32bfca..4be70d5c 100644 --- a/nw/gui/dochighlight.py +++ b/nw/gui/dochighlight.py @@ -55,18 +55,18 @@ class GuiDocHighlighter(QSyntaxHighlighter): self.hRules = [] self.hStyles = {} - self.colHead = QColor(0,0,0) - self.colHeadH = QColor(0,0,0) - self.colEmph = QColor(0,0,0) - self.colDialN = QColor(0,0,0) - self.colDialD = QColor(0,0,0) - self.colDialS = QColor(0,0,0) - self.colComm = QColor(0,0,0) - self.colKey = QColor(0,0,0) - self.colVal = QColor(0,0,0) - self.colSpell = QColor(0,0,0) - self.colTagErr = QColor(0,0,0) - self.colRepTag = QColor(0,0,0) + self.colHead = QColor(0, 0, 0) + self.colHeadH = QColor(0, 0, 0) + self.colEmph = QColor(0, 0, 0) + self.colDialN = QColor(0, 0, 0) + self.colDialD = QColor(0, 0, 0) + self.colDialS = QColor(0, 0, 0) + self.colComm = QColor(0, 0, 0) + self.colKey = QColor(0, 0, 0) + self.colVal = QColor(0, 0, 0) + self.colSpell = QColor(0, 0, 0) + self.colTagErr = QColor(0, 0, 0) + self.colRepTag = QColor(0, 0, 0) self.initHighlighter() @@ -143,7 +143,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): # Quoted Strings if self.mainConf.highlightQuotes: self.hRules.append(( - "{:s}(.+?){:s}".format('"','"'), { + "{:s}(.+?){:s}".format('"', '"'), { 0 : self.hStyles["dialogue1"], } )) diff --git a/nw/gui/docviewer.py b/nw/gui/docviewer.py index 50c86b72..13707ae9 100644 --- a/nw/gui/docviewer.py +++ b/nw/gui/docviewer.py @@ -366,7 +366,6 @@ class GuiDocViewer(QTextBrowser): "}}\n" ).format( textSize = self.mainConf.textSize, - preSize = self.mainConf.textSize*0.9, tColR = self.theTheme.colText[0], tColG = self.theTheme.colText[1], tColB = self.theTheme.colText[2], @@ -701,7 +700,6 @@ class GuiDocViewDetails(QScrollArea): self.refList.setScaledContents(True) self.refList.linkActivated.connect(self._linkClicked) - hCol = self.palette().highlight().color() self.linkStyle = "style='color: rgb({0},{1},{2})'".format( *self.theTheme.colLink ) diff --git a/nw/gui/itemdetails.py b/nw/gui/itemdetails.py index dea27381..f1788f06 100644 --- a/nw/gui/itemdetails.py +++ b/nw/gui/itemdetails.py @@ -238,7 +238,7 @@ class GuiItemDetails(QWidget): else: self.labelFlag.setPixmap(self.expCross) else: - self.labelFlag.setPixmap(QPixmap(1,1)) + self.labelFlag.setPixmap(QPixmap(1, 1)) self.statusFlag.setPixmap(flagIcon.pixmap(self.sPx, self.sPx)) self.classFlag.setText(nwLabels.CLASS_FLAG[nwItem.itemClass]) if nwItem.itemLayout == nwItemLayout.NO_LAYOUT: diff --git a/nw/gui/itemeditor.py b/nw/gui/itemeditor.py index 1a149a09..13024641 100644 --- a/nw/gui/itemeditor.py +++ b/nw/gui/itemeditor.py @@ -96,7 +96,7 @@ class GuiItemEditor(QDialog): for itemLayout in nwItemLayout: if itemLayout in self.validLayouts: - self.editLayout.addItem(nwLabels.LAYOUT_NAME[itemLayout],itemLayout) + self.editLayout.addItem(nwLabels.LAYOUT_NAME[itemLayout], itemLayout) # Export Switch self.textExport = QLabel("Include when building project") diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py index b81bac82..99a4b5c9 100644 --- a/nw/gui/mainmenu.py +++ b/nw/gui/mainmenu.py @@ -607,9 +607,9 @@ class GuiMainMenu(QMenuBar): self.aFindNext = QAction("Find Next", self) self.aFindNext.setStatusTip("Find next occurrence text in document") if self.mainConf.osDarwin: - self.aFindNext.setShortcuts(["Ctrl+G","F3"]) + self.aFindNext.setShortcuts(["Ctrl+G", "F3"]) else: - self.aFindNext.setShortcuts(["F3","Ctrl+G"]) + self.aFindNext.setShortcuts(["F3", "Ctrl+G"]) self.aFindNext.triggered.connect(lambda: self._docAction(nwDocAction.GO_NEXT)) self.srcMenu.addAction(self.aFindNext) @@ -617,9 +617,9 @@ class GuiMainMenu(QMenuBar): self.aFindPrev = QAction("Find Previous", self) self.aFindPrev.setStatusTip("Find previous occurrence text in document") if self.mainConf.osDarwin: - self.aFindPrev.setShortcuts(["Ctrl+Shift+G","Shift+F3"]) + self.aFindPrev.setShortcuts(["Ctrl+Shift+G", "Shift+F3"]) else: - self.aFindPrev.setShortcuts(["Shift+F3","Ctrl+Shift+G"]) + self.aFindPrev.setShortcuts(["Shift+F3", "Ctrl+Shift+G"]) self.aFindPrev.triggered.connect(lambda: self._docAction(nwDocAction.GO_PREV)) self.srcMenu.addAction(self.aFindPrev) @@ -717,7 +717,7 @@ class GuiMainMenu(QMenuBar): # Format > Remove Block Format self.aFmtNoFormat = QAction("Remove Block Format", self) self.aFmtNoFormat.setStatusTip("Strips block format") - self.aFmtNoFormat.setShortcuts(["Ctrl+0","Ctrl+Shift+/"]) + self.aFmtNoFormat.setShortcuts(["Ctrl+0", "Ctrl+Shift+/"]) self.aFmtNoFormat.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_TXT)) self.fmtMenu.addAction(self.aFmtNoFormat) @@ -870,7 +870,7 @@ class GuiMainMenu(QMenuBar): if self.mainConf.hasHelp and self.mainConf.hasAssistant: self.aHelpWeb.setShortcut("Shift+F1") else: - self.aHelpWeb.setShortcuts(["F1","Shift+F1"]) + self.aHelpWeb.setShortcuts(["F1", "Shift+F1"]) self.helpMenu.addAction(self.aHelpWeb) # Document > Go to Website diff --git a/nw/gui/outline.py b/nw/gui/outline.py index c1986b98..039e2f3f 100644 --- a/nw/gui/outline.py +++ b/nw/gui/outline.py @@ -193,7 +193,7 @@ class GuiOutline(QTreeWidget): tHandle = tItem.data(self.colIndex[nwOutline.TITLE], Qt.UserRole) try: tLine = int(tItem.text(self.colIndex[nwOutline.LINE])) - except: + except Exception: tLine = 1 logger.verbose("User selected entry with handle %s on line %s" % (tHandle, tLine)) @@ -254,7 +254,7 @@ class GuiOutline(QTreeWidget): for hName in tempOrder: try: treeOrder.append(nwOutline[hName]) - except: + except Exception: logger.warning("Ignored unknown outline column '%s'" % str(hName)) # Add columns that was not in the file to the treeOrder array. @@ -276,14 +276,14 @@ class GuiOutline(QTreeWidget): for hName in tmpWidth: try: self.colWidth[nwOutline[hName]] = self.mainConf.pxInt(tmpWidth[hName]) - except: + except Exception: logger.warning("Ignored unknown outline column '%s'" % str(hName)) tmpHidden = self.optState.getValue("GuiOutline", "columnHidden", {}) for hName in tmpHidden: try: self.colHidden[nwOutline[hName]] = tmpHidden[hName] - except: + except Exception: logger.warning("Ignored unknown outline column '%s'" % str(hName)) self.headerMenu.setHiddenState(self.colHidden) @@ -374,7 +374,6 @@ class GuiOutline(QTreeWidget): continue tLevel = self.theIndex.novelIndex[tHandle][sTitle]["level"] - tTime = self.theIndex.novelIndex[tHandle][sTitle]["updated"] tItem = self._createTreeItem(tHandle, sTitle, tLevel) self.treeMap[titleKey] = tItem diff --git a/nw/gui/outlinedetails.py b/nw/gui/outlinedetails.py index e18ac9d1..9e53653f 100644 --- a/nw/gui/outlinedetails.py +++ b/nw/gui/outlinedetails.py @@ -30,8 +30,7 @@ import nw from PyQt5.QtCore import Qt from PyQt5.QtWidgets import ( - QScrollArea, QWidget, QGridLayout, QHBoxLayout, QGroupBox, QLabel, - QSizePolicy + QScrollArea, QWidget, QGridLayout, QHBoxLayout, QGroupBox, QLabel ) from nw.constants import nwLabels, nwKeyWords @@ -237,7 +236,7 @@ class GuiOutlineDetails(QScrollArea): nwItem = self.theProject.projTree[tHandle] novIdx = self.theIndex.novelIndex[tHandle][sTitle] theRefs = self.theIndex.getReferences(tHandle, sTitle) - except: + except Exception: return False if novIdx["level"] in self.LVL_MAP: diff --git a/nw/gui/preferences.py b/nw/gui/preferences.py index 8b103194..e7052671 100644 --- a/nw/gui/preferences.py +++ b/nw/gui/preferences.py @@ -342,7 +342,7 @@ class GuiConfigEditGeneralTab(QWidget): dlgOpt |= QFileDialog.ShowDirsOnly dlgOpt |= QFileDialog.DontUseNativeDialog newDir = QFileDialog.getExistingDirectory( - self,"Backup Directory",currDir,options=dlgOpt + self, "Backup Directory", currDir, options=dlgOpt ) if newDir: self.backupPath = newDir @@ -720,7 +720,6 @@ class GuiConfigEditEditingTab(QWidget): def _disableComboItem(self, theList, theValue): """Disable a list item in the combo box. """ - theIdx = theList.findData(theValue) theModel = theList.model() anItem = theModel.item(1) anItem.setFlags(anItem.flags() ^ Qt.ItemIsEnabled) diff --git a/nw/gui/projsettings.py b/nw/gui/projsettings.py index 86ea3ead..44f39d5b 100644 --- a/nw/gui/projsettings.py +++ b/nw/gui/projsettings.py @@ -69,11 +69,11 @@ class GuiProjectSettings(PagedDialog): self.tabImport = GuiProjectEditStatus(self.theParent, self.theProject, False) self.tabReplace = GuiProjectEditReplace(self.theParent, self.theProject) - self.addTab(self.tabMain, "Settings") - self.addTab(self.tabMeta, "Details") - self.addTab(self.tabStatus, "Status") - self.addTab(self.tabImport, "Importance") - self.addTab(self.tabReplace,"Auto-Replace") + self.addTab(self.tabMain, "Settings") + self.addTab(self.tabMeta, "Details") + self.addTab(self.tabStatus, "Status") + self.addTab(self.tabImport, "Importance") + self.addTab(self.tabReplace, "Auto-Replace") self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.accepted.connect(self._doSave) @@ -331,7 +331,7 @@ class GuiProjectEditStatus(QWidget): self.saveButton = QPushButton("Save") self.colPixmap = QPixmap(self.iPx, self.iPx) self.colPixmap.fill(QColor(120, 120, 120)) - self.colButton = QPushButton(QIcon(self.colPixmap),"Colour") + self.colButton = QPushButton(QIcon(self.colPixmap), "Colour") self.colButton.setIconSize(self.colPixmap.rect().size()) self.newButton.clicked.connect(self._newItem) @@ -422,7 +422,6 @@ class GuiProjectEditStatus(QWidget): """ logger.verbose("Save item button clicked") selItem = self._getSelectedItem() - iRow = self.listBox.row(selItem) if selItem is not None: selIdx = selItem.data(Qt.UserRole) self.colData[selIdx] = ( @@ -513,7 +512,7 @@ class GuiProjectEditReplace(QWidget): self.optState.getInt("GuiProjectSettings", "replaceColW", 100) ) self.listBox = QTreeWidget() - self.listBox.setHeaderLabels(["Keyword","Replace With"]) + self.listBox.setHeaderLabels(["Keyword", "Replace With"]) self.listBox.itemSelectionChanged.connect(self._selectedItem) self.listBox.setColumnWidth(0, wCol0) self.listBox.setIndentation(0) @@ -601,8 +600,8 @@ class GuiProjectEditReplace(QWidget): saveKey = self._stripNotAllowed(newKey) if len(saveKey) > 0 and len(newVal) > 0: - selItem.setText(0,"<%s>" % saveKey) - selItem.setText(1,newVal) + selItem.setText(0, "<%s>" % saveKey) + selItem.setText(1, newVal) self.editKey.clear() self.editValue.clear() self.editKey.setEnabled(False) diff --git a/nw/gui/projtree.py b/nw/gui/projtree.py index ce7bf499..a4a9b8f7 100644 --- a/nw/gui/projtree.py +++ b/nw/gui/projtree.py @@ -475,7 +475,6 @@ class GuiProjectTree(QTreeWidget): tName = nwItem.itemName tClass = nwItem.itemClass tHandle = nwItem.itemHandle - pHandle = nwItem.parHandle expIcon = QIcon() @@ -543,7 +542,7 @@ class GuiProjectTree(QTreeWidget): self.theProject.setProjectWordCount(nWords) sWords = self.theProject.getSessionWordCount() - self.theParent.statusBar.setStats(nWords,sWords) + self.theParent.statusBar.setStats(nWords, sWords) return @@ -670,7 +669,6 @@ class GuiProjectTree(QTreeWidget): isNote = snItem.itemLayout == nwItemLayout.NOTE onFile = dnItem.itemType == nwItemType.FILE isRoot = snItem.itemType == nwItemType.ROOT - onRoot = dnItem.itemType == nwItemType.ROOT isOnTop = self.dropIndicatorPosition() == QAbstractItemView.OnItem if (isSame or isNone or isNote) and not (onFile and isOnTop) and not isRoot: logger.debug("Drag'n'drop of item %s accepted" % sHandle) @@ -756,9 +754,9 @@ class GuiProjectTree(QTreeWidget): if nHandle is not None and nHandle in self.theMap: try: byIndex = self.theMap[pHandle].indexOfChild(self.theMap[nHandle]) - except: + except Exception: logger.error("Failed to get index of item with handle %s" % nHandle) - if byIndex >= 0: + if byIndex >= 0: self.theMap[pHandle].insertChild(byIndex+1, newItem) else: self.theMap[pHandle].addChild(newItem) @@ -841,7 +839,7 @@ class GuiProjectTree(QTreeWidget): self.setTreeItemValues(tHandle) self._setTreeChanged(True) - logger.debug("The parent of item %s has been changed to %s" % (tHandle,pHandle)) + logger.debug("The parent of item %s has been changed to %s" % (tHandle, pHandle)) return True diff --git a/nw/gui/projwizard.py b/nw/gui/projwizard.py index e95f0a26..bfadbcea 100644 --- a/nw/gui/projwizard.py +++ b/nw/gui/projwizard.py @@ -214,7 +214,7 @@ class ProjWizardFolderPage(QWizardPage): dlgOpt |= QFileDialog.ShowDirsOnly dlgOpt |= QFileDialog.DontUseNativeDialog projDir = QFileDialog.getExistingDirectory( - self,"Select Project Folder", lastPath, options=dlgOpt + self, "Select Project Folder", lastPath, options=dlgOpt ) if projDir: projName = self.field("projName") diff --git a/nw/gui/statusbar.py b/nw/gui/statusbar.py index 330d7de9..ab5fe23a 100644 --- a/nw/gui/statusbar.py +++ b/nw/gui/statusbar.py @@ -35,7 +35,6 @@ from PyQt5.QtGui import QColor, QPainter from PyQt5.QtWidgets import qApp, QStatusBar, QLabel, QAbstractButton from nw.core import NWSpellCheck -from nw.common import formatInt logger = logging.getLogger(__name__) @@ -212,7 +211,7 @@ class GuiMainStatus(QStatusBar): tH = int(tM/60) tM = tM - tH*60 tS = tS - tM*60 - tH*3600 - theTime = "%02d:%02d:%02d" % (tH,tM,tS) + theTime = "%02d:%02d:%02d" % (tH, tM, tS) self.timeText.setText(theTime) return @@ -242,9 +241,9 @@ class StatusLED(QAbstractButton): """ if theState is None: self._theCol = self.colNone - elif theState == True: + elif theState: self._theCol = self.colTrue - elif theState == False: + elif not theState: self._theCol = self.colFalse else: self._theCol = self.colNone diff --git a/nw/gui/theme.py b/nw/gui/theme.py index 226ccecb..3ec6d717 100644 --- a/nw/gui/theme.py +++ b/nw/gui/theme.py @@ -33,7 +33,7 @@ import nw from os import path, listdir from math import ceil -from PyQt5.QtCore import Qt, QSize +from PyQt5.QtCore import Qt from PyQt5.QtSvg import QSvgWidget from PyQt5.QtWidgets import QStyle, qApp from PyQt5.QtGui import ( @@ -182,7 +182,7 @@ class GuiTheme: for fontFam in listdir(fontAssets): fontDir = path.join(fontAssets, fontFam) if path.isdir(fontDir): - if not fontFam in self.guiFontDB.families(): + if fontFam not in self.guiFontDB.families(): for fontFile in listdir(fontDir): ttfFile = path.join(fontDir, fontFile) if path.isfile(ttfFile) and fontFile.endswith(".ttf"): @@ -260,6 +260,7 @@ class GuiTheme: cssData = inFile.read() except Exception as e: logger.error("Could not load theme css file") + logger.error(str(e)) return False # Config File @@ -269,6 +270,7 @@ class GuiTheme: confParser.read_file(inFile) except Exception as e: logger.error("Could not load theme settings from: %s" % self.confFile) + logger.error(str(e)) return False ## Main @@ -324,6 +326,7 @@ class GuiTheme: confParser.read_file(inFile) except Exception as e: logger.error("Could not load syntax colours from: %s" % self.syntaxFile) + logger.error(str(e)) return False ## Main @@ -431,14 +434,14 @@ class GuiTheme: def _loadColour(self, confParser, cnfSec, cnfName): """Load a colour value from a config string. """ - if confParser.has_option(cnfSec,cnfName): - inData = confParser.get(cnfSec,cnfName).split(",") + if confParser.has_option(cnfSec, cnfName): + inData = confParser.get(cnfSec, cnfName).split(",") outData = [] try: outData.append(int(inData[0])) outData.append(int(inData[1])) outData.append(int(inData[2])) - except: + except Exception: logger.error("Could not load theme colours for '%s' from config file" % cnfName) outData = [0, 0, 0] else: @@ -450,13 +453,13 @@ class GuiTheme: """Set a palette colour value from a config string. """ readCol = [] - if confParser.has_option(cnfSec,cnfName): - inData = confParser.get(cnfSec,cnfName).split(",") + if confParser.has_option(cnfSec, cnfName): + inData = confParser.get(cnfSec, cnfName).split(",") try: readCol.append(int(inData[0])) readCol.append(int(inData[1])) readCol.append(int(inData[2])) - except: + except Exception: logger.error("Could not load theme colours for '%s' from config file" % cnfName) return if len(readCol) == 3: @@ -615,6 +618,7 @@ class GuiIcons: confParser.read_file(inFile) except Exception as e: logger.error("Could not load icon theme settings from: %s" % self.confFile) + logger.error(str(e)) return False ## Main diff --git a/nw/gui/writingstats.py b/nw/gui/writingstats.py index 955376a7..424912e5 100644 --- a/nw/gui/writingstats.py +++ b/nw/gui/writingstats.py @@ -450,7 +450,7 @@ class GuiWritingStats(QDialog): except Exception as e: self.theParent.makeAlert( - ["Failed to read session log file.",str(e)], nwAlert.ERROR + ["Failed to read session log file.", str(e)], nwAlert.ERROR ) return False @@ -577,6 +577,6 @@ class GuiWritingStats(QDialog): tH = int(tM/60) tM = tM - tH*60 tS = tS - tM*60 - tH*3600 - return "%02d:%02d:%02d" % (tH,tM,tS) + return "%02d:%02d:%02d" % (tH, tM, tS) # END Class GuiWritingStats diff --git a/nw/guimain.py b/nw/guimain.py index 73c7eef0..9267a49d 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -269,7 +269,7 @@ class GuiMain(QMainWindow): """ if self.hasProject: msgBox = QMessageBox() - msgRes = msgBox.warning( + msgBox.warning( self, "New Project", "Please close the current project before making a new one." ) @@ -286,9 +286,9 @@ class GuiMain(QMainWindow): logger.error("No projData or projPath set") return False - if path.isfile(path.join(projPath,self.theProject.projFile)) and not forceNew: + if path.isfile(path.join(projPath, self.theProject.projFile)) and not forceNew: msgBox = QMessageBox() - msgRes = msgBox.critical( + msgBox.critical( self, "New Project", "A project already exists in that location. Please choose another folder." ) @@ -391,7 +391,7 @@ class GuiMain(QMainWindow): int(self.theProject.lockedBy[3]) ).strftime("%x %X") ) - except: + except Exception: lockDetails = "" msgBox = QMessageBox() @@ -597,7 +597,7 @@ class GuiMain(QMainWindow): self.mainConf.setLastPath(loadFile) except Exception as e: self.makeAlert( - ["Could not read file. The file must be an existing text file.",str(e)], + ["Could not read file. The file must be an existing text file.", str(e)], nwAlert.ERROR ) return False @@ -713,7 +713,6 @@ class GuiMain(QMainWindow): self.treeView.saveTreeOrder() self.theIndex.clearIndex() - nItems = len(self.theProject.projTree) theDoc = NWDoc(self.theProject, self) for nDone, tItem in enumerate(self.theProject.projTree): diff --git a/tests/nwdummy.py b/tests/nwdummy.py index 2e46352c..a6460c99 100644 --- a/tests/nwdummy.py +++ b/tests/nwdummy.py @@ -12,19 +12,6 @@ class DummyMain(): return def makeAlert(self, theMessage, theLevel): - if theLevel == nwAlert.WARN: - lvlMsg = "WARNING: " - elif theLevel == nwAlert.ERROR: - lvlMsg = "ERROR: " - elif theLevel == nwAlert.BUG: - lvlMsg = "BUG: " - else: - lvlMsg = "" - if isinstance(theMessage, list): - for msgLine in logMsg: - print(lvlMsg+msgLine) - else: - print(lvlMsg+theMessage) return def setStatus(self, theMessage):