Merge branch 'main' into release_0.12

This commit is contained in:
Veronica K. B. Olsen
2020-08-12 22:04:45 +02:00
37 changed files with 315 additions and 322 deletions
+1 -3
View File
@@ -10,9 +10,7 @@ coverage:
project: project:
default: default:
threshold: 1% threshold: 1%
patch: patch: no
default:
threshold: 1%
changes: no changes: no
parsers: parsers:
+27
View File
@@ -0,0 +1,27 @@
name: Flake 8 Checks
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
checkSyntax:
runs-on: ubuntu-latest
steps:
- name: Python Setup
uses: actions/setup-python@v1
with:
python-version: 3.7
architecture: x64
- name: Checkout novelWriter
uses: actions/checkout@v2
- name: Install flake8
run: pip install flake8
- 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
+25
View File
@@ -0,0 +1,25 @@
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/source/conf.py
# Build documentation with MkDocs
#mkdocs:
# configuration: mkdocs.yml
# Optionally build your docs in additional formats such as PDF
formats:
- htmlzip
- epub
- pdf
# Optionally set the version of Python and requirements required to build your docs
python:
version: 3.7
install:
- requirements: docs/source/requirements.txt
+1
View File
@@ -0,0 +1 @@
sphinx_rtd_theme
+8 -8
View File
@@ -153,7 +153,7 @@ def main(sysArgs=None):
# Parse Options # Parse Options
try: try:
inOpts, inRemain = getopt.getopt(sysArgs,shortOpt,longOpt) inOpts, inRemain = getopt.getopt(sysArgs, shortOpt, longOpt)
except getopt.GetoptError as E: except getopt.GetoptError as E:
print(helpMsg) print(helpMsg)
print("ERROR: %s" % str(E)) print("ERROR: %s" % str(E))
@@ -163,7 +163,7 @@ def main(sysArgs=None):
cmdOpen = inRemain[0] cmdOpen = inRemain[0]
for inOpt, inArg in inOpts: for inOpt, inArg in inOpts:
if inOpt in ("-h","--help"): if inOpt in ("-h", "--help"):
print(helpMsg) print(helpMsg)
sys.exit() sys.exit()
elif inOpt in ("-v", "--version"): elif inOpt in ("-v", "--version"):
@@ -179,7 +179,7 @@ def main(sysArgs=None):
elif inOpt == "--logfile": elif inOpt == "--logfile":
logFile = inArg logFile = inArg
toFile = True toFile = True
elif inOpt in ("-q","--quiet"): elif inOpt in ("-q", "--quiet"):
toStd = False toStd = False
elif inOpt == "--verbose": elif inOpt == "--verbose":
debugLevel = VERBOSE debugLevel = VERBOSE
@@ -205,7 +205,7 @@ def main(sysArgs=None):
if path.isfile(logFile+".bak"): if path.isfile(logFile+".bak"):
remove(logFile+".bak") remove(logFile+".bak")
if path.isfile(logFile): if path.isfile(logFile):
rename(logFile,logFile+".bak") rename(logFile, logFile+".bak")
fHandle = logging.FileHandler(logFile) fHandle = logging.FileHandler(logFile)
fHandle.setLevel(debugLevel) fHandle.setLevel(debugLevel)
@@ -239,13 +239,13 @@ def main(sysArgs=None):
) )
try: try:
import PyQt5.QtSvg import PyQt5.QtSvg # noqa: F401
except: except ImportError:
errorData.append("Python module 'PyQt5.QtSvg' is missing.") errorData.append("Python module 'PyQt5.QtSvg' is missing.")
try: try:
import lxml import lxml # noqa: F401
except: except ImportError:
errorData.append("Python module 'lxml' is missing.") errorData.append("Python module 'lxml' is missing.")
if errorData: if errorData:
+12 -13
View File
@@ -26,7 +26,6 @@
""" """
import logging import logging
import nw
from datetime import datetime from datetime import datetime
@@ -38,11 +37,11 @@ def checkString(checkValue, defaultValue, allowNone=False):
"""Check if a variable is a string or a none. """Check if a variable is a string or a none.
""" """
if allowNone: if allowNone:
if checkValue == None: if checkValue is None:
return None return None
if checkValue == "None": if checkValue == "None":
return None return None
if isinstance(checkValue,str): if isinstance(checkValue, str):
return str(checkValue) return str(checkValue)
return defaultValue return defaultValue
@@ -50,20 +49,20 @@ def checkInt(checkValue, defaultValue, allowNone=False):
"""Check if a variable is an integer or a none. """Check if a variable is an integer or a none.
""" """
if allowNone: if allowNone:
if checkValue == None: if checkValue is None:
return None return None
if checkValue == "None": if checkValue == "None":
return None return None
try: try:
return int(checkValue) return int(checkValue)
except: except Exception:
return defaultValue return defaultValue
def checkBool(checkValue, defaultValue, allowNone=False): def checkBool(checkValue, defaultValue, allowNone=False):
"""Check if a variable is a boolean or a none. """Check if a variable is a boolean or a none.
""" """
if allowNone: if allowNone:
if checkValue == None: if checkValue is None:
return None return None
if checkValue == "None": if checkValue == "None":
return None return None
@@ -109,7 +108,7 @@ def colRange(rgbStart, rgbEnd, nStep):
elif nStep == 2: elif nStep == 2:
return [rgbStart, rgbEnd] return [rgbStart, rgbEnd]
dC = [0,0,0] dC = [0, 0, 0]
for c in range(3): for c in range(3):
cA = rgbStart[c] cA = rgbStart[c]
cB = rgbEnd[c] cB = rgbEnd[c]
@@ -139,11 +138,11 @@ def formatInt(theInt):
theVal /= 1000.0 theVal /= 1000.0
if theVal < 1000.0: if theVal < 1000.0:
if theVal < 10.0: if theVal < 10.0:
return "%4.2f%s" % (theVal,pF) return "%4.2f%s" % (theVal, pF)
elif theVal < 100.0: elif theVal < 100.0:
return "%4.1f%s" % (theVal,pF) return "%4.1f%s" % (theVal, pF)
else: else:
return "%3.0f%s" % (theVal,pF) return "%3.0f%s" % (theVal, pF)
return "%d" % theInt return "%d" % theInt
@@ -169,11 +168,11 @@ def splitVersionNumber(vString):
nBits = len(vBits) nBits = len(vBits)
if nBits > 0: if nBits > 0:
vMajor = checkInt(vBits[0],0) vMajor = checkInt(vBits[0], 0)
if nBits > 1: if nBits > 1:
vMinor = checkInt(vBits[1],0) vMinor = checkInt(vBits[1], 0)
if nBits > 2: if nBits > 2:
vPatch = checkInt(vBits[2],0) vPatch = checkInt(vBits[2], 0)
vInt = vMajor*10000 + vMinor*100 + vPatch vInt = vMajor*10000 + vMinor*100 + vPatch
+65 -66
View File
@@ -29,7 +29,6 @@ import logging
import configparser import configparser
import json import json
import sys import sys
import nw
from os import path, mkdir, unlink, rename from os import path, mkdir, unlink, rename
from time import time from time import time
@@ -260,12 +259,12 @@ class Config:
self.homePath = path.expanduser("~") self.homePath = path.expanduser("~")
self.lastPath = self.homePath self.lastPath = self.homePath
self.appPath = getattr(sys, "_MEIPASS", path.abspath(path.dirname(__file__))) self.appPath = getattr(sys, "_MEIPASS", path.abspath(path.dirname(__file__)))
self.appRoot = path.join(self.appPath,path.pardir) self.appRoot = path.join(self.appPath, path.pardir)
self.assetPath = path.join(self.appPath,"assets") self.assetPath = path.join(self.appPath, "assets")
self.themeRoot = path.join(self.assetPath,"themes") self.themeRoot = path.join(self.assetPath, "themes")
self.graphPath = path.join(self.assetPath,"graphics") self.graphPath = path.join(self.assetPath, "graphics")
self.dictPath = path.join(self.assetPath,"dict") self.dictPath = path.join(self.assetPath, "dict")
self.iconPath = path.join(self.assetPath,"icons") self.iconPath = path.join(self.assetPath, "icons")
self.appIcon = path.join(self.iconPath, "novelwriter.svg") self.appIcon = path.join(self.iconPath, "novelwriter.svg")
logger.verbose("App path: %s" % self.appPath) logger.verbose("App path: %s" % self.appPath)
@@ -549,85 +548,85 @@ class Config:
## Main ## Main
cnfSec = "Main" cnfSec = "Main"
cnfParse.add_section(cnfSec) cnfParse.add_section(cnfSec)
cnfParse.set(cnfSec,"timestamp", formatTimeStamp(time())) cnfParse.set(cnfSec, "timestamp", formatTimeStamp(time()))
cnfParse.set(cnfSec,"theme", str(self.guiTheme)) cnfParse.set(cnfSec, "theme", str(self.guiTheme))
cnfParse.set(cnfSec,"syntax", str(self.guiSyntax)) cnfParse.set(cnfSec, "syntax", str(self.guiSyntax))
cnfParse.set(cnfSec,"icons", str(self.guiIcons)) cnfParse.set(cnfSec, "icons", str(self.guiIcons))
cnfParse.set(cnfSec,"guidark", str(self.guiDark)) cnfParse.set(cnfSec, "guidark", str(self.guiDark))
cnfParse.set(cnfSec,"guifont", str(self.guiFont)) cnfParse.set(cnfSec, "guifont", str(self.guiFont))
cnfParse.set(cnfSec,"guifontsize", str(self.guiFontSize)) cnfParse.set(cnfSec, "guifontsize", str(self.guiFontSize))
## Sizes ## Sizes
cnfSec = "Sizes" cnfSec = "Sizes"
cnfParse.add_section(cnfSec) cnfParse.add_section(cnfSec)
cnfParse.set(cnfSec,"geometry", self._packList(self.winGeometry)) cnfParse.set(cnfSec, "geometry", self._packList(self.winGeometry))
cnfParse.set(cnfSec,"treecols", self._packList(self.treeColWidth)) cnfParse.set(cnfSec, "treecols", self._packList(self.treeColWidth))
cnfParse.set(cnfSec,"projcols", self._packList(self.projColWidth)) cnfParse.set(cnfSec, "projcols", self._packList(self.projColWidth))
cnfParse.set(cnfSec,"mainpane", self._packList(self.mainPanePos)) cnfParse.set(cnfSec, "mainpane", self._packList(self.mainPanePos))
cnfParse.set(cnfSec,"docpane", self._packList(self.docPanePos)) cnfParse.set(cnfSec, "docpane", self._packList(self.docPanePos))
cnfParse.set(cnfSec,"viewpane", self._packList(self.viewPanePos)) cnfParse.set(cnfSec, "viewpane", self._packList(self.viewPanePos))
cnfParse.set(cnfSec,"outlinepane", self._packList(self.outlnPanePos)) cnfParse.set(cnfSec, "outlinepane", self._packList(self.outlnPanePos))
cnfParse.set(cnfSec,"fullscreen", str(self.isFullScreen)) cnfParse.set(cnfSec, "fullscreen", str(self.isFullScreen))
## Project ## Project
cnfSec = "Project" cnfSec = "Project"
cnfParse.add_section(cnfSec) cnfParse.add_section(cnfSec)
cnfParse.set(cnfSec,"autosaveproject", str(self.autoSaveProj)) cnfParse.set(cnfSec, "autosaveproject", str(self.autoSaveProj))
cnfParse.set(cnfSec,"autosavedoc", str(self.autoSaveDoc)) cnfParse.set(cnfSec, "autosavedoc", str(self.autoSaveDoc))
## Editor ## Editor
cnfSec = "Editor" cnfSec = "Editor"
cnfParse.add_section(cnfSec) cnfParse.add_section(cnfSec)
cnfParse.set(cnfSec,"textfont", str(self.textFont)) cnfParse.set(cnfSec, "textfont", str(self.textFont))
cnfParse.set(cnfSec,"textsize", str(self.textSize)) cnfParse.set(cnfSec, "textsize", str(self.textSize))
cnfParse.set(cnfSec,"fixedwidth", str(self.textFixedW)) cnfParse.set(cnfSec, "fixedwidth", str(self.textFixedW))
cnfParse.set(cnfSec,"width", str(self.textWidth)) cnfParse.set(cnfSec, "width", str(self.textWidth))
cnfParse.set(cnfSec,"margin", str(self.textMargin)) cnfParse.set(cnfSec, "margin", str(self.textMargin))
cnfParse.set(cnfSec,"tabwidth", str(self.tabWidth)) cnfParse.set(cnfSec, "tabwidth", str(self.tabWidth))
cnfParse.set(cnfSec,"focuswidth", str(self.focusWidth)) cnfParse.set(cnfSec, "focuswidth", str(self.focusWidth))
cnfParse.set(cnfSec,"hidefocusfooter", str(self.hideFocusFooter)) cnfParse.set(cnfSec, "hidefocusfooter", str(self.hideFocusFooter))
cnfParse.set(cnfSec,"justify", str(self.doJustify)) cnfParse.set(cnfSec, "justify", str(self.doJustify))
cnfParse.set(cnfSec,"autoselect", str(self.autoSelect)) cnfParse.set(cnfSec, "autoselect", str(self.autoSelect))
cnfParse.set(cnfSec,"autoreplace", str(self.doReplace)) cnfParse.set(cnfSec, "autoreplace", str(self.doReplace))
cnfParse.set(cnfSec,"repsquotes", str(self.doReplaceSQuote)) cnfParse.set(cnfSec, "repsquotes", str(self.doReplaceSQuote))
cnfParse.set(cnfSec,"repdquotes", str(self.doReplaceDQuote)) cnfParse.set(cnfSec, "repdquotes", str(self.doReplaceDQuote))
cnfParse.set(cnfSec,"repdash", str(self.doReplaceDash)) cnfParse.set(cnfSec, "repdash", str(self.doReplaceDash))
cnfParse.set(cnfSec,"repdots", str(self.doReplaceDots)) cnfParse.set(cnfSec, "repdots", str(self.doReplaceDots))
cnfParse.set(cnfSec,"fmtsinglequote", self._packList(self.fmtSingleQuotes)) cnfParse.set(cnfSec, "fmtsinglequote", self._packList(self.fmtSingleQuotes))
cnfParse.set(cnfSec,"fmtdoublequote", self._packList(self.fmtDoubleQuotes)) cnfParse.set(cnfSec, "fmtdoublequote", self._packList(self.fmtDoubleQuotes))
cnfParse.set(cnfSec,"spelltool", str(self.spellTool)) cnfParse.set(cnfSec, "spelltool", str(self.spellTool))
cnfParse.set(cnfSec,"spellcheck", str(self.spellLanguage)) cnfParse.set(cnfSec, "spellcheck", str(self.spellLanguage))
cnfParse.set(cnfSec,"showtabsnspaces", str(self.showTabsNSpaces)) cnfParse.set(cnfSec, "showtabsnspaces", str(self.showTabsNSpaces))
cnfParse.set(cnfSec,"showlineendings", str(self.showLineEndings)) cnfParse.set(cnfSec, "showlineendings", str(self.showLineEndings))
cnfParse.set(cnfSec,"bigdoclimit", str(self.bigDocLimit)) cnfParse.set(cnfSec, "bigdoclimit", str(self.bigDocLimit))
cnfParse.set(cnfSec,"showfullpath", str(self.showFullPath)) cnfParse.set(cnfSec, "showfullpath", str(self.showFullPath))
cnfParse.set(cnfSec,"highlightquotes", str(self.highlightQuotes)) cnfParse.set(cnfSec, "highlightquotes", str(self.highlightQuotes))
cnfParse.set(cnfSec,"highlightemph", str(self.highlightEmph)) cnfParse.set(cnfSec, "highlightemph", str(self.highlightEmph))
## Backup ## Backup
cnfSec = "Backup" cnfSec = "Backup"
cnfParse.add_section(cnfSec) cnfParse.add_section(cnfSec)
cnfParse.set(cnfSec,"backuppath", str(self.backupPath)) cnfParse.set(cnfSec, "backuppath", str(self.backupPath))
cnfParse.set(cnfSec,"backuponclose", str(self.backupOnClose)) cnfParse.set(cnfSec, "backuponclose", str(self.backupOnClose))
cnfParse.set(cnfSec,"askbeforebackup",str(self.askBeforeBackup)) cnfParse.set(cnfSec, "askbeforebackup", str(self.askBeforeBackup))
## State ## State
cnfSec = "State" cnfSec = "State"
cnfParse.add_section(cnfSec) cnfParse.add_section(cnfSec)
cnfParse.set(cnfSec,"showrefpanel", str(self.showRefPanel)) cnfParse.set(cnfSec, "showrefpanel", str(self.showRefPanel))
cnfParse.set(cnfSec,"viewcomments", str(self.viewComments)) cnfParse.set(cnfSec, "viewcomments", str(self.viewComments))
cnfParse.set(cnfSec,"viewsynopsis", str(self.viewSynopsis)) cnfParse.set(cnfSec, "viewsynopsis", str(self.viewSynopsis))
cnfParse.set(cnfSec,"searchcase", str(self.searchCase)) cnfParse.set(cnfSec, "searchcase", str(self.searchCase))
cnfParse.set(cnfSec,"searchword", str(self.searchWord)) cnfParse.set(cnfSec, "searchword", str(self.searchWord))
cnfParse.set(cnfSec,"searchregex", str(self.searchRegEx)) cnfParse.set(cnfSec, "searchregex", str(self.searchRegEx))
cnfParse.set(cnfSec,"searchloop", str(self.searchLoop)) cnfParse.set(cnfSec, "searchloop", str(self.searchLoop))
cnfParse.set(cnfSec,"searchnextfile", str(self.searchNextFile)) cnfParse.set(cnfSec, "searchnextfile", str(self.searchNextFile))
cnfParse.set(cnfSec,"searchmatchcap", str(self.searchMatchCap)) cnfParse.set(cnfSec, "searchmatchcap", str(self.searchMatchCap))
## Path ## Path
cnfSec = "Path" cnfSec = "Path"
cnfParse.add_section(cnfSec) cnfParse.add_section(cnfSec)
cnfParse.set(cnfSec,"lastpath", str(self.lastPath)) cnfParse.set(cnfSec, "lastpath", str(self.lastPath))
# Write config file # Write config file
cnfPath = path.join(self.confPath, self.confFile) cnfPath = path.join(self.confPath, self.confFile)
@@ -862,7 +861,7 @@ class Config:
for i in range(listLen): for i in range(listLen):
try: try:
outData.append(castTo(inData[i])) outData.append(castTo(inData[i]))
except: except Exception:
outData.append(listDefault[i]) outData.append(listDefault[i])
return outData return outData
@@ -902,16 +901,16 @@ class Config:
"""Cheks if we have the optional packages used by some features. """Cheks if we have the optional packages used by some features.
""" """
try: try:
import enchant import enchant # noqa: F401
self.hasEnchant = True self.hasEnchant = True
logger.debug("Checking package 'pyenchant': Ok") logger.debug("Checking package 'pyenchant': Ok")
except: except Exception:
self.hasEnchant = False self.hasEnchant = False
logger.debug("Checking package 'pyenchant': Missing") logger.debug("Checking package 'pyenchant': Missing")
try: try:
self.hasAssistant = which("assistant") self.hasAssistant = which("assistant")
except: except Exception:
self.hasAssistant = False self.hasAssistant = False
if self.hasAssistant: if self.hasAssistant:
logger.debug("Checking executable 'assistant': Ok") logger.debug("Checking executable 'assistant': Ok")
+1 -1
View File
@@ -192,7 +192,7 @@ class NWDoc():
unlink(chkFile) unlink(chkFile)
logger.debug("Deleted: %s" % chkFile) logger.debug("Deleted: %s" % chkFile)
except Exception as e: 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 False
return True return True
+3 -6
View File
@@ -27,7 +27,6 @@
import logging import logging
import json import json
import nw
from os import path from os import path
from time import time from time import time
@@ -135,7 +134,7 @@ class NWIndex():
if path.isfile(indexFile): if path.isfile(indexFile):
logger.debug("Loading index file") logger.debug("Loading index file")
try: try:
with open(indexFile,mode="r",encoding="utf8") as inFile: with open(indexFile, mode="r", encoding="utf8") as inFile:
theJson = inFile.read() theJson = inFile.read()
theData = json.loads(theJson) theData = json.loads(theJson)
except Exception as e: except Exception as e:
@@ -222,7 +221,7 @@ class NWIndex():
if len(self.textCounts[tHandle]) != 3: if len(self.textCounts[tHandle]) != 3:
self.indexBroken = True self.indexBroken = True
except: except Exception:
self.indexBroken = True self.indexBroken = True
if self.indexBroken: if self.indexBroken:
@@ -520,7 +519,7 @@ class NWIndex():
return isGood return isGood
# If we're still here, we better check that the references exist # 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: if theBits[n] in self.tagIndex:
isGood[n] = self.TAG_CLASS[theBits[0]].name == self.tagIndex[theBits[n]][2] isGood[n] = self.TAG_CLASS[theBits[0]].name == self.tagIndex[theBits[n]][2]
@@ -603,8 +602,6 @@ class NWIndex():
by tHandle. by tHandle.
""" """
theRefs = {} theRefs = {}
tItem = self.theProject.projTree[tHandle]
if tHandle is None: if tHandle is None:
return theRefs return theRefs
+18 -19
View File
@@ -26,7 +26,6 @@
""" """
import logging import logging
import nw
from lxml import etree from lxml import etree
@@ -68,24 +67,24 @@ class NWItem():
def packXML(self, xParent): def packXML(self, xParent):
"""Packs all the data in the class instance into an XML object. """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), "handle" : str(self.itemHandle),
"order" : str(self.itemOrder), "order" : str(self.itemOrder),
"parent" : str(self.parHandle), "parent" : str(self.parHandle),
}) })
xSub = self._subPack(xPack,"name", text=str(self.itemName)) self._subPack(xPack, "name", text=str(self.itemName))
xSub = self._subPack(xPack,"type", text=str(self.itemType.name)) self._subPack(xPack, "type", text=str(self.itemType.name))
xSub = self._subPack(xPack,"class", text=str(self.itemClass.name)) self._subPack(xPack, "class", text=str(self.itemClass.name))
xSub = self._subPack(xPack,"status", text=str(self.itemStatus)) self._subPack(xPack, "status", text=str(self.itemStatus))
if self.itemType == nwItemType.FILE: if self.itemType == nwItemType.FILE:
xSub = self._subPack(xPack,"exported", text=str(self.isExported)) self._subPack(xPack, "exported", text=str(self.isExported))
xSub = self._subPack(xPack,"layout", text=str(self.itemLayout.name)) self._subPack(xPack, "layout", text=str(self.itemLayout.name))
xSub = self._subPack(xPack,"charCount", text=str(self.charCount), none=False) self._subPack(xPack, "charCount", text=str(self.charCount), none=False)
xSub = self._subPack(xPack,"wordCount", text=str(self.wordCount), none=False) self._subPack(xPack, "wordCount", text=str(self.wordCount), none=False)
xSub = self._subPack(xPack,"paraCount", text=str(self.paraCount), none=False) self._subPack(xPack, "paraCount", text=str(self.paraCount), none=False)
xSub = self._subPack(xPack,"cursorPos", text=str(self.cursorPos), none=False) self._subPack(xPack, "cursorPos", text=str(self.cursorPos), none=False)
else: else:
xSub = 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):
@@ -130,12 +129,12 @@ class NWItem():
def _subPack(xParent, name, attrib=None, text=None, none=True): def _subPack(xParent, name, attrib=None, text=None, none=True):
"""Packs the values into an xml element. """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 return None
xSub = etree.SubElement(xParent, name, attrib=attrib) xSub = etree.SubElement(xParent, name, attrib=attrib)
if text is not None: if text is not None:
xSub.text = text xSub.text = text
return xSub return
## ##
# Set Item Values # Set Item Values
@@ -233,18 +232,18 @@ class NWItem():
"""Save the expanded status of an item in the project tree. """Save the expanded status of an item in the project tree.
""" """
if isinstance(expState, str): if isinstance(expState, str):
self.isExpanded = expState == str(True) self.isExpanded = (expState == str(True))
else: else:
self.isExpanded = expState == True self.isExpanded = (expState == True) # noqa: E712
return return
def setExported(self, expState): def setExported(self, expState):
"""Save the export flag. """Save the export flag.
""" """
if isinstance(expState, str): if isinstance(expState, str):
self.isExported = expState == str(True) self.isExported = (expState == str(True))
else: else:
self.isExported = expState == True self.isExported = (expState == True) # noqa: E712
return return
## ##
+3 -3
View File
@@ -153,15 +153,15 @@ class OptionState():
def setValue(self, setGroup, setName, setValue): def setValue(self, setGroup, setName, setValue):
"""Saves a value, with a given group and name. """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) logger.error("Unknown option group '%s'" % setGroup)
return False return False
if not setName in self.validMap[setGroup]: if setName not in self.validMap[setGroup]:
logger.error("Unknown option name '%s'" % setName) logger.error("Unknown option name '%s'" % setName)
return False return False
if not setGroup in self.theState: if setGroup not in self.theState:
self.theState[setGroup] = {} self.theState[setGroup] = {}
self.theState[setGroup][setName] = setValue self.theState[setGroup][setName] = setValue
+30 -30
View File
@@ -26,7 +26,6 @@
""" """
import logging import logging
import json
import nw import nw
from os import path, mkdir, listdir, unlink, rename, rmdir from os import path, mkdir, listdir, unlink, rename, rmdir
@@ -206,15 +205,15 @@ class NWProject():
self.spellCheck = False self.spellCheck = False
self.autoOutline = True self.autoOutline = True
self.statusItems = NWStatus() self.statusItems = NWStatus()
self.statusItems.addEntry("New", (100, 100, 100)) self.statusItems.addEntry("New", (100, 100, 100))
self.statusItems.addEntry("Note", (200, 50, 0)) self.statusItems.addEntry("Note", (200, 50, 0))
self.statusItems.addEntry("Draft", (200, 150, 0)) self.statusItems.addEntry("Draft", (200, 150, 0))
self.statusItems.addEntry("Finished",( 50, 200, 0)) self.statusItems.addEntry("Finished", ( 50, 200, 0))
self.importItems = NWStatus() self.importItems = NWStatus()
self.importItems.addEntry("New", (100, 100, 100)) self.importItems.addEntry("New", (100, 100, 100))
self.importItems.addEntry("Minor", (200, 50, 0)) self.importItems.addEntry("Minor", (200, 50, 0))
self.importItems.addEntry("Major", (200, 150, 0)) self.importItems.addEntry("Major", (200, 150, 0))
self.importItems.addEntry("Main", ( 50, 200, 0)) self.importItems.addEntry("Main", ( 50, 200, 0))
self.lastEdited = None self.lastEdited = None
self.lastViewed = None self.lastViewed = None
self.lastWCount = 0 self.lastWCount = 0
@@ -265,27 +264,28 @@ class NWProject():
if popMinimal: if popMinimal:
# Creating a minimal project with a few root folders and a # Creating a minimal project with a few root folders and a
# single chapter folder with a single file. # single chapter folder with a single file.
nHandle = self.newRoot("Novel", nwItemClass.NOVEL) xHandle = {}
xHandle = self.newRoot("Plot", nwItemClass.PLOT) xHandle[1] = self.newRoot("Novel", nwItemClass.NOVEL)
xHandle = self.newRoot("Characters", nwItemClass.CHARACTER) xHandle[2] = self.newRoot("Plot", nwItemClass.PLOT)
xHandle = self.newRoot("World", nwItemClass.WORLD) xHandle[3] = self.newRoot("Characters", nwItemClass.CHARACTER)
tHandle = self.newFile("Title Page", nwItemClass.NOVEL, nHandle) xHandle[4] = self.newRoot("World", nwItemClass.WORLD)
dHandle = self.newFolder("New Chapter", nwItemClass.NOVEL, nHandle) xHandle[5] = self.newFile("Title Page", nwItemClass.NOVEL, xHandle[1])
cHandle = self.newFile("New Chapter", nwItemClass.NOVEL, dHandle) xHandle[6] = self.newFolder("New Chapter", nwItemClass.NOVEL, xHandle[1])
sHandle = self.newFile("New Scene", nwItemClass.NOVEL, dHandle) 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(xHandle[5], nwItemLayout.TITLE)
self.projTree.setFileItemLayout(cHandle, nwItemLayout.CHAPTER) self.projTree.setFileItemLayout(xHandle[7], nwItemLayout.CHAPTER)
aDoc.openDocument(tHandle, showStatus=False) aDoc.openDocument(xHandle[5], showStatus=False)
aDoc.saveDocument(titlePage) aDoc.saveDocument(titlePage)
aDoc.clearDocument() aDoc.clearDocument()
aDoc.openDocument(cHandle, showStatus=False) aDoc.openDocument(xHandle[7], showStatus=False)
aDoc.saveDocument("## New Chapter\n\n") aDoc.saveDocument("## New Chapter\n\n")
aDoc.clearDocument() aDoc.clearDocument()
aDoc.openDocument(sHandle, showStatus=False) aDoc.openDocument(xHandle[8], showStatus=False)
aDoc.saveDocument("### New Scene\n\n") aDoc.saveDocument("### New Scene\n\n")
aDoc.clearDocument() aDoc.clearDocument()
@@ -421,7 +421,7 @@ class NWProject():
try: try:
nwXML = etree.parse(fileName) nwXML = etree.parse(fileName)
except Exception as e: 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 # Trying to open backup file instead
backFile = fileName[:-3]+"bak" backFile = fileName[:-3]+"bak"
@@ -430,7 +430,7 @@ class NWProject():
try: try:
nwXML = etree.parse(backFile) nwXML = etree.parse(backFile)
except Exception as e: 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() self.clearProject()
return False return False
else: else:
@@ -794,7 +794,7 @@ class NWProject():
logger.debug("Created folder %s" % baseDir) logger.debug("Created folder %s" % baseDir)
except Exception as e: except Exception as e:
self.theParent.makeAlert( self.theParent.makeAlert(
["Could not create backup folder.",str(e)], ["Could not create backup folder.", str(e)],
nwAlert.ERROR nwAlert.ERROR
) )
return False return False
@@ -823,7 +823,7 @@ class NWProject():
logger.info("Backup written to: %s" % archName) logger.info("Backup written to: %s" % archName)
except Exception as e: except Exception as e:
self.theParent.makeAlert( self.theParent.makeAlert(
["Could not write backup archive.",str(e)], ["Could not write backup archive.", str(e)],
nwAlert.ERROR nwAlert.ERROR
) )
return False return False
@@ -838,7 +838,6 @@ class NWProject():
project path, or if the folder doesn't exist, look for the zip project path, or if the folder doesn't exist, look for the zip
file in the assets folder. file in the assets folder.
""" """
projName = projData.get("projName", "Sample Project")
projPath = projData.get("projPath", None) projPath = projData.get("projPath", None)
if projPath is None: if projPath is None:
logger.error("No project path set for the example project") logger.error("No project path set for the example project")
@@ -1231,7 +1230,7 @@ class NWProject():
mkdir(thePath) mkdir(thePath)
logger.debug("Created folder %s" % thePath) logger.debug("Created folder %s" % thePath)
except Exception as e: 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 False
return True return True
@@ -1243,7 +1242,8 @@ class NWProject():
for aValue in theValue: for aValue in theValue:
if not isinstance(aValue, str): if not isinstance(aValue, str):
aValue = str(aValue) aValue = str(aValue)
if aValue == "" and not allowNone: continue if aValue == "" and not allowNone:
continue
xItem = etree.SubElement(xParent, theName) xItem = etree.SubElement(xParent, theName)
xItem.text = aValue xItem.text = aValue
return return
@@ -1402,7 +1402,7 @@ class NWProject():
try: try:
rmdir(theData) rmdir(theData)
logger.info("Removed folder: %s" % theFolder) logger.info("Removed folder: %s" % theFolder)
except: except Exception:
errList.append("Failed to remove: %s" % theFolder) errList.append("Failed to remove: %s" % theFolder)
return errList return errList
+8 -8
View File
@@ -75,7 +75,7 @@ class NWSpellCheck():
newWord = newWord.strip() newWord = newWord.strip()
self.PROJW.append(newWord) self.PROJW.append(newWord)
try: 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) outFile.write("%s\n" % newWord)
except Exception as e: except Exception as e:
logger.error("Failed to add word to project word list %s" % str(self.projectDict)) 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.theDict = enchant.Dict(theLang)
self.spellLanguage = theLang self.spellLanguage = theLang
logger.debug("Enchant spell checking for language %s loaded" % 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) logger.error("Failed to load enchant spell checking for language %s" % theLang)
self.theDict = NWSpellEnchantDummy() self.theDict = NWSpellEnchantDummy()
self.spellLanguage = None self.spellLanguage = None
@@ -186,7 +186,7 @@ class NWSpellEnchant(NWSpellCheck):
for spTag, spProvider in enchant.list_dicts(): for spTag, spProvider in enchant.list_dicts():
spName = "%s [%s]" % (self.expandLanguage(spTag), spProvider.name) spName = "%s [%s]" % (self.expandLanguage(spTag), spProvider.name)
retList.append((spTag, spName)) retList.append((spTag, spName))
except: except Exception:
logger.error("Failed to list languages for enchant spell checking") logger.error("Failed to list languages for enchant spell checking")
return retList return retList
@@ -197,7 +197,7 @@ class NWSpellEnchantDummy:
""" """
def __init__(self): def __init__(self):
return return
def check(self, theWord): def check(self, theWord):
return True return True
@@ -231,9 +231,9 @@ class NWSpellSimple(NWSpellCheck):
"""Load a dictionary as a list from the app assets folder. """Load a dictionary as a list from the app assets folder.
""" """
self.WORDS = [] self.WORDS = []
dictFile = path.join(self.mainConf.dictPath,theLang+".dict") dictFile = path.join(self.mainConf.dictPath, theLang+".dict")
try: 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: for theLine in wordsFile:
if len(theLine) == 0 or theLine.startswith("#"): if len(theLine) == 0 or theLine.startswith("#"):
continue continue
@@ -258,7 +258,7 @@ class NWSpellSimple(NWSpellCheck):
this function as fast as possible as it is called for every this function as fast as possible as it is called for every
word by the syntax highlighter. word by the syntax highlighter.
""" """
theWord = theWord.replace(self.mainConf.fmtApostrophe,"'").lower() theWord = theWord.replace(self.mainConf.fmtApostrophe, "'").lower()
return theWord in self.WORDS return theWord in self.WORDS
def suggestWords(self, theWord): def suggestWords(self, theWord):
@@ -282,7 +282,7 @@ class NWSpellSimple(NWSpellCheck):
continue continue
if firstUp: if firstUp:
aWord = aWord[0].upper() + aWord[1:] aWord = aWord[0].upper() + aWord[1:]
aWord = aWord.replace("'",self.mainConf.fmtApostrophe) aWord = aWord.replace("'", self.mainConf.fmtApostrophe)
theOptions.append(aWord) theOptions.append(aWord)
return theOptions return theOptions
+5 -6
View File
@@ -26,7 +26,6 @@
""" """
import logging import logging
import nw
from lxml import etree from lxml import etree
@@ -121,7 +120,7 @@ class NWStatus():
main project file. main project file.
""" """
for n in range(self.theLength): for n in range(self.theLength):
xSub = etree.SubElement(xParent,"entry",attrib={ xSub = etree.SubElement(xParent, "entry", attrib={
"blue" : str(self.theColours[n][2]), "blue" : str(self.theColours[n][2]),
"green" : str(self.theColours[n][1]), "green" : str(self.theColours[n][1]),
"red" : str(self.theColours[n][0]), "red" : str(self.theColours[n][0]),
@@ -138,18 +137,18 @@ class NWStatus():
for xChild in xParent: for xChild in xParent:
theLabels.append(xChild.text) theLabels.append(xChild.text)
if "red" in xChild.attrib: if "red" in xChild.attrib:
cR = checkInt(xChild.attrib["red"],0,False) cR = checkInt(xChild.attrib["red"], 0, False)
else: else:
cR = 0 cR = 0
if "green" in xChild.attrib: if "green" in xChild.attrib:
cG = checkInt(xChild.attrib["green"],0,False) cG = checkInt(xChild.attrib["green"], 0, False)
else: else:
cG = 0 cG = 0
if "blue" in xChild.attrib: if "blue" in xChild.attrib:
cB = checkInt(xChild.attrib["blue"],0,False) cB = checkInt(xChild.attrib["blue"], 0, False)
else: else:
cB = 0 cB = 0
theColours.append((cR,cG,cB)) theColours.append((cR, cG, cB))
if len(theLabels) > 0: if len(theLabels) > 0:
self.theLabels = [] self.theLabels = []
-7
View File
@@ -27,7 +27,6 @@
import logging import logging
import re import re
import nw
from nw.core.tokenizer import Tokenizer from nw.core.tokenizer import Tokenizer
from nw.constants import nwUnicode, nwLabels, nwKeyWords from nw.constants import nwUnicode, nwLabels, nwKeyWords
@@ -153,12 +152,6 @@ class ToHtml(Tokenizer):
h3 = "h3" h3 = "h3"
h4 = "h4" h4 = "h4"
alignHead = self.A_LEFT
if self.doJustify:
alignPar = self.A_JUSTIFY
else:
alignPar = self.A_LEFT
self.theResult = "" self.theResult = ""
thisPar = [] thisPar = []
+3 -3
View File
@@ -418,11 +418,11 @@ class Tokenizer():
rxThis = theRX.globalMatch(aLine, 0) rxThis = theRX.globalMatch(aLine, 0)
while rxThis.hasNext(): while rxThis.hasNext():
rxMatch = rxThis.next() rxMatch = rxThis.next()
for n in range(1,len(theKeys)): for n in range(1, len(theKeys)):
if theKeys[n] is not None: if theKeys[n] is not None:
xPos = rxMatch.capturedStart(n) xPos = rxMatch.capturedStart(n)
xLen = rxMatch.capturedLength(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 # Save the line as is, but append the array of formatting locations
# sorted by position # sorted by position
@@ -686,7 +686,7 @@ class Tokenizer():
theTitle = theTitle.replace(r"%sc%", str(self.numChScene)) theTitle = theTitle.replace(r"%sc%", str(self.numChScene))
theTitle = theTitle.replace(r"%sca%", str(self.numAbsScene)) theTitle = theTitle.replace(r"%sca%", str(self.numAbsScene))
if r"%chw%" in theTitle: 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: if r"%chi%" in theTitle:
theTitle = theTitle.replace(r"%chi%", numberToRoman(self.numChapter, True)) theTitle = theTitle.replace(r"%chi%", numberToRoman(self.numChapter, True))
if r"%chI%" in theTitle: if r"%chI%" in theTitle:
+24 -41
View File
@@ -28,7 +28,6 @@
""" """
import logging import logging
import nw
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -73,12 +72,13 @@ def countWords(theText):
charCount -= 2 charCount -= 2
countPara = False countPara = False
theBuff = aLine.replace(""," ").replace(""," ") theBuff = aLine.replace("", " ").replace("", " ")
wordCount += len(theBuff.split()) wordCount += len(theBuff.split())
charCount += theLen charCount += theLen
if countPara and prevEmpty: if countPara and prevEmpty:
paraCount += 1 paraCount += 1
prevEmpty = countPara == False
prevEmpty = not countPara
return charCount, wordCount, paraCount return charCount, wordCount, paraCount
@@ -139,48 +139,31 @@ def _numberToWordEN(numVal):
tenVal = (numVal-oneVal) % 100 tenVal = (numVal-oneVal) % 100
hunVal = (numVal-tenVal-oneVal) % 1000 hunVal = (numVal-tenVal-oneVal) % 1000
if hunVal == 100: hunWord = "One Hundred" theHundreds = {
if hunVal == 200: hunWord = "Two Hundred" 100: "One Hundred", 200: "Two Hundred", 300: "Three Hundred",
if hunVal == 300: hunWord = "Three Hundred" 400: "Four Hundred", 500: "Five Hundred", 600: "Six Hundred",
if hunVal == 400: hunWord = "Four Hundred" 700: "Seven Hundred", 800: "Eight Hundred", 900: "Nine Hundred",
if hunVal == 500: hunWord = "Five Hundred" }
if hunVal == 600: hunWord = "Six Hundred" theTens = {
if hunVal == 700: hunWord = "Seven Hundred" 20: "Twenty", 30: "Thirty", 40: "Forty", 50: "Fifty",
if hunVal == 800: hunWord = "Eight Hundred" 60: "Sixty", 70: "Seventy", 80: "Eighty", 90: "Ninety",
if hunVal == 900: hunWord = "Nine Hundred" }
theTeens = {
if tenVal == 20: tenWord = "Twenty" 0: "Ten", 1: "Eleven", 2: "Twelve", 3: "Thirteen", 4: "Fourteen",
if tenVal == 30: tenWord = "Thirty" 5: "Fifteen", 6: "Sixteen", 7: "Seventeen", 8: "Eighteen", 9: "Nineteen",
if tenVal == 40: tenWord = "Forty" }
if tenVal == 50: tenWord = "Fifty" theOnes = {
if tenVal == 60: tenWord = "Sixty" 0: "", 1: "One", 2: "Two", 3: "Three", 4: "Four",
if tenVal == 70: tenWord = "Seventy" 5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine",
if tenVal == 80: tenWord = "Eighty" }
if tenVal == 90: tenWord = "Ninety"
hunWord = theHundreds.get(hunVal, "")
tenWord = theTens.get(tenVal, "")
if tenVal == 10: if tenVal == 10:
if oneVal == 0: oneWord = "Ten" oneWord = theTeens.get(oneVal, "")
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"
numWord = ("%s %s" % (hunWord, oneWord)).strip() numWord = ("%s %s" % (hunWord, oneWord)).strip()
else: else:
if oneVal == 0: oneWord = "" oneWord = theOnes.get(oneVal, "")
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"
if tenVal == 0: if tenVal == 0:
numWord = ("%s %s" % (hunWord, oneWord)).strip() numWord = ("%s %s" % (hunWord, oneWord)).strip()
else: else:
+2 -3
View File
@@ -27,7 +27,6 @@
import logging import logging
import json import json
import nw
from os import path from os import path
from lxml import etree from lxml import etree
@@ -114,7 +113,7 @@ class NWTree():
"""Pack the content of the tree into an XML object. """Pack the content of the tree into an XML object.
""" """
xContent = etree.SubElement(xParent, "content", attrib={ xContent = etree.SubElement(xParent, "content", attrib={
"count":str(self._theLength)} "count": str(self._theLength)}
) )
for tHandle in self._treeOrder: for tHandle in self._treeOrder:
tItem = self.__getitem__(tHandle) tItem = self.__getitem__(tHandle)
@@ -154,7 +153,7 @@ class NWTree():
outFile.write(" Table of Contents\n") outFile.write(" Table of Contents\n")
outFile.write("===================\n") outFile.write("===================\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") outFile.write("-"*80+"\n")
for tHandle in sorted(self._treeOrder): for tHandle in sorted(self._treeOrder):
tItem = self.__getitem__(tHandle) tItem = self.__getitem__(tHandle)
+9 -9
View File
@@ -146,9 +146,9 @@ class GuiAbout(QDialog):
aboutMsg += ( aboutMsg += (
"<h4>Theme: {name:s}</h4>" "<h4>Theme: {name:s}</h4>"
"<p>" "<p>"
"<b>Author:</b> {author:s}<br/>" "<b>Author:</b> {author:s}<br/>"
"<b>Credit:</b> {credit:s}<br/>" "<b>Credit:</b> {credit:s}<br/>"
"<b>License:</b> <a href='{lic_url:s}'>{license:s}</a>" "<b>License:</b> <a href='{lic_url:s}'>{license:s}</a>"
"</p>" "</p>"
).format( ).format(
name = theTheme.themeName, name = theTheme.themeName,
@@ -161,9 +161,9 @@ class GuiAbout(QDialog):
aboutMsg += ( aboutMsg += (
"<h4>Icons: {name:s}</h4>" "<h4>Icons: {name:s}</h4>"
"<p>" "<p>"
"<b>Author:</b> {author:s}<br/>" "<b>Author:</b> {author:s}<br/>"
"<b>Credit:</b> {credit:s}<br/>" "<b>Credit:</b> {credit:s}<br/>"
"<b>License:</b> <a href='{lic_url:s}'>{license:s}</a>" "<b>License:</b> <a href='{lic_url:s}'>{license:s}</a>"
"</p>" "</p>"
).format( ).format(
name = theIcons.themeName, name = theIcons.themeName,
@@ -176,9 +176,9 @@ class GuiAbout(QDialog):
aboutMsg += ( aboutMsg += (
"<h4>Syntax: {name:s}</h4>" "<h4>Syntax: {name:s}</h4>"
"<p>" "<p>"
"<b>Author:</b> {author:s}<br/>" "<b>Author:</b> {author:s}<br/>"
"<b>Credit:</b> {credit:s}<br/>" "<b>Credit:</b> {credit:s}<br/>"
"<b>License:</b> <a href='{lic_url:s}'>{license:s}</a>" "<b>License:</b> <a href='{lic_url:s}'>{license:s}</a>"
"</p>" "</p>"
).format( ).format(
name = theTheme.syntaxName, name = theTheme.syntaxName,
-1
View File
@@ -964,7 +964,6 @@ class GuiBuildNovelDocView(QTextBrowser):
lblFont.setPointSizeF(0.9*self.theTheme.fontPointSize) lblFont.setPointSizeF(0.9*self.theTheme.fontPointSize)
fPx = int(1.1*self.theTheme.fontPixelSize) fPx = int(1.1*self.theTheme.fontPixelSize)
mPx = self.mainConf.pxInt(4)
self.theTitle = QLabel("<b>Build Time:</b> Unknown", self) self.theTitle = QLabel("<b>Build Time:</b> Unknown", self)
self.theTitle.setIndent(0) self.theTitle.setIndent(0)
+6 -12
View File
@@ -962,8 +962,9 @@ class GuiDocEditor(QTextEdit):
if theSize > self.mainConf.bigDocLimit*1000: if theSize > self.mainConf.bigDocLimit*1000:
logger.info( logger.info(
"The document size is %d > %d, big doc mode is enabled" % ( "The document size is %d > %d, big doc mode is enabled" % (
theSize, self.mainConf.bigDocLimit*1000 theSize, self.mainConf.bigDocLimit*1000
)) )
)
self.bigDoc = True self.bigDoc = True
else: else:
self.bigDoc = False self.bigDoc = False
@@ -1271,7 +1272,7 @@ class GuiDocEditor(QTextEdit):
try: try:
isFind = self.lastFind[0] == theCursor.selectionStart() isFind = self.lastFind[0] == theCursor.selectionStart()
isFind &= self.lastFind[1] == theCursor.selectionEnd() isFind &= self.lastFind[1] == theCursor.selectionEnd()
except: except Exception:
isFind = False isFind = False
if isFind: if isFind:
@@ -1371,7 +1372,6 @@ class GuiDocEditSearch(QFrame):
self.doMatchCap = self.mainConf.searchMatchCap self.doMatchCap = self.mainConf.searchMatchCap
mPx = self.mainConf.pxInt(6) mPx = self.mainConf.pxInt(6)
fPx = int(0.9*self.theTheme.fontPixelSize)
tPx = int(0.8*self.theTheme.fontPixelSize) tPx = int(0.8*self.theTheme.fontPixelSize)
boxFont = self.theTheme.guiFont boxFont = self.theTheme.guiFont
boxFont.setPointSizeF(0.9*self.theTheme.fontPointSize) 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.setStyleSheet(r"QToolButton {border: none; background: transparent;}")
self.showReplace.toggled.connect(self._doToggleReplace) 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.setFixedSize(QSize(bPx, bPx))
self.searchButton.setToolTip("Find in current document") self.searchButton.setToolTip("Find in current document")
self.searchButton.clicked.connect(self._doSearch) 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.setFixedSize(QSize(bPx, bPx))
self.replaceButton.setToolTip("Find and replace in current document") self.replaceButton.setToolTip("Find and replace in current document")
self.replaceButton.clicked.connect(self._doReplace) self.replaceButton.clicked.connect(self._doReplace)
@@ -1891,7 +1891,6 @@ class GuiDocEditFooter(QWidget):
self.sPx = int(round(0.9*self.theTheme.baseIconSize)) self.sPx = int(round(0.9*self.theTheme.baseIconSize))
fPx = int(0.9*self.theTheme.fontPixelSize) fPx = int(0.9*self.theTheme.fontPixelSize)
bSp = self.mainConf.pxInt(4) bSp = self.mainConf.pxInt(4)
hSp = self.mainConf.pxInt(8)
lblFont = self.font() lblFont = self.font()
lblFont.setPointSizeF(0.9*self.theTheme.fontPointSize) lblFont.setPointSizeF(0.9*self.theTheme.fontPointSize)
@@ -1901,11 +1900,6 @@ class GuiDocEditFooter(QWidget):
self.setAutoFillBackground(True) self.setAutoFillBackground(True)
self.setPalette(self.thePalette) 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 # Status
self.statusIcon = QLabel("") self.statusIcon = QLabel("")
self.statusIcon.setContentsMargins(0, 0, 0, 0) self.statusIcon.setContentsMargins(0, 0, 0, 0)
+13 -13
View File
@@ -55,18 +55,18 @@ class GuiDocHighlighter(QSyntaxHighlighter):
self.hRules = [] self.hRules = []
self.hStyles = {} self.hStyles = {}
self.colHead = QColor(0,0,0) self.colHead = QColor(0, 0, 0)
self.colHeadH = QColor(0,0,0) self.colHeadH = QColor(0, 0, 0)
self.colEmph = QColor(0,0,0) self.colEmph = QColor(0, 0, 0)
self.colDialN = QColor(0,0,0) self.colDialN = QColor(0, 0, 0)
self.colDialD = QColor(0,0,0) self.colDialD = QColor(0, 0, 0)
self.colDialS = QColor(0,0,0) self.colDialS = QColor(0, 0, 0)
self.colComm = QColor(0,0,0) self.colComm = QColor(0, 0, 0)
self.colKey = QColor(0,0,0) self.colKey = QColor(0, 0, 0)
self.colVal = QColor(0,0,0) self.colVal = QColor(0, 0, 0)
self.colSpell = QColor(0,0,0) self.colSpell = QColor(0, 0, 0)
self.colTagErr = QColor(0,0,0) self.colTagErr = QColor(0, 0, 0)
self.colRepTag = QColor(0,0,0) self.colRepTag = QColor(0, 0, 0)
self.initHighlighter() self.initHighlighter()
@@ -143,7 +143,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
# Quoted Strings # Quoted Strings
if self.mainConf.highlightQuotes: if self.mainConf.highlightQuotes:
self.hRules.append(( self.hRules.append((
"{:s}(.+?){:s}".format('"','"'), { "{:s}(.+?){:s}".format('"', '"'), {
0 : self.hStyles["dialogue1"], 0 : self.hStyles["dialogue1"],
} }
)) ))
-2
View File
@@ -366,7 +366,6 @@ class GuiDocViewer(QTextBrowser):
"}}\n" "}}\n"
).format( ).format(
textSize = self.mainConf.textSize, textSize = self.mainConf.textSize,
preSize = self.mainConf.textSize*0.9,
tColR = self.theTheme.colText[0], tColR = self.theTheme.colText[0],
tColG = self.theTheme.colText[1], tColG = self.theTheme.colText[1],
tColB = self.theTheme.colText[2], tColB = self.theTheme.colText[2],
@@ -701,7 +700,6 @@ class GuiDocViewDetails(QScrollArea):
self.refList.setScaledContents(True) self.refList.setScaledContents(True)
self.refList.linkActivated.connect(self._linkClicked) self.refList.linkActivated.connect(self._linkClicked)
hCol = self.palette().highlight().color()
self.linkStyle = "style='color: rgb({0},{1},{2})'".format( self.linkStyle = "style='color: rgb({0},{1},{2})'".format(
*self.theTheme.colLink *self.theTheme.colLink
) )
+1 -1
View File
@@ -238,7 +238,7 @@ class GuiItemDetails(QWidget):
else: else:
self.labelFlag.setPixmap(self.expCross) self.labelFlag.setPixmap(self.expCross)
else: else:
self.labelFlag.setPixmap(QPixmap(1,1)) self.labelFlag.setPixmap(QPixmap(1, 1))
self.statusFlag.setPixmap(flagIcon.pixmap(self.sPx, self.sPx)) self.statusFlag.setPixmap(flagIcon.pixmap(self.sPx, self.sPx))
self.classFlag.setText(nwLabels.CLASS_FLAG[nwItem.itemClass]) self.classFlag.setText(nwLabels.CLASS_FLAG[nwItem.itemClass])
if nwItem.itemLayout == nwItemLayout.NO_LAYOUT: if nwItem.itemLayout == nwItemLayout.NO_LAYOUT:
+1 -1
View File
@@ -96,7 +96,7 @@ class GuiItemEditor(QDialog):
for itemLayout in nwItemLayout: for itemLayout in nwItemLayout:
if itemLayout in self.validLayouts: if itemLayout in self.validLayouts:
self.editLayout.addItem(nwLabels.LAYOUT_NAME[itemLayout],itemLayout) self.editLayout.addItem(nwLabels.LAYOUT_NAME[itemLayout], itemLayout)
# Export Switch # Export Switch
self.textExport = QLabel("Include when building project") self.textExport = QLabel("Include when building project")
+6 -6
View File
@@ -607,9 +607,9 @@ class GuiMainMenu(QMenuBar):
self.aFindNext = QAction("Find Next", self) self.aFindNext = QAction("Find Next", self)
self.aFindNext.setStatusTip("Find next occurrence text in document") self.aFindNext.setStatusTip("Find next occurrence text in document")
if self.mainConf.osDarwin: if self.mainConf.osDarwin:
self.aFindNext.setShortcuts(["Ctrl+G","F3"]) self.aFindNext.setShortcuts(["Ctrl+G", "F3"])
else: else:
self.aFindNext.setShortcuts(["F3","Ctrl+G"]) self.aFindNext.setShortcuts(["F3", "Ctrl+G"])
self.aFindNext.triggered.connect(lambda: self._docAction(nwDocAction.GO_NEXT)) self.aFindNext.triggered.connect(lambda: self._docAction(nwDocAction.GO_NEXT))
self.srcMenu.addAction(self.aFindNext) self.srcMenu.addAction(self.aFindNext)
@@ -617,9 +617,9 @@ class GuiMainMenu(QMenuBar):
self.aFindPrev = QAction("Find Previous", self) self.aFindPrev = QAction("Find Previous", self)
self.aFindPrev.setStatusTip("Find previous occurrence text in document") self.aFindPrev.setStatusTip("Find previous occurrence text in document")
if self.mainConf.osDarwin: if self.mainConf.osDarwin:
self.aFindPrev.setShortcuts(["Ctrl+Shift+G","Shift+F3"]) self.aFindPrev.setShortcuts(["Ctrl+Shift+G", "Shift+F3"])
else: 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.aFindPrev.triggered.connect(lambda: self._docAction(nwDocAction.GO_PREV))
self.srcMenu.addAction(self.aFindPrev) self.srcMenu.addAction(self.aFindPrev)
@@ -717,7 +717,7 @@ class GuiMainMenu(QMenuBar):
# Format > Remove Block Format # Format > Remove Block Format
self.aFmtNoFormat = QAction("Remove Block Format", self) self.aFmtNoFormat = QAction("Remove Block Format", self)
self.aFmtNoFormat.setStatusTip("Strips block format") 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.aFmtNoFormat.triggered.connect(lambda: self._docAction(nwDocAction.BLOCK_TXT))
self.fmtMenu.addAction(self.aFmtNoFormat) self.fmtMenu.addAction(self.aFmtNoFormat)
@@ -870,7 +870,7 @@ class GuiMainMenu(QMenuBar):
if self.mainConf.hasHelp and self.mainConf.hasAssistant: if self.mainConf.hasHelp and self.mainConf.hasAssistant:
self.aHelpWeb.setShortcut("Shift+F1") self.aHelpWeb.setShortcut("Shift+F1")
else: else:
self.aHelpWeb.setShortcuts(["F1","Shift+F1"]) self.aHelpWeb.setShortcuts(["F1", "Shift+F1"])
self.helpMenu.addAction(self.aHelpWeb) self.helpMenu.addAction(self.aHelpWeb)
# Document > Go to Website # Document > Go to Website
+4 -5
View File
@@ -193,7 +193,7 @@ class GuiOutline(QTreeWidget):
tHandle = tItem.data(self.colIndex[nwOutline.TITLE], Qt.UserRole) tHandle = tItem.data(self.colIndex[nwOutline.TITLE], Qt.UserRole)
try: try:
tLine = int(tItem.text(self.colIndex[nwOutline.LINE])) tLine = int(tItem.text(self.colIndex[nwOutline.LINE]))
except: except Exception:
tLine = 1 tLine = 1
logger.verbose("User selected entry with handle %s on line %s" % (tHandle, tLine)) logger.verbose("User selected entry with handle %s on line %s" % (tHandle, tLine))
@@ -254,7 +254,7 @@ class GuiOutline(QTreeWidget):
for hName in tempOrder: for hName in tempOrder:
try: try:
treeOrder.append(nwOutline[hName]) treeOrder.append(nwOutline[hName])
except: except Exception:
logger.warning("Ignored unknown outline column '%s'" % str(hName)) logger.warning("Ignored unknown outline column '%s'" % str(hName))
# Add columns that was not in the file to the treeOrder array. # Add columns that was not in the file to the treeOrder array.
@@ -276,14 +276,14 @@ class GuiOutline(QTreeWidget):
for hName in tmpWidth: for hName in tmpWidth:
try: try:
self.colWidth[nwOutline[hName]] = self.mainConf.pxInt(tmpWidth[hName]) self.colWidth[nwOutline[hName]] = self.mainConf.pxInt(tmpWidth[hName])
except: except Exception:
logger.warning("Ignored unknown outline column '%s'" % str(hName)) logger.warning("Ignored unknown outline column '%s'" % str(hName))
tmpHidden = self.optState.getValue("GuiOutline", "columnHidden", {}) tmpHidden = self.optState.getValue("GuiOutline", "columnHidden", {})
for hName in tmpHidden: for hName in tmpHidden:
try: try:
self.colHidden[nwOutline[hName]] = tmpHidden[hName] self.colHidden[nwOutline[hName]] = tmpHidden[hName]
except: except Exception:
logger.warning("Ignored unknown outline column '%s'" % str(hName)) logger.warning("Ignored unknown outline column '%s'" % str(hName))
self.headerMenu.setHiddenState(self.colHidden) self.headerMenu.setHiddenState(self.colHidden)
@@ -374,7 +374,6 @@ class GuiOutline(QTreeWidget):
continue continue
tLevel = self.theIndex.novelIndex[tHandle][sTitle]["level"] tLevel = self.theIndex.novelIndex[tHandle][sTitle]["level"]
tTime = self.theIndex.novelIndex[tHandle][sTitle]["updated"]
tItem = self._createTreeItem(tHandle, sTitle, tLevel) tItem = self._createTreeItem(tHandle, sTitle, tLevel)
self.treeMap[titleKey] = tItem self.treeMap[titleKey] = tItem
+2 -3
View File
@@ -30,8 +30,7 @@ import nw
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QScrollArea, QWidget, QGridLayout, QHBoxLayout, QGroupBox, QLabel, QScrollArea, QWidget, QGridLayout, QHBoxLayout, QGroupBox, QLabel
QSizePolicy
) )
from nw.constants import nwLabels, nwKeyWords from nw.constants import nwLabels, nwKeyWords
@@ -237,7 +236,7 @@ class GuiOutlineDetails(QScrollArea):
nwItem = self.theProject.projTree[tHandle] nwItem = self.theProject.projTree[tHandle]
novIdx = self.theIndex.novelIndex[tHandle][sTitle] novIdx = self.theIndex.novelIndex[tHandle][sTitle]
theRefs = self.theIndex.getReferences(tHandle, sTitle) theRefs = self.theIndex.getReferences(tHandle, sTitle)
except: except Exception:
return False return False
if novIdx["level"] in self.LVL_MAP: if novIdx["level"] in self.LVL_MAP:
+1 -2
View File
@@ -342,7 +342,7 @@ class GuiConfigEditGeneralTab(QWidget):
dlgOpt |= QFileDialog.ShowDirsOnly dlgOpt |= QFileDialog.ShowDirsOnly
dlgOpt |= QFileDialog.DontUseNativeDialog dlgOpt |= QFileDialog.DontUseNativeDialog
newDir = QFileDialog.getExistingDirectory( newDir = QFileDialog.getExistingDirectory(
self,"Backup Directory",currDir,options=dlgOpt self, "Backup Directory", currDir, options=dlgOpt
) )
if newDir: if newDir:
self.backupPath = newDir self.backupPath = newDir
@@ -720,7 +720,6 @@ class GuiConfigEditEditingTab(QWidget):
def _disableComboItem(self, theList, theValue): def _disableComboItem(self, theList, theValue):
"""Disable a list item in the combo box. """Disable a list item in the combo box.
""" """
theIdx = theList.findData(theValue)
theModel = theList.model() theModel = theList.model()
anItem = theModel.item(1) anItem = theModel.item(1)
anItem.setFlags(anItem.flags() ^ Qt.ItemIsEnabled) anItem.setFlags(anItem.flags() ^ Qt.ItemIsEnabled)
+9 -10
View File
@@ -69,11 +69,11 @@ class GuiProjectSettings(PagedDialog):
self.tabImport = GuiProjectEditStatus(self.theParent, self.theProject, False) self.tabImport = GuiProjectEditStatus(self.theParent, self.theProject, False)
self.tabReplace = GuiProjectEditReplace(self.theParent, self.theProject) self.tabReplace = GuiProjectEditReplace(self.theParent, self.theProject)
self.addTab(self.tabMain, "Settings") self.addTab(self.tabMain, "Settings")
self.addTab(self.tabMeta, "Details") self.addTab(self.tabMeta, "Details")
self.addTab(self.tabStatus, "Status") self.addTab(self.tabStatus, "Status")
self.addTab(self.tabImport, "Importance") self.addTab(self.tabImport, "Importance")
self.addTab(self.tabReplace,"Auto-Replace") self.addTab(self.tabReplace, "Auto-Replace")
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.accepted.connect(self._doSave) self.buttonBox.accepted.connect(self._doSave)
@@ -331,7 +331,7 @@ class GuiProjectEditStatus(QWidget):
self.saveButton = QPushButton("Save") self.saveButton = QPushButton("Save")
self.colPixmap = QPixmap(self.iPx, self.iPx) self.colPixmap = QPixmap(self.iPx, self.iPx)
self.colPixmap.fill(QColor(120, 120, 120)) 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.colButton.setIconSize(self.colPixmap.rect().size())
self.newButton.clicked.connect(self._newItem) self.newButton.clicked.connect(self._newItem)
@@ -422,7 +422,6 @@ class GuiProjectEditStatus(QWidget):
""" """
logger.verbose("Save item button clicked") logger.verbose("Save item button clicked")
selItem = self._getSelectedItem() selItem = self._getSelectedItem()
iRow = self.listBox.row(selItem)
if selItem is not None: if selItem is not None:
selIdx = selItem.data(Qt.UserRole) selIdx = selItem.data(Qt.UserRole)
self.colData[selIdx] = ( self.colData[selIdx] = (
@@ -513,7 +512,7 @@ class GuiProjectEditReplace(QWidget):
self.optState.getInt("GuiProjectSettings", "replaceColW", 100) self.optState.getInt("GuiProjectSettings", "replaceColW", 100)
) )
self.listBox = QTreeWidget() self.listBox = QTreeWidget()
self.listBox.setHeaderLabels(["Keyword","Replace With"]) self.listBox.setHeaderLabels(["Keyword", "Replace With"])
self.listBox.itemSelectionChanged.connect(self._selectedItem) self.listBox.itemSelectionChanged.connect(self._selectedItem)
self.listBox.setColumnWidth(0, wCol0) self.listBox.setColumnWidth(0, wCol0)
self.listBox.setIndentation(0) self.listBox.setIndentation(0)
@@ -601,8 +600,8 @@ class GuiProjectEditReplace(QWidget):
saveKey = self._stripNotAllowed(newKey) saveKey = self._stripNotAllowed(newKey)
if len(saveKey) > 0 and len(newVal) > 0: if len(saveKey) > 0 and len(newVal) > 0:
selItem.setText(0,"<%s>" % saveKey) selItem.setText(0, "<%s>" % saveKey)
selItem.setText(1,newVal) selItem.setText(1, newVal)
self.editKey.clear() self.editKey.clear()
self.editValue.clear() self.editValue.clear()
self.editKey.setEnabled(False) self.editKey.setEnabled(False)
+4 -6
View File
@@ -475,7 +475,6 @@ class GuiProjectTree(QTreeWidget):
tName = nwItem.itemName tName = nwItem.itemName
tClass = nwItem.itemClass tClass = nwItem.itemClass
tHandle = nwItem.itemHandle tHandle = nwItem.itemHandle
pHandle = nwItem.parHandle
expIcon = QIcon() expIcon = QIcon()
@@ -543,7 +542,7 @@ class GuiProjectTree(QTreeWidget):
self.theProject.setProjectWordCount(nWords) self.theProject.setProjectWordCount(nWords)
sWords = self.theProject.getSessionWordCount() sWords = self.theProject.getSessionWordCount()
self.theParent.statusBar.setStats(nWords,sWords) self.theParent.statusBar.setStats(nWords, sWords)
return return
@@ -670,7 +669,6 @@ class GuiProjectTree(QTreeWidget):
isNote = snItem.itemLayout == nwItemLayout.NOTE isNote = snItem.itemLayout == nwItemLayout.NOTE
onFile = dnItem.itemType == nwItemType.FILE onFile = dnItem.itemType == nwItemType.FILE
isRoot = snItem.itemType == nwItemType.ROOT isRoot = snItem.itemType == nwItemType.ROOT
onRoot = dnItem.itemType == nwItemType.ROOT
isOnTop = self.dropIndicatorPosition() == QAbstractItemView.OnItem isOnTop = self.dropIndicatorPosition() == QAbstractItemView.OnItem
if (isSame or isNone or isNote) and not (onFile and isOnTop) and not isRoot: if (isSame or isNone or isNote) and not (onFile and isOnTop) and not isRoot:
logger.debug("Drag'n'drop of item %s accepted" % sHandle) 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: if nHandle is not None and nHandle in self.theMap:
try: try:
byIndex = self.theMap[pHandle].indexOfChild(self.theMap[nHandle]) byIndex = self.theMap[pHandle].indexOfChild(self.theMap[nHandle])
except: except Exception:
logger.error("Failed to get index of item with handle %s" % nHandle) 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) self.theMap[pHandle].insertChild(byIndex+1, newItem)
else: else:
self.theMap[pHandle].addChild(newItem) self.theMap[pHandle].addChild(newItem)
@@ -841,7 +839,7 @@ class GuiProjectTree(QTreeWidget):
self.setTreeItemValues(tHandle) self.setTreeItemValues(tHandle)
self._setTreeChanged(True) 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 return True
+1 -1
View File
@@ -214,7 +214,7 @@ class ProjWizardFolderPage(QWizardPage):
dlgOpt |= QFileDialog.ShowDirsOnly dlgOpt |= QFileDialog.ShowDirsOnly
dlgOpt |= QFileDialog.DontUseNativeDialog dlgOpt |= QFileDialog.DontUseNativeDialog
projDir = QFileDialog.getExistingDirectory( projDir = QFileDialog.getExistingDirectory(
self,"Select Project Folder", lastPath, options=dlgOpt self, "Select Project Folder", lastPath, options=dlgOpt
) )
if projDir: if projDir:
projName = self.field("projName") projName = self.field("projName")
+3 -4
View File
@@ -35,7 +35,6 @@ from PyQt5.QtGui import QColor, QPainter
from PyQt5.QtWidgets import qApp, QStatusBar, QLabel, QAbstractButton from PyQt5.QtWidgets import qApp, QStatusBar, QLabel, QAbstractButton
from nw.core import NWSpellCheck from nw.core import NWSpellCheck
from nw.common import formatInt
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -212,7 +211,7 @@ class GuiMainStatus(QStatusBar):
tH = int(tM/60) tH = int(tM/60)
tM = tM - tH*60 tM = tM - tH*60
tS = tS - tM*60 - tH*3600 tS = tS - tM*60 - tH*3600
theTime = "%02d:%02d:%02d" % (tH,tM,tS) theTime = "%02d:%02d:%02d" % (tH, tM, tS)
self.timeText.setText(theTime) self.timeText.setText(theTime)
return return
@@ -242,9 +241,9 @@ class StatusLED(QAbstractButton):
""" """
if theState is None: if theState is None:
self._theCol = self.colNone self._theCol = self.colNone
elif theState == True: elif theState:
self._theCol = self.colTrue self._theCol = self.colTrue
elif theState == False: elif not theState:
self._theCol = self.colFalse self._theCol = self.colFalse
else: else:
self._theCol = self.colNone self._theCol = self.colNone
+12 -8
View File
@@ -33,7 +33,7 @@ import nw
from os import path, listdir from os import path, listdir
from math import ceil from math import ceil
from PyQt5.QtCore import Qt, QSize from PyQt5.QtCore import Qt
from PyQt5.QtSvg import QSvgWidget from PyQt5.QtSvg import QSvgWidget
from PyQt5.QtWidgets import QStyle, qApp from PyQt5.QtWidgets import QStyle, qApp
from PyQt5.QtGui import ( from PyQt5.QtGui import (
@@ -182,7 +182,7 @@ class GuiTheme:
for fontFam in listdir(fontAssets): for fontFam in listdir(fontAssets):
fontDir = path.join(fontAssets, fontFam) fontDir = path.join(fontAssets, fontFam)
if path.isdir(fontDir): if path.isdir(fontDir):
if not fontFam in self.guiFontDB.families(): if fontFam not in self.guiFontDB.families():
for fontFile in listdir(fontDir): for fontFile in listdir(fontDir):
ttfFile = path.join(fontDir, fontFile) ttfFile = path.join(fontDir, fontFile)
if path.isfile(ttfFile) and fontFile.endswith(".ttf"): if path.isfile(ttfFile) and fontFile.endswith(".ttf"):
@@ -260,6 +260,7 @@ class GuiTheme:
cssData = inFile.read() cssData = inFile.read()
except Exception as e: except Exception as e:
logger.error("Could not load theme css file") logger.error("Could not load theme css file")
logger.error(str(e))
return False return False
# Config File # Config File
@@ -269,6 +270,7 @@ class GuiTheme:
confParser.read_file(inFile) confParser.read_file(inFile)
except Exception as e: except Exception as e:
logger.error("Could not load theme settings from: %s" % self.confFile) logger.error("Could not load theme settings from: %s" % self.confFile)
logger.error(str(e))
return False return False
## Main ## Main
@@ -324,6 +326,7 @@ class GuiTheme:
confParser.read_file(inFile) confParser.read_file(inFile)
except Exception as e: except Exception as e:
logger.error("Could not load syntax colours from: %s" % self.syntaxFile) logger.error("Could not load syntax colours from: %s" % self.syntaxFile)
logger.error(str(e))
return False return False
## Main ## Main
@@ -431,14 +434,14 @@ class GuiTheme:
def _loadColour(self, confParser, cnfSec, cnfName): def _loadColour(self, confParser, cnfSec, cnfName):
"""Load a colour value from a config string. """Load a colour value from a config string.
""" """
if confParser.has_option(cnfSec,cnfName): if confParser.has_option(cnfSec, cnfName):
inData = confParser.get(cnfSec,cnfName).split(",") inData = confParser.get(cnfSec, cnfName).split(",")
outData = [] outData = []
try: try:
outData.append(int(inData[0])) outData.append(int(inData[0]))
outData.append(int(inData[1])) outData.append(int(inData[1]))
outData.append(int(inData[2])) outData.append(int(inData[2]))
except: except Exception:
logger.error("Could not load theme colours for '%s' from config file" % cnfName) logger.error("Could not load theme colours for '%s' from config file" % cnfName)
outData = [0, 0, 0] outData = [0, 0, 0]
else: else:
@@ -450,13 +453,13 @@ class GuiTheme:
"""Set a palette colour value from a config string. """Set a palette colour value from a config string.
""" """
readCol = [] readCol = []
if confParser.has_option(cnfSec,cnfName): if confParser.has_option(cnfSec, cnfName):
inData = confParser.get(cnfSec,cnfName).split(",") inData = confParser.get(cnfSec, cnfName).split(",")
try: try:
readCol.append(int(inData[0])) readCol.append(int(inData[0]))
readCol.append(int(inData[1])) readCol.append(int(inData[1]))
readCol.append(int(inData[2])) readCol.append(int(inData[2]))
except: except Exception:
logger.error("Could not load theme colours for '%s' from config file" % cnfName) logger.error("Could not load theme colours for '%s' from config file" % cnfName)
return return
if len(readCol) == 3: if len(readCol) == 3:
@@ -615,6 +618,7 @@ class GuiIcons:
confParser.read_file(inFile) confParser.read_file(inFile)
except Exception as e: except Exception as e:
logger.error("Could not load icon theme settings from: %s" % self.confFile) logger.error("Could not load icon theme settings from: %s" % self.confFile)
logger.error(str(e))
return False return False
## Main ## Main
+2 -2
View File
@@ -450,7 +450,7 @@ class GuiWritingStats(QDialog):
except Exception as e: except Exception as e:
self.theParent.makeAlert( 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 return False
@@ -577,6 +577,6 @@ class GuiWritingStats(QDialog):
tH = int(tM/60) tH = int(tM/60)
tM = tM - tH*60 tM = tM - tH*60
tS = tS - tM*60 - tH*3600 tS = tS - tM*60 - tH*3600
return "%02d:%02d:%02d" % (tH,tM,tS) return "%02d:%02d:%02d" % (tH, tM, tS)
# END Class GuiWritingStats # END Class GuiWritingStats
+5 -6
View File
@@ -269,7 +269,7 @@ class GuiMain(QMainWindow):
""" """
if self.hasProject: if self.hasProject:
msgBox = QMessageBox() msgBox = QMessageBox()
msgRes = msgBox.warning( msgBox.warning(
self, "New Project", self, "New Project",
"Please close the current project before making a new one." "Please close the current project before making a new one."
) )
@@ -286,9 +286,9 @@ class GuiMain(QMainWindow):
logger.error("No projData or projPath set") logger.error("No projData or projPath set")
return False 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() msgBox = QMessageBox()
msgRes = msgBox.critical( msgBox.critical(
self, "New Project", self, "New Project",
"A project already exists in that location. Please choose another folder." "A project already exists in that location. Please choose another folder."
) )
@@ -391,7 +391,7 @@ class GuiMain(QMainWindow):
int(self.theProject.lockedBy[3]) int(self.theProject.lockedBy[3])
).strftime("%x %X") ).strftime("%x %X")
) )
except: except Exception:
lockDetails = "" lockDetails = ""
msgBox = QMessageBox() msgBox = QMessageBox()
@@ -597,7 +597,7 @@ class GuiMain(QMainWindow):
self.mainConf.setLastPath(loadFile) self.mainConf.setLastPath(loadFile)
except Exception as e: except Exception as e:
self.makeAlert( 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 nwAlert.ERROR
) )
return False return False
@@ -713,7 +713,6 @@ class GuiMain(QMainWindow):
self.treeView.saveTreeOrder() self.treeView.saveTreeOrder()
self.theIndex.clearIndex() self.theIndex.clearIndex()
nItems = len(self.theProject.projTree)
theDoc = NWDoc(self.theProject, self) theDoc = NWDoc(self.theProject, self)
for nDone, tItem in enumerate(self.theProject.projTree): for nDone, tItem in enumerate(self.theProject.projTree):
-13
View File
@@ -12,19 +12,6 @@ class DummyMain():
return return
def makeAlert(self, theMessage, theLevel): 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 return
def setStatus(self, theMessage): def setStatus(self, theMessage):