* Update instructions and readmes
* Cleanup in base files
* Cleanup in core files
* Cleanup in gui files
* Cleanup in dialog files
* Cleanup in tools files
* Cleanup in test files
This commit is contained in:
Veronica Berglyd Olsen
2021-07-04 17:57:54 +02:00
committed by GitHub
parent 1881b3d32c
commit 6d7ca2bb86
51 changed files with 583 additions and 580 deletions
+9 -9
View File
@@ -39,9 +39,9 @@ from nw.config import Config
# Generally follows PEP 440
# Hex Version:
# - Digit 1,2 : Major Version (01-ff)
# = Digit 3,4 : Minor Version (01-ff)
# - Digit 3,4 : Minor Version (01-ff)
# - Digit 5,6 : Patch Version (01-ff)
# = Digit 7 : Release Type (a: aplha, b: beta, c: candidate, f: final)
# - Digit 7 : Release Type (a: aplha, b: beta, c: candidate, f: final)
# - Digit 8 : Release Number (0-f)
#
# Example : Full Short Description
@@ -111,7 +111,7 @@ CONFIG = Config()
def main(sysArgs=None):
"""Parses command line, sets up logging, and launches main GUI.
"""Parse command line, set up logging, and launches main GUI.
"""
if sysArgs is None:
sysArgs = sys.argv[1:]
@@ -155,13 +155,13 @@ def main(sysArgs=None):
)
# Defaults
logLevel = logging.WARN
logLevel = logging.WARN
logFormat = "{levelname:8} {message:}"
confPath = None
dataPath = None
testMode = False
qtStyle = "Fusion"
cmdOpen = None
confPath = None
dataPath = None
testMode = False
qtStyle = "Fusion"
cmdOpen = None
# Parse Options
try:
+1 -1
View File
@@ -208,7 +208,7 @@ def splitVersionNumber(vString):
vMajor = 0
vMinor = 0
vPatch = 0
vInt = 0
vInt = 0
vBits = vString.split(".")
nBits = len(vBits)
+12 -12
View File
@@ -23,12 +23,12 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import os
import sys
import json
import shutil
import logging
import configparser
import shutil
import json
import sys
import os
from time import time
@@ -433,9 +433,9 @@ class Config:
return False
cnfParse = configparser.ConfigParser()
cnfPath = os.path.join(self.confPath, self.confFile)
cnfPath = os.path.join(self.confPath, self.confFile)
try:
with open(cnfPath, mode="r", encoding="utf8") as inFile:
with open(cnfPath, mode="r", encoding="utf-8") as inFile:
cnfParse.read_file(inFile)
except Exception as e:
logger.error("Could not load config file")
@@ -807,7 +807,7 @@ class Config:
# Write config file
cnfPath = os.path.join(self.confPath, self.confFile)
try:
with open(cnfPath, mode="w", encoding="utf8") as outFile:
with open(cnfPath, mode="w", encoding="utf-8") as outFile:
cnfParse.write(outFile)
self.confChanged = False
except Exception as e:
@@ -831,13 +831,13 @@ class Config:
if os.path.isfile(cacheFile):
try:
with open(cacheFile, mode="r", encoding="utf8") as inFile:
with open(cacheFile, mode="r", encoding="utf-8") as inFile:
theData = json.load(inFile)
for projPath in theData.keys():
theEntry = theData[projPath]
theTitle = ""
lastTime = 0
theEntry = theData[projPath]
theTitle = ""
lastTime = 0
wordCount = 0
if "title" in theEntry.keys():
theTitle = theEntry["title"]
@@ -869,7 +869,7 @@ class Config:
cacheTemp = os.path.join(self.dataPath, nwFiles.RECENT_FILE+"~")
try:
with open(cacheTemp, mode="w+", encoding="utf8") as outFile:
with open(cacheTemp, mode="w+", encoding="utf-8") as outFile:
json.dump(self.recentProj, outFile, indent=2)
except Exception as e:
self.hasError = True
+2 -2
View File
@@ -82,7 +82,7 @@ class NWDoc():
self._docMeta = {}
if os.path.isfile(docPath):
try:
with open(docPath, mode="r", encoding="utf8") as inFile:
with open(docPath, mode="r", encoding="utf-8") as inFile:
# Check the first <= 10 lines for metadata
for i in range(10):
@@ -136,7 +136,7 @@ class NWDoc():
)
try:
with open(docTemp, mode="w", encoding="utf8") as outFile:
with open(docTemp, mode="w", encoding="utf-8") as outFile:
outFile.write(docMeta)
outFile.write(docText)
except Exception as e:
+15 -15
View File
@@ -144,13 +144,13 @@ class NWIndex():
def loadIndex(self):
"""Load index from last session from the project meta folder.
"""
theData = {}
theData = {}
indexFile = os.path.join(self.theProject.projMeta, nwFiles.INDEX_FILE)
if os.path.isfile(indexFile):
logger.debug("Loading index file")
try:
with open(indexFile, mode="r", encoding="utf8") as inFile:
with open(indexFile, mode="r", encoding="utf-8") as inFile:
theData = json.load(inFile)
except Exception:
logger.error("Failed to load index file")
@@ -158,10 +158,10 @@ class NWIndex():
self.indexBroken = True
return False
self._tagIndex = theData.get("tagIndex", {})
self._refIndex = theData.get("refIndex", {})
self._tagIndex = theData.get("tagIndex", {})
self._refIndex = theData.get("refIndex", {})
self._novelIndex = theData.get("novelIndex", {})
self._noteIndex = theData.get("noteIndex", {})
self._noteIndex = theData.get("noteIndex", {})
self._textCounts = theData.get("textCounts", {})
nowTime = round(time())
@@ -181,12 +181,12 @@ class NWIndex():
indexFile = os.path.join(self.theProject.projMeta, nwFiles.INDEX_FILE)
try:
with open(indexFile, mode="w+", encoding="utf8") as outFile:
with open(indexFile, mode="w+", encoding="utf-8") as outFile:
json.dump({
"tagIndex": self._tagIndex,
"refIndex": self._refIndex,
"tagIndex": self._tagIndex,
"refIndex": self._refIndex,
"novelIndex": self._novelIndex,
"noteIndex": self._noteIndex,
"noteIndex": self._noteIndex,
"textCounts": self._textCounts,
}, outFile, indent=2)
except Exception:
@@ -292,12 +292,12 @@ class NWIndex():
for aTag in clearTags:
self._tagIndex.pop(aTag)
nLine = 0
nLine = 0
nTitle = 0
theLines = theText.splitlines()
for aLine in theLines:
nLine += 1
nChar = len(aLine.strip())
nChar = len(aLine.strip())
if nChar == 0:
continue
@@ -352,16 +352,16 @@ class NWIndex():
"""
if aLine.startswith("# "):
hDepth = "H1"
hText = aLine[2:].strip()
hText = aLine[2:].strip()
elif aLine.startswith("## "):
hDepth = "H2"
hText = aLine[3:].strip()
hText = aLine[3:].strip()
elif aLine.startswith("### "):
hDepth = "H3"
hText = aLine[4:].strip()
hText = aLine[4:].strip()
elif aLine.startswith("#### "):
hDepth = "H4"
hText = aLine[5:].strip()
hText = aLine[5:].strip()
else:
return False
+3 -3
View File
@@ -125,12 +125,12 @@ class OptionState():
return False
stateFile = os.path.join(self.theProject.projMeta, nwFiles.OPTS_FILE)
theState = {}
theState = {}
if os.path.isfile(stateFile):
logger.debug("Loading GUI options file")
try:
with open(stateFile, mode="r", encoding="utf8") as inFile:
with open(stateFile, mode="r", encoding="utf-8") as inFile:
theState = json.load(inFile)
except Exception:
logger.error("Failed to load GUI options file")
@@ -157,7 +157,7 @@ class OptionState():
logger.debug("Saving GUI options file")
try:
with open(stateFile, mode="w+", encoding="utf8") as outFile:
with open(stateFile, mode="w+", encoding="utf-8") as outFile:
json.dump(self.theState, outFile, indent=2)
except Exception:
logger.error("Failed to save GUI options file")
+17 -18
View File
@@ -355,7 +355,7 @@ class NWProject():
def openProject(self, fileName, overrideLock=False):
"""Open the project file provided, or if doesn't exist, assume
it is a folder, and look for the file within it. If successful,
it is a folder and look for the file within it. If successful,
parse the XML of the file and populate the project variables and
build the tree of project items.
"""
@@ -483,10 +483,11 @@ class NWProject():
msgYes = self.theParent.askQuestion(
self.tr("Version Conflict"),
self.tr(
"This project was saved by a newer version of novelWriter, version "
"{0}. This is version {1}. If you continue to open the project, "
"some attributes and settings may not be preserved, but the "
"overall project should be fine. Continue opening the project?"
"This project was saved by a newer version of "
"novelWriter, version {0}. This is version {1}. If you "
"continue to open the project, some attributes and "
"settings may not be preserved, but the overall project "
"should be fine. Continue opening the project?"
).format(appVersion, nw.__version__)
)
if not msgYes:
@@ -1219,7 +1220,7 @@ class NWProject():
loadFile = chkFile2
try:
with open(loadFile, mode="r", encoding="utf8") as inFile:
with open(loadFile, mode="r", encoding="utf-8") as inFile:
self.langData = json.load(inFile)
logger.debug("Loaded project language file: %s", os.path.basename(loadFile))
@@ -1242,7 +1243,7 @@ class NWProject():
theLines = []
try:
with open(lockFile, mode="r", encoding="utf8") as inFile:
with open(lockFile, mode="r", encoding="utf-8") as inFile:
theData = inFile.read()
theLines = theData.splitlines()
if len(theLines) != 4:
@@ -1263,7 +1264,7 @@ class NWProject():
lockFile = os.path.join(self.projPath, nwFiles.PROJ_LOCK)
try:
with open(lockFile, mode="w+", encoding="utf8") as outFile:
with open(lockFile, mode="w+", encoding="utf-8") as outFile:
outFile.write("%s\n" % self.mainConf.hostName)
outFile.write("%s\n" % self.mainConf.osType)
outFile.write("%s\n" % self.mainConf.kernelVer)
@@ -1442,7 +1443,7 @@ class NWProject():
return False
try:
with open(sessionFile, mode="a+", encoding="utf8") as outFile:
with open(sessionFile, mode="a+", encoding="utf-8") as outFile:
if not isFile:
# It's a new file, so add a header
if self.lastWCount > 0:
@@ -1481,7 +1482,6 @@ class NWProject():
logger.info("Old data folder %s found", theFolder)
# Move Documents to Content
# =========================
for dataItem in os.listdir(theData):
theFile = os.path.join(theData, dataItem)
if not os.path.isfile(theFile):
@@ -1517,7 +1517,6 @@ class NWProject():
errList.append(theErr)
# Remove Data Folder
# ==================
try:
os.rmdir(theData)
logger.info("Deleted folder: %s", theFolder)
@@ -1563,13 +1562,13 @@ class NWProject():
os.path.join(self.projCache, "nwProject.nwx.7"),
os.path.join(self.projCache, "nwProject.nwx.8"),
os.path.join(self.projCache, "nwProject.nwx.9"),
os.path.join(self.projMeta, "mainOptions.json"),
os.path.join(self.projMeta, "exportOptions.json"),
os.path.join(self.projMeta, "outlineOptions.json"),
os.path.join(self.projMeta, "timelineOptions.json"),
os.path.join(self.projMeta, "docMergeOptions.json"),
os.path.join(self.projMeta, "sessionLogOptions.json"),
os.path.join(self.projPath, "ToC.json"),
os.path.join(self.projMeta, "mainOptions.json"),
os.path.join(self.projMeta, "exportOptions.json"),
os.path.join(self.projMeta, "outlineOptions.json"),
os.path.join(self.projMeta, "timelineOptions.json"),
os.path.join(self.projMeta, "docMergeOptions.json"),
os.path.join(self.projMeta, "sessionLogOptions.json"),
os.path.join(self.projPath, "ToC.json"),
]
for rmFile in rmList:
+1 -2
View File
@@ -235,8 +235,7 @@ class FakeEnchant:
class NWSpellSimple(NWSpellCheck):
"""Internal spell check tool that uses standard Python packages with
no other external dependencies. This is the fallback spell checker
when no other is available. This method is fairly slow compared to
other implementations.
when no other is available. This method is slower than enchant.
"""
theWords = set()
+12 -10
View File
@@ -35,12 +35,14 @@ logger = logging.getLogger(__name__)
class NWStatus():
def __init__(self):
self._theLabels = []
self._theLabels = []
self._theColours = []
self._theCounts = []
self._theMap = {}
self._theLength = 0
self._theIndex = 0
self._theCounts = []
self._theMap = {}
self._theLength = 0
self._theIndex = 0
return
def addEntry(self, theLabel, theColours):
@@ -87,12 +89,12 @@ class NWStatus():
replaceMap = {}
if newList is not None:
self._theLabels = []
self._theLabels = []
self._theColours = []
self._theCounts = []
self._theMap = {}
self._theLength = 0
self._theIndex = 0
self._theCounts = []
self._theMap = {}
self._theLength = 0
self._theIndex = 0
for nName, nR, nG, nB, oName in newList:
self.addEntry(nName, (nR, nG, nB))
+4 -4
View File
@@ -40,9 +40,9 @@ class ToHtml(Tokenizer):
def __init__(self, theProject):
Tokenizer.__init__(self, theProject)
self.genMode = self.M_EXPORT
self.genMode = self.M_EXPORT
self.cssStyles = True
self.fullHTML = []
self.fullHTML = []
# Internals
self._trMap = {}
@@ -59,7 +59,7 @@ class ToHtml(Tokenizer):
need to make a few changes to formatting, which is managed by
these flags.
"""
self.genMode = self.M_PREVIEW
self.genMode = self.M_PREVIEW
self.doKeywords = True
self.doComments = doComments
self.doSynopsis = doSynopsis
@@ -268,7 +268,7 @@ class ToHtml(Tokenizer):
def saveHTML5(self, savePath):
"""Save the data to an .html file.
"""
with open(savePath, mode="w", encoding="utf8") as outFile:
with open(savePath, mode="w", encoding="utf-8") as outFile:
theStyle = self.getStyleSheet()
theStyle.append("article {width: 800px; margin: 40px auto;}")
bodyText = "".join(self.fullHTML)
+19 -19
View File
@@ -24,8 +24,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import nw
import logging
import re
import logging
from operator import itemgetter
from functools import partial
@@ -43,12 +43,12 @@ logger = logging.getLogger(__name__)
class Tokenizer():
# In-Text Format
FMT_B_B = 1 # Begin bold
FMT_B_E = 2 # End bold
FMT_I_B = 3 # Begin italics
FMT_I_E = 4 # End italics
FMT_D_B = 5 # Begin strikeout
FMT_D_E = 6 # End strikeout
FMT_B_B = 1 # Begin bold
FMT_B_E = 2 # End bold
FMT_I_B = 3 # Begin italics
FMT_I_E = 4 # End italics
FMT_D_B = 5 # Begin strikeout
FMT_D_E = 6 # End strikeout
# Block Type
T_EMPTY = 1 # Empty line (new paragraph)
@@ -86,11 +86,11 @@ class Tokenizer():
self.mainConf = nw.CONFIG
# Data Variables
self.theText = "" # The raw text to be tokenized
self.theHandle = None # The handle associated with the text
self.theItem = None # The NWItem associated with the handle
self.theTokens = [] # The list of the processed tokens
self.theResult = "" # The result of the last document
self.theText = "" # The raw text to be tokenized
self.theHandle = None # The handle associated with the text
self.theItem = None # The NWItem associated with the handle
self.theTokens = [] # The list of the processed tokens
self.theResult = "" # The result of the last document
self.keepMarkdown = False # Whether to keep the markdown text
self.theMarkdown = [] # The result novelWriter markdown of all documents
@@ -117,11 +117,11 @@ class Tokenizer():
self.marginMeta = (0.000, 0.584)
# Title Formats
self.fmtTitle = "%title%" # Formatting for titles
self.fmtChapter = "%title%" # Formatting for numbered chapters
self.fmtUnNum = "%title%" # Formatting for unnumbered chapters
self.fmtScene = "%title%" # Formatting for scenes
self.fmtSection = "%title%" # Formatting for sections
self.fmtTitle = "%title%" # Formatting for titles
self.fmtChapter = "%title%" # Formatting for numbered chapters
self.fmtUnNum = "%title%" # Formatting for unnumbered chapters
self.fmtScene = "%title%" # Formatting for scenes
self.fmtSection = "%title%" # Formatting for sections
self.hideScene = False # Do not include scene headers
self.hideSection = False # Do not include section headers
@@ -320,7 +320,7 @@ class Tokenizer():
return True
def doPreProcessing(self):
"""Reun trough the various replace doctionaries.
"""Run trough the various replace doctionaries.
"""
# Process the user's auto-replace dictionary
if len(self.theProject.autoReplace) > 0:
@@ -701,7 +701,7 @@ class Tokenizer():
def saveRawMarkdown(self, savePath):
"""Save the data to a plain text file.
"""
with open(savePath, mode="w", encoding="utf8") as outFile:
with open(savePath, mode="w", encoding="utf-8") as outFile:
for nwdPage in self.theMarkdown:
outFile.write(nwdPage)
return
+14 -8
View File
@@ -72,16 +72,22 @@ class ToMarkdown(Tokenizer):
if self.genMode == self.M_STD:
# Standard
mdTags = {
self.FMT_B_B: "**", self.FMT_B_E: "**",
self.FMT_I_B: "_", self.FMT_I_E: "_",
self.FMT_D_B: "", self.FMT_D_E: "",
self.FMT_B_B: "**",
self.FMT_B_E: "**",
self.FMT_I_B: "_",
self.FMT_I_E: "_",
self.FMT_D_B: "",
self.FMT_D_E: "",
}
else:
# GitHub
mdTags = {
self.FMT_B_B: "**", self.FMT_B_E: "**",
self.FMT_I_B: "_", self.FMT_I_E: "_",
self.FMT_D_B: "~~", self.FMT_D_E: "~~",
self.FMT_B_B: "**",
self.FMT_B_E: "**",
self.FMT_I_B: "_",
self.FMT_I_E: "_",
self.FMT_D_B: "~~",
self.FMT_D_E: "~~",
}
self.theResult = ""
@@ -149,7 +155,7 @@ class ToMarkdown(Tokenizer):
def saveMarkdown(self, savePath):
"""Save the data to a plain text file.
"""
with open(savePath, mode="w", encoding="utf8") as outFile:
with open(savePath, mode="w", encoding="utf-8") as outFile:
theText = "".join(self.fullMD)
outFile.write(theText)
@@ -173,7 +179,7 @@ class ToMarkdown(Tokenizer):
def _formatKeywords(self, tText, tStyle):
"""Apply Markdown formatting to keywords.
"""
isValid, theBits, thePos = self.theParent.theIndex.scanThis("@"+tText)
isValid, theBits, _ = self.theParent.theIndex.scanThis("@"+tText)
if not isValid or not theBits:
return ""
+3 -3
View File
@@ -24,11 +24,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import nw
import logging
import os
import logging
from lxml import etree
from time import time
from lxml import etree
from hashlib import sha256
from nw.enum import nwItemType, nwItemClass, nwItemLayout
@@ -193,7 +193,7 @@ class NWTree():
try:
# Dump the text
tocText = os.path.join(self.theProject.projPath, nwFiles.TOC_TXT)
with open(tocText, mode="w", encoding="utf8") as outFile:
with open(tocText, mode="w", encoding="utf-8") as outFile:
outFile.write("\n")
outFile.write("Table of Contents\n")
outFile.write("=================\n")
+4 -4
View File
@@ -24,13 +24,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import nw
import logging
import os
import logging
from datetime import datetime
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QCursor
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
qApp, QDialog, QHBoxLayout, QVBoxLayout, QDialogButtonBox, QTabWidget,
QTextBrowser, QLabel
@@ -229,7 +229,7 @@ class GuiAbout(QDialog):
"""
docPath = os.path.join(self.mainConf.assetPath, "text", "release_notes.htm")
if os.path.isfile(docPath):
with open(docPath, mode="r", encoding="utf8") as inFile:
with open(docPath, mode="r", encoding="utf-8") as inFile:
helpText = inFile.read()
self.pageNotes.setHtml(helpText)
else:
@@ -241,7 +241,7 @@ class GuiAbout(QDialog):
"""
docPath = os.path.join(self.mainConf.assetPath, "text", "gplv3_en.htm")
if os.path.isfile(docPath):
with open(docPath, mode="r", encoding="utf8") as inFile:
with open(docPath, mode="r", encoding="utf-8") as inFile:
helpText = inFile.read()
self.pageLicense.setHtml(helpText)
else:
+2 -2
View File
@@ -137,7 +137,7 @@ class GuiItemEditor(QDialog):
# Assemble
##
nameLabel = QLabel(self.tr("Label"))
nameLabel = QLabel(self.tr("Label"))
statusLabel = QLabel(self.tr("Status"))
layoutLabel = QLabel(self.tr("Layout"))
@@ -179,7 +179,7 @@ class GuiItemEditor(QDialog):
"""
logger.verbose("ItemEditor save button clicked")
itemName = self.editName.text()
itemName = self.editName.text()
itemStatus = self.editStatus.currentData()
itemLayout = self.editLayout.currentData()
isExported = self.editExport.isChecked()
+9 -9
View File
@@ -24,11 +24,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import nw
import logging
import os
import logging
from PyQt5.QtCore import Qt, QLocale
from PyQt5.QtGui import QFont
from PyQt5.QtCore import Qt, QLocale
from PyQt5.QtWidgets import (
QDialog, QWidget, QComboBox, QSpinBox, QPushButton, QDialogButtonBox,
QLineEdit, QFileDialog, QFontDialog, QDoubleSpinBox
@@ -127,7 +127,7 @@ class GuiPreferences(PagedDialog):
def _saveWindowSize(self):
"""Save the dialog window size.
"""
winWidth = self.mainConf.rpxInt(self.width())
winWidth = self.mainConf.rpxInt(self.width())
winHeight = self.mainConf.rpxInt(self.height())
self.mainConf.setPreferencesSize(winWidth, winHeight)
return
@@ -272,12 +272,12 @@ class GuiPreferencesGeneral(QWidget):
def saveValues(self):
"""Save the values set for this tab.
"""
guiLang = self.guiLang.currentData()
guiTheme = self.guiTheme.currentData()
guiIcons = self.guiIcons.currentData()
guiDark = self.guiDark.isChecked()
guiFont = self.guiFont.text()
guiFontSize = self.guiFontSize.value()
guiLang = self.guiLang.currentData()
guiTheme = self.guiTheme.currentData()
guiIcons = self.guiIcons.currentData()
guiDark = self.guiDark.isChecked()
guiFont = self.guiFont.text()
guiFontSize = self.guiFontSize.value()
# Check if restart is needed
needsRestart = False
+4 -4
View File
@@ -24,13 +24,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import nw
import logging
import os
import logging
from datetime import datetime
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QKeySequence
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtWidgets import (
QDialog, QHBoxLayout, QVBoxLayout, QGridLayout, QPushButton, QTreeWidget,
QAbstractItemView, QTreeWidgetItem, QDialogButtonBox, QLabel, QShortcut,
@@ -105,8 +105,8 @@ class GuiProjectLoad(QDialog):
treeHead.setTextAlignment(self.C_TIME, Qt.AlignRight)
self.lblRecent = QLabel("<b>%s</b>" % self.tr("Recently Opened Projects"))
self.lblPath = QLabel("<b>%s</b>" % self.tr("Path"))
self.selPath = QLineEdit("")
self.lblPath = QLabel("<b>%s</b>" % self.tr("Path"))
self.selPath = QLineEdit("")
self.selPath.setReadOnly(True)
self.browseButton = QPushButton("...")
+4 -4
View File
@@ -26,8 +26,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
import nw
import logging
from PyQt5.QtCore import Qt, QLocale
from PyQt5.QtGui import QIcon, QPixmap, QColor, QBrush
from PyQt5.QtCore import Qt, QLocale
from PyQt5.QtWidgets import (
QHBoxLayout, QVBoxLayout, QLineEdit, QPlainTextEdit, QLabel, QWidget,
QDialogButtonBox, QPushButton, QColorDialog, QTreeWidget, QTreeWidgetItem,
@@ -393,7 +393,7 @@ class GuiProjectEditStatus(QWidget):
"""
selItem = self._getSelectedItem()
if selItem is not None:
iRow = self.listBox.indexOfTopLevelItem(selItem)
iRow = self.listBox.indexOfTopLevelItem(selItem)
selIdx = selItem.data(self.COL_LABEL, Qt.UserRole)
if self.colCounts[selIdx] == 0:
self.listBox.takeTopLevelItem(iRow)
@@ -626,8 +626,8 @@ class GuiProjectEditReplace(QWidget):
if selItem is None:
return False
newKey = self.editKey.text()
newVal = self.editValue.text()
newKey = self.editKey.text()
newVal = self.editValue.text()
saveKey = self._stripNotAllowed(newKey)
if len(saveKey) > 0 and len(newVal) > 0:
+3 -3
View File
@@ -24,8 +24,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import nw
import logging
import os
import logging
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
@@ -155,7 +155,7 @@ class GuiWordList(QDialog):
tmpFile = dctFile + "~"
try:
with open(tmpFile, mode="w", encoding="utf8") as outFile:
with open(tmpFile, mode="w", encoding="utf-8") as outFile:
for i in range(self.listBox.count()):
outFile.write(self.listBox.item(i).text() + "\n")
@@ -193,7 +193,7 @@ class GuiWordList(QDialog):
logger.debug("No project dictionary file found")
return False
with open(wordList, mode="r", encoding="utf8") as inFile:
with open(wordList, mode="r", encoding="utf-8") as inFile:
for inLine in inFile:
theWord = inLine.strip()
if len(theWord) == 0:
+5 -5
View File
@@ -104,11 +104,11 @@ class nwDocAction(Enum):
class nwDocInsert(Enum):
NO_INSERT = 0
QUOTE_LS = 1
QUOTE_RS = 2
QUOTE_LD = 3
QUOTE_RD = 4
NO_INSERT = 0
QUOTE_LS = 1
QUOTE_RS = 2
QUOTE_LD = 3
QUOTE_RD = 4
# END Enum nwDocInsert
+15 -12
View File
@@ -311,13 +311,13 @@ class QSwitch(QAbstractButton):
if self.isChecked():
trackBrush = qPalette.highlight()
thumbBrush = qPalette.highlightedText()
textColor = qPalette.highlight().color()
thumbText = nwUnicode.U_CHECK
textColor = qPalette.highlight().color()
thumbText = nwUnicode.U_CHECK
else:
trackBrush = qPalette.dark()
thumbBrush = qPalette.light()
textColor = qPalette.dark().color()
thumbText = nwUnicode.U_CROSS
textColor = qPalette.dark().color()
thumbText = nwUnicode.U_CROSS
if self.isEnabled():
trackOpacity = 1.0
@@ -325,7 +325,7 @@ class QSwitch(QAbstractButton):
trackOpacity = 0.6
trackBrush = qPalette.shadow()
thumbBrush = qPalette.mid()
textColor = qPalette.shadow().color()
textColor = qPalette.shadow().color()
qPaint.setBrush(trackBrush)
qPaint.setOpacity(trackOpacity)
@@ -379,18 +379,18 @@ class PagedDialog(QDialog):
def __init__(self, theParent=None):
QDialog.__init__(self, parent=theParent)
self._outerBox = QVBoxLayout()
self._buttonBox = QHBoxLayout()
self._tabBox = QTabWidget()
self._tabBar = VerticalTabBar(self)
self._tabBox.setTabBar(self._tabBar)
self._tabBox.setTabPosition(QTabWidget.West)
self._tabBar.setExpanding(False)
self._tabBox = QTabWidget()
self._tabBox.setTabBar(self._tabBar)
self._tabBox.setTabPosition(QTabWidget.West)
self._buttonBox = QHBoxLayout()
self._outerBox = QVBoxLayout()
self._outerBox.addWidget(self._tabBox)
self._outerBox.addLayout(self._buttonBox)
self.setLayout(self._outerBox)
# Default Margins
qM = self._outerBox.contentsMargins()
@@ -399,11 +399,14 @@ class PagedDialog(QDialog):
mT = qM.top()
mB = qM.bottom()
# Set Margins
self.setContentsMargins(0, 0, 0, 0)
self._outerBox.setContentsMargins(0, 0, 0, mB)
self._buttonBox.setContentsMargins(mL, 0, mR, 0)
self._outerBox.setSpacing(mT)
self.setLayout(self._outerBox)
return
def addTab(self, tabWidget, tabLabel):
+35 -33
View File
@@ -1090,7 +1090,7 @@ class GuiDocEditor(QTextEdit):
# Spell Checking
# ==============
posCursor = self.cursorForPosition(thePos)
posCursor = self.cursorForPosition(thePos)
spellCheck = self._spellCheck
if posCursor.block().text().startswith("@"):
@@ -1272,7 +1272,7 @@ class GuiDocEditor(QTextEdit):
findOpt |= QTextDocument.FindWholeWords
searchFor = self.docSearch.getSearchObject()
wasFound = self.find(searchFor, findOpt)
wasFound = self.find(searchFor, findOpt)
if not wasFound:
if self.docSearch.doNextFile and not goBack:
self.theParent.openNextDocument(
@@ -1330,7 +1330,7 @@ class GuiDocEditor(QTextEdit):
return
searchFor = self.docSearch.getSearchText()
replWith = self.docSearch.getReplaceText()
replWith = self.docSearch.getReplaceText()
if self.docSearch.doMatchCap:
replWith = transferCase(theCursor.selectedText(), replWith)
@@ -1376,7 +1376,7 @@ class GuiDocEditor(QTextEdit):
theCursor = self.textCursor()
theBlock = theCursor.block()
theText = theBlock.text()
theText = theBlock.text()
if len(theText) == 0:
return False
@@ -1413,16 +1413,16 @@ class GuiDocEditor(QTextEdit):
if not theBlock.isValid():
return
theText = theBlock.text()
theText = theBlock.text()
theCursor = self.textCursor()
thePos = theCursor.positionInBlock()
theLen = len(theText)
thePos = theCursor.positionInBlock()
theLen = len(theText)
if theLen < 1 or thePos-1 > theLen:
return
theOne = theText[thePos-1:thePos]
theTwo = theText[thePos-2:thePos]
theOne = theText[thePos-1:thePos]
theTwo = theText[thePos-2:thePos]
theThree = theText[thePos-3:thePos]
if not theOne: # Makes Neo sad
@@ -2028,7 +2028,7 @@ class GuiDocEditSearch(QFrame):
self.searchOpt.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.searchOpt.setIconSize(QSize(tPx, tPx))
self.searchOpt.setContentsMargins(0, 0, 0, 0)
self.searchOpt.setStyleSheet(r"QToolBar {padding: 0;}")
self.searchOpt.setStyleSheet("QToolBar {padding: 0;}")
self.searchLabel = QLabel(self.tr("Search"))
self.searchLabel.setFont(boxFont)
@@ -2100,7 +2100,7 @@ class GuiDocEditSearch(QFrame):
self.showReplace.setArrowType(Qt.RightArrow)
self.showReplace.setCheckable(True)
self.showReplace.setToolTip(self.tr("Show/hide the replace text box"))
self.showReplace.setStyleSheet(r"QToolButton {border: none; background: transparent;}")
self.showReplace.setStyleSheet("QToolButton {border: none; background: transparent;}")
self.showReplace.toggled.connect(self._doToggleReplace)
self.searchButton = QPushButton(self.theTheme.getIcon("search"), "")
@@ -2139,9 +2139,9 @@ class GuiDocEditSearch(QFrame):
# Construct Box Colours
qPalette = self.searchBox.palette()
baseCol = qPalette.base().color()
rCol = baseCol.redF() + 0.1
rCol = baseCol.redF() + 0.1
gCol = baseCol.greenF() - 0.1
bCol = baseCol.blueF() - 0.1
bCol = baseCol.blueF() - 0.1
mCol = max(rCol, gCol, bCol, 1.0)
errCol = QColor()
@@ -2161,10 +2161,10 @@ class GuiDocEditSearch(QFrame):
def closeSearch(self):
"""Close the search box.
"""
self.mainConf.searchCase = self.isCaseSense
self.mainConf.searchWord = self.isWholeWord
self.mainConf.searchRegEx = self.isRegEx
self.mainConf.searchLoop = self.doLoop
self.mainConf.searchCase = self.isCaseSense
self.mainConf.searchWord = self.isWholeWord
self.mainConf.searchRegEx = self.isRegEx
self.mainConf.searchLoop = self.doLoop
self.mainConf.searchNextFile = self.doNextFile
self.mainConf.searchMatchCap = self.doMatchCap
@@ -2367,7 +2367,8 @@ class GuiDocEditHeader(QWidget):
self.theParent = docEditor.theParent
self.theProject = docEditor.theProject
self.theTheme = docEditor.theTheme
self._docHandle = None
self._docHandle = None
fPx = int(0.9*self.theTheme.fontPixelSize)
hSp = self.mainConf.pxInt(6)
@@ -2591,8 +2592,9 @@ class GuiDocEditFooter(QWidget):
self.theProject = docEditor.theProject
self.theTheme = docEditor.theTheme
self.optState = docEditor.theProject.optState
self._docHandle = None
self.theItem = None
self._theItem = None
self._docHandle = None
self.sPx = int(round(0.9*self.theTheme.baseIconSize))
fPx = int(0.9*self.theTheme.fontPixelSize)
@@ -2708,9 +2710,9 @@ class GuiDocEditFooter(QWidget):
self._docHandle = tHandle
if self._docHandle is None:
logger.verbose("No handle set, so clearing the editor footer")
self.theItem = None
self._theItem = None
else:
self.theItem = self.theProject.projTree[self._docHandle]
self._theItem = self.theProject.projTree[self._docHandle]
self.updateInfo()
self.updateCounts()
@@ -2720,12 +2722,12 @@ class GuiDocEditFooter(QWidget):
def updateInfo(self):
"""Update the content of text labels.
"""
if self.theItem is None:
if self._theItem is None:
sIcon = QPixmap()
sText = ""
else:
iStatus = self.theItem.itemStatus
if self.theItem.itemClass == nwItemClass.NOVEL:
iStatus = self._theItem.itemStatus
if self._theItem.itemClass == nwItemClass.NOVEL:
iStatus = self.theProject.statusItems.checkEntry(iStatus)
theIcon = self.theParent.statusIcons[iStatus]
else:
@@ -2733,9 +2735,9 @@ class GuiDocEditFooter(QWidget):
theIcon = self.theParent.importIcons[iStatus]
sIcon = theIcon.pixmap(self.sPx, self.sPx)
sClass = trConst(nwLabels.CLASS_NAME[self.theItem.itemClass])
sLayout = trConst(nwLabels.LAYOUT_NAME[self.theItem.itemLayout])
sText = f"{self.theItem.itemStatus} / {sClass} / {sLayout}"
sClass = trConst(nwLabels.CLASS_NAME[self._theItem.itemClass])
sLayout = trConst(nwLabels.LAYOUT_NAME[self._theItem.itemLayout])
sText = f"{self._theItem.itemStatus} / {sClass} / {sLayout}"
self.statusIcon.setPixmap(sIcon)
self.statusText.setText(sText)
@@ -2745,7 +2747,7 @@ class GuiDocEditFooter(QWidget):
def updateLineCount(self):
"""Update the word count.
"""
if self.theItem is None:
if self._theItem is None:
iLine = 0
iDist = 0
else:
@@ -2762,12 +2764,12 @@ class GuiDocEditFooter(QWidget):
def updateCounts(self):
"""Update the word count.
"""
if self.theItem is None:
if self._theItem is None:
wCount = 0
wDiff = 0
wDiff = 0
else:
wCount = self.theItem.wordCount
wDiff = wCount - self.theItem.initCount
wCount = self._theItem.wordCount
wDiff = wCount - self._theItem.initCount
self.wordsText.setText(
self.tr("Words: {0} ({1})").format(f"{wCount:n}", f"{wDiff:+n}")
+2 -6
View File
@@ -60,7 +60,7 @@ class GuiDocViewer(QTextBrowser):
self.theProject = theParent.theProject
# Internal Variables
self._docHandle = None
self._docHandle = None
self._qDocument = self.document()
# Settings
@@ -312,9 +312,7 @@ class GuiDocViewer(QTextBrowser):
return
def updateDocMargins(self):
"""Automatically adjust the margins so the text is centred if
Config.textFixedW is enabled or we're in Focus Mode. Otherwise,
just ensure the margins are set correctly.
"""Automatically adjust the margins so the text is centred.
"""
vBar = self.verticalScrollBar()
sW = vBar.width() if vBar.isVisible() else 0
@@ -1152,7 +1150,6 @@ class GuiDocViewDetails(QScrollArea):
self.theParent = theParent
self.theProject = theParent.theProject
self.theTheme = theParent.theTheme
self.currHandle = None
self.refList = QLabel("")
self.refList.setWordWrap(True)
@@ -1185,7 +1182,6 @@ class GuiDocViewDetails(QScrollArea):
"""Update the current list of document references from the
project index.
"""
self.currHandle = tHandle
if self.theParent.docViewer.stickyRef:
return
+16 -18
View File
@@ -47,7 +47,7 @@ class GuiMainMenu(QMenuBar):
self.theProject = theParent.theProject
# Internals
self.assistProc = None
self._assistProc = None
# Build Menu
self._buildProjectMenu()
@@ -92,19 +92,19 @@ class GuiMainMenu(QMenuBar):
def closeHelp(self):
"""Close the process used for the Qt Assistant, if it is open.
"""
if self.assistProc is None:
if self._assistProc is None:
return
if self.assistProc.state() == QProcess.Starting:
if self.assistProc.waitForStarted(10000):
self.assistProc.terminate()
if self._assistProc.state() == QProcess.Starting:
if self._assistProc.waitForStarted(10000):
self._assistProc.terminate()
else:
self.assistProc.kill()
self._assistProc.kill()
elif self.assistProc.state() == QProcess.Running:
self.assistProc.terminate()
if not self.assistProc.waitForFinished(10000):
self.assistProc.kill()
elif self._assistProc.state() == QProcess.Running:
self._assistProc.terminate()
if not self._assistProc.waitForFinished(10000):
self._assistProc.kill()
return
@@ -134,7 +134,7 @@ class GuiMainMenu(QMenuBar):
# Slots
##
def _toggleSpellCheck(self, isChecked=False):
def _toggleSpellCheck(self):
"""Toggle spell checking. The active status of the spell check
flag is handled by the document editor class, so we make no
decision, just pass a None to the function and let it decide.
@@ -155,10 +155,10 @@ class GuiMainMenu(QMenuBar):
self._openWebsite(nw.__docurl__)
return False
self.assistProc = QProcess(self)
self.assistProc.start("assistant", ["-collectionFile", self.mainConf.helpPath])
self._assistProc = QProcess(self)
self._assistProc.start("assistant", ["-collectionFile", self.mainConf.helpPath])
if not self.assistProc.waitForStarted(10000):
if not self._assistProc.waitForStarted(10000):
self._openWebsite(nw.__docurl__)
return False
@@ -239,11 +239,9 @@ class GuiMainMenu(QMenuBar):
self.rootItems[nwItemClass.ENTITY] = QAction(self.tr("Entity Root"), self.rootMenu)
self.rootItems[nwItemClass.CUSTOM] = QAction(self.tr("Custom Root"), self.rootMenu)
self.rootItems[nwItemClass.ARCHIVE] = QAction(self.tr("Outtakes Root"), self.rootMenu)
nCount = 0
for itemClass in self.rootItems.keys():
nCount += 1 # This forces the lambdas to be unique
for n, itemClass in enumerate(self.rootItems.keys()):
self.rootItems[itemClass].triggered.connect(
lambda nCount, itemClass=itemClass: self._newTreeItem(nwItemType.ROOT, itemClass)
lambda n, itemClass=itemClass: self._newTreeItem(nwItemType.ROOT, itemClass)
)
self.rootMenu.addAction(self.rootItems[itemClass])
+5 -5
View File
@@ -247,9 +247,9 @@ class GuiNovelTree(QTreeWidget):
"""
self.clearTree()
currTitle = None
currTitle = None
currChapter = None
currScene = None
currScene = None
for tKey, tHandle, sTitle, novIdx in self.theIndex.novelStructure(skipExcluded=True):
@@ -259,9 +259,9 @@ class GuiNovelTree(QTreeWidget):
tLevel = novIdx["level"]
if tLevel == "H1":
self.addTopLevelItem(tItem)
currTitle = tItem
currTitle = tItem
currChapter = None
currScene = None
currScene = None
elif tLevel == "H2":
if currTitle is None:
@@ -269,7 +269,7 @@ class GuiNovelTree(QTreeWidget):
else:
currTitle.addChild(tItem)
currChapter = tItem
currScene = None
currScene = None
elif tLevel == "H3":
if currChapter is None:
+88 -86
View File
@@ -28,7 +28,7 @@ import logging
from time import time
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtCore import Qt, QSize, pyqtSlot
from PyQt5.QtWidgets import (
QTreeWidget, QTreeWidgetItem, QMenu, QAction, QAbstractItemView
)
@@ -94,9 +94,6 @@ class GuiOutline(QTreeWidget):
self.optState = theParent.theProject.optState
self.headerMenu = GuiOutlineHeaderMenu(self)
self.firstView = True
self.lastBuild = 0
self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.setSelectionMode(QAbstractItemView.SingleSelection)
self.setExpandsOnDoubleClick(False)
@@ -113,16 +110,18 @@ class GuiOutline(QTreeWidget):
self.treeHead.customContextMenuRequested.connect(self._headerRightClick)
self.treeHead.sectionMoved.connect(self._columnMoved)
self.treeMap = {}
self.treeOrder = []
self.colWidth = {}
self.colHidden = {}
self.colIndex = {}
self.treeNCols = 0
# Internals
self._treeOrder = []
self._colWidth = {}
self._colHidden = {}
self._colIdx = {}
self._treeNCols = 0
self._firstView = True
self._lastBuild = 0
self.initOutline()
self.clearOutline()
self.headerMenu.setHiddenState(self.colHidden)
self.headerMenu.setHiddenState(self._colHidden)
logger.debug("GuiOutline initialisation complete")
@@ -152,18 +151,18 @@ class GuiOutline(QTreeWidget):
self.setColumnCount(1)
self.setHeaderLabel(trConst(nwLabels.OUTLINE_COLS[nwOutline.TITLE]))
self.treeOrder = []
self.colWidth = {}
self.colHidden = {}
self.colIndex = {}
self.treeNCols = 0
self._treeOrder = []
self._colWidth = {}
self._colHidden = {}
self._colIdx = {}
self._treeNCols = 0
for i, hItem in enumerate(nwOutline):
self.treeOrder.append(hItem)
self.colWidth[hItem] = self.DEF_WIDTH[hItem]
self.colHidden[hItem] = self.DEF_HIDDEN[hItem]
for hItem in nwOutline:
self._treeOrder.append(hItem)
self._colWidth[hItem] = self.DEF_WIDTH[hItem]
self._colHidden[hItem] = self.DEF_HIDDEN[hItem]
self.treeNCols = len(self.treeOrder)
self._treeNCols = len(self._treeOrder)
return
@@ -173,15 +172,15 @@ class GuiOutline(QTreeWidget):
tree.
"""
# If it's the first time, we always build
if self.firstView or self.firstView and overRide:
if self._firstView or self._firstView and overRide:
self._loadHeaderState()
self._populateTree()
self.firstView = False
self._firstView = False
return
# If the novel index or novel tree has changed since the tree
# was last built, we rebuild the tree from the updated index.
indexChanged = self.theIndex.novelChangedSince(self.lastBuild)
indexChanged = self.theIndex.novelChangedSince(self._lastBuild)
doBuild = (novelChanged or indexChanged) and self.theProject.autoOutline
if doBuild or overRide:
logger.debug("Rebuilding Project Outline")
@@ -194,21 +193,22 @@ class GuiOutline(QTreeWidget):
"""
self._saveHeaderState()
self.clearOutline()
self.firstView = True
self._firstView = True
return
##
# Slots
##
@pyqtSlot("QTreeWidgetItem*", int)
def _treeDoubleClick(self, tItem, tCol):
"""Extract the handle and line number of the title double-
clicked, and send it to the main gui class for opening in the
document editor.
"""
tHandle = tItem.data(self.colIndex[nwOutline.TITLE], Qt.UserRole)
tHandle = tItem.data(self._colIdx[nwOutline.TITLE], Qt.UserRole)
try:
tLine = int(tItem.text(self.colIndex[nwOutline.LINE]))
tLine = int(tItem.text(self._colIdx[nwOutline.LINE]))
except Exception:
tLine = 1
@@ -217,30 +217,33 @@ class GuiOutline(QTreeWidget):
return
@pyqtSlot()
def _itemSelected(self):
"""Extract the handle and line number of the currently selected
title, and send it to the details panel.
"""
selItems = self.selectedItems()
if selItems:
tHandle = selItems[0].data(self.colIndex[nwOutline.TITLE], Qt.UserRole)
sTitle = selItems[0].data(self.colIndex[nwOutline.LINE], Qt.UserRole)
tHandle = selItems[0].data(self._colIdx[nwOutline.TITLE], Qt.UserRole)
sTitle = selItems[0].data(self._colIdx[nwOutline.LINE], Qt.UserRole)
self.theParent.projMeta.showItem(tHandle, sTitle)
self.theParent.treeView.setSelectedHandle(tHandle)
return
@pyqtSlot("QPoint")
def _headerRightClick(self, clickPos):
"""Show the header column menu.
"""
self.headerMenu.exec_(self.mapToGlobal(clickPos))
return
@pyqtSlot(int, int, int)
def _columnMoved(self, logIdx, oldVisualIdx, newVisualIdx):
"""Make sure the order array is up to date with the actual order
of the columns.
"""
self.treeOrder.insert(newVisualIdx, self.treeOrder.pop(oldVisualIdx))
self._treeOrder.insert(newVisualIdx, self._treeOrder.pop(oldVisualIdx))
self._saveHeaderState()
return
@@ -249,8 +252,8 @@ class GuiOutline(QTreeWidget):
header context menu.
"""
logger.verbose("User toggled Outline column '%s'", theItem.name)
if theItem in self.colIndex:
self.setColumnHidden(self.colIndex[theItem], not isChecked)
if theItem in self._colIdx:
self.setColumnHidden(self._colIdx[theItem], not isChecked)
self._saveHeaderState()
return
@@ -281,29 +284,29 @@ class GuiOutline(QTreeWidget):
# Check that we now have a complete list, and only if so, save
# the order loaded from file. Otherwise, we keep the default.
if len(treeOrder) == self.treeNCols:
self.treeOrder = treeOrder
if len(treeOrder) == self._treeNCols:
self._treeOrder = treeOrder
else:
logger.error("Failed to extract outline column order from previous session")
logger.error("Column count doesn't match %d != %d", len(treeOrder), self.treeNCols)
logger.error("Column count doesn't match %d != %d", len(treeOrder), self._treeNCols)
# We load whatever column widths and hidden states we find in
# the file, and leave the rest in their default state.
tmpWidth = self.optState.getValue("GuiOutline", "columnWidth", {})
for hName in tmpWidth:
try:
self.colWidth[nwOutline[hName]] = self.mainConf.pxInt(tmpWidth[hName])
self._colWidth[nwOutline[hName]] = self.mainConf.pxInt(tmpWidth[hName])
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]
self._colHidden[nwOutline[hName]] = tmpHidden[hName]
except Exception:
logger.warning("Ignored unknown outline column '%s'", str(hName))
self.headerMenu.setHiddenState(self.colHidden)
self.headerMenu.setHiddenState(self._colHidden)
return
@@ -314,19 +317,19 @@ class GuiOutline(QTreeWidget):
the last known width in case they're unhidden again.
"""
# If we haven't built the tree, there is nothing to save.
if self.lastBuild == 0:
if self._lastBuild == 0:
return
treeOrder = []
colWidth = {}
colWidth = {}
colHidden = {}
for hItem in nwOutline:
colWidth[hItem.name] = self.mainConf.rpxInt(self.colWidth[hItem])
colHidden[hItem.name] = self.colHidden[hItem]
colWidth[hItem.name] = self.mainConf.rpxInt(self._colWidth[hItem])
colHidden[hItem.name] = self._colHidden[hItem]
for iCol in range(self.columnCount()):
hName = self.treeOrder[iCol].name
hName = self._treeOrder[iCol].name
treeOrder.append(hName)
iLog = self.treeHead.logicalIndex(iCol)
@@ -353,41 +356,40 @@ class GuiOutline(QTreeWidget):
"""
self.clear()
if self.firstView:
if self._firstView:
theLabels = []
for i, hItem in enumerate(self.treeOrder):
for i, hItem in enumerate(self._treeOrder):
theLabels.append(trConst(nwLabels.OUTLINE_COLS[hItem]))
self.colIndex[hItem] = i
self._colIdx[hItem] = i
self.setHeaderLabels(theLabels)
for hItem in self.treeOrder:
self.setColumnWidth(self.colIndex[hItem], self.colWidth[hItem])
self.setColumnHidden(self.colIndex[hItem], self.colHidden[hItem])
for hItem in self._treeOrder:
self.setColumnWidth(self._colIdx[hItem], self._colWidth[hItem])
self.setColumnHidden(self._colIdx[hItem], self._colHidden[hItem])
# Make sure title column is always visible,
# and handle column always hidden
self.setColumnHidden(self.colIndex[nwOutline.TITLE], False)
self.setColumnHidden(self._colIdx[nwOutline.TITLE], False)
headItem = self.headerItem()
headItem.setTextAlignment(self.colIndex[nwOutline.CCOUNT], Qt.AlignRight)
headItem.setTextAlignment(self.colIndex[nwOutline.WCOUNT], Qt.AlignRight)
headItem.setTextAlignment(self.colIndex[nwOutline.PCOUNT], Qt.AlignRight)
headItem.setTextAlignment(self._colIdx[nwOutline.CCOUNT], Qt.AlignRight)
headItem.setTextAlignment(self._colIdx[nwOutline.WCOUNT], Qt.AlignRight)
headItem.setTextAlignment(self._colIdx[nwOutline.PCOUNT], Qt.AlignRight)
currTitle = None
currTitle = None
currChapter = None
currScene = None
currScene = None
for tKey, tHandle, sTitle, novIdx in self.theIndex.novelStructure(skipExcluded=True):
tItem = self._createTreeItem(tHandle, sTitle, novIdx)
self.treeMap[tKey] = tItem
tLevel = novIdx["level"]
if tLevel == "H1":
self.addTopLevelItem(tItem)
currTitle = tItem
currTitle = tItem
currChapter = None
currScene = None
currScene = None
elif tLevel == "H2":
if currTitle is None:
@@ -395,7 +397,7 @@ class GuiOutline(QTreeWidget):
else:
currTitle.addChild(tItem)
currChapter = tItem
currScene = None
currScene = None
elif tLevel == "H3":
if currChapter is None:
@@ -421,47 +423,47 @@ class GuiOutline(QTreeWidget):
tItem.setExpanded(True)
self.lastBuild = time()
self._lastBuild = time()
return
def _createTreeItem(self, tHandle, sTitle, novIdx):
"""Populate a tree item with all the column values.
"""
nwItem = self.theProject.projTree[tHandle]
nwItem = self.theProject.projTree[tHandle]
newItem = QTreeWidgetItem()
hIcon = "doc_%s" % novIdx["level"].lower()
hIcon = "doc_%s" % novIdx["level"].lower()
cC = int(novIdx["cCount"])
wC = int(novIdx["wCount"])
pC = int(novIdx["pCount"])
newItem.setText(self.colIndex[nwOutline.TITLE], novIdx["title"])
newItem.setData(self.colIndex[nwOutline.TITLE], Qt.UserRole, tHandle)
newItem.setIcon(self.colIndex[nwOutline.TITLE], self.theTheme.getIcon(hIcon))
newItem.setText(self.colIndex[nwOutline.LEVEL], novIdx["level"])
newItem.setText(self.colIndex[nwOutline.LABEL], nwItem.itemName)
newItem.setIcon(self.colIndex[nwOutline.LABEL], self.theTheme.getIcon("proj_document"))
newItem.setText(self.colIndex[nwOutline.LINE], sTitle[1:].lstrip("0"))
newItem.setData(self.colIndex[nwOutline.LINE], Qt.UserRole, sTitle)
newItem.setText(self.colIndex[nwOutline.SYNOP], novIdx["synopsis"])
newItem.setText(self.colIndex[nwOutline.CCOUNT], f"{cC:n}")
newItem.setText(self.colIndex[nwOutline.WCOUNT], f"{wC:n}")
newItem.setText(self.colIndex[nwOutline.PCOUNT], f"{pC:n}")
newItem.setTextAlignment(self.colIndex[nwOutline.CCOUNT], Qt.AlignRight)
newItem.setTextAlignment(self.colIndex[nwOutline.WCOUNT], Qt.AlignRight)
newItem.setTextAlignment(self.colIndex[nwOutline.PCOUNT], Qt.AlignRight)
newItem.setText(self._colIdx[nwOutline.TITLE], novIdx["title"])
newItem.setData(self._colIdx[nwOutline.TITLE], Qt.UserRole, tHandle)
newItem.setIcon(self._colIdx[nwOutline.TITLE], self.theTheme.getIcon(hIcon))
newItem.setText(self._colIdx[nwOutline.LEVEL], novIdx["level"])
newItem.setText(self._colIdx[nwOutline.LABEL], nwItem.itemName)
newItem.setIcon(self._colIdx[nwOutline.LABEL], self.theTheme.getIcon("proj_document"))
newItem.setText(self._colIdx[nwOutline.LINE], sTitle[1:].lstrip("0"))
newItem.setData(self._colIdx[nwOutline.LINE], Qt.UserRole, sTitle)
newItem.setText(self._colIdx[nwOutline.SYNOP], novIdx["synopsis"])
newItem.setText(self._colIdx[nwOutline.CCOUNT], f"{cC:n}")
newItem.setText(self._colIdx[nwOutline.WCOUNT], f"{wC:n}")
newItem.setText(self._colIdx[nwOutline.PCOUNT], f"{pC:n}")
newItem.setTextAlignment(self._colIdx[nwOutline.CCOUNT], Qt.AlignRight)
newItem.setTextAlignment(self._colIdx[nwOutline.WCOUNT], Qt.AlignRight)
newItem.setTextAlignment(self._colIdx[nwOutline.PCOUNT], Qt.AlignRight)
theRefs = self.theIndex.getReferences(tHandle, sTitle)
newItem.setText(self.colIndex[nwOutline.POV], ", ".join(theRefs[nwKeyWords.POV_KEY]))
newItem.setText(self.colIndex[nwOutline.FOCUS], ", ".join(theRefs[nwKeyWords.FOCUS_KEY]))
newItem.setText(self.colIndex[nwOutline.CHAR], ", ".join(theRefs[nwKeyWords.CHAR_KEY]))
newItem.setText(self.colIndex[nwOutline.PLOT], ", ".join(theRefs[nwKeyWords.PLOT_KEY]))
newItem.setText(self.colIndex[nwOutline.TIME], ", ".join(theRefs[nwKeyWords.TIME_KEY]))
newItem.setText(self.colIndex[nwOutline.WORLD], ", ".join(theRefs[nwKeyWords.WORLD_KEY]))
newItem.setText(self.colIndex[nwOutline.OBJECT], ", ".join(theRefs[nwKeyWords.OBJECT_KEY]))
newItem.setText(self.colIndex[nwOutline.ENTITY], ", ".join(theRefs[nwKeyWords.ENTITY_KEY]))
newItem.setText(self.colIndex[nwOutline.CUSTOM], ", ".join(theRefs[nwKeyWords.CUSTOM_KEY]))
newItem.setText(self._colIdx[nwOutline.POV], ", ".join(theRefs[nwKeyWords.POV_KEY]))
newItem.setText(self._colIdx[nwOutline.FOCUS], ", ".join(theRefs[nwKeyWords.FOCUS_KEY]))
newItem.setText(self._colIdx[nwOutline.CHAR], ", ".join(theRefs[nwKeyWords.CHAR_KEY]))
newItem.setText(self._colIdx[nwOutline.PLOT], ", ".join(theRefs[nwKeyWords.PLOT_KEY]))
newItem.setText(self._colIdx[nwOutline.TIME], ", ".join(theRefs[nwKeyWords.TIME_KEY]))
newItem.setText(self._colIdx[nwOutline.WORLD], ", ".join(theRefs[nwKeyWords.WORLD_KEY]))
newItem.setText(self._colIdx[nwOutline.OBJECT], ", ".join(theRefs[nwKeyWords.OBJECT_KEY]))
newItem.setText(self._colIdx[nwOutline.ENTITY], ", ".join(theRefs[nwKeyWords.ENTITY_KEY]))
newItem.setText(self._colIdx[nwOutline.CUSTOM], ", ".join(theRefs[nwKeyWords.CUSTOM_KEY]))
return newItem
+3 -3
View File
@@ -191,7 +191,7 @@ class GuiOutlineDetails(QScrollArea):
# Selected Item Tags
self.tagsGroup = QGroupBox(self.tr("Reference Tags"), self)
self.tagsForm = QGridLayout()
self.tagsForm = QGridLayout()
self.tagsGroup.setLayout(self.tagsForm)
self.tagsForm.addWidget(self.povKeyLabel, 0, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
@@ -279,8 +279,8 @@ class GuiOutlineDetails(QScrollArea):
"""Update the content of the tree with the given handle and line
number pointing to a header.
"""
nwItem = self.theProject.projTree[tHandle]
novIdx = self.theIndex.getNovelData(tHandle, sTitle)
nwItem = self.theProject.projTree[tHandle]
novIdx = self.theIndex.getNovelData(tHandle, sTitle)
theRefs = self.theIndex.getReferences(tHandle, sTitle)
if nwItem is None or novIdx is None:
return False
+5 -5
View File
@@ -24,8 +24,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import nw
import logging
import math
import logging
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QFont
@@ -66,10 +66,10 @@ class GuiProjectDetails(PagedDialog):
self.mainConf.pxInt(self.optState.getInt("GuiProjectDetails", "winHeight", wH))
)
self.tabMain = GuiProjectDetailsMain(self.theParent, self.theProject)
self.tabMain = GuiProjectDetailsMain(self.theParent, self.theProject)
self.tabContents = GuiProjectDetailsContents(self.theParent, self.theProject)
self.addTab(self.tabMain, self.tr("Overview"))
self.addTab(self.tabMain, self.tr("Overview"))
self.addTab(self.tabContents, self.tr("Contents"))
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
@@ -413,8 +413,8 @@ class GuiProjectDetailsContents(QWidget):
"""Set the content of the chapter/page tree.
"""
dblPages = self.dblValue.isChecked()
wpPage = self.wpValue.value()
fstPage = self.poValue.value() - 1
wpPage = self.wpValue.value()
fstPage = self.poValue.value() - 1
pTotal = 0
tPages = 1
+2 -2
View File
@@ -132,7 +132,7 @@ class GuiProjectTree(QTreeWidget):
self.initTree()
# Internal Function Mapping
self.makeAlert = self.theParent.makeAlert
self.makeAlert = self.theParent.makeAlert
self.askQuestion = self.theParent.askQuestion
logger.debug("GuiProjectTree initialisation complete")
@@ -1167,7 +1167,7 @@ class GuiProjectTreeMenu(QMenu):
inTrash = theItem.itemParent == trashHandle and trashHandle is not None
isTrash = theItem.itemHandle == trashHandle and trashHandle is not None
isFile = theItem.itemType == nwItemType.FILE
isFile = theItem.itemType == nwItemType.FILE
allowNew = not (isTrash or inTrash)
+4 -4
View File
@@ -51,8 +51,8 @@ class GuiMainStatus(QStatusBar):
self.refTime = None
self.userIdle = False
colNone = QColor(*self.theTheme.statNone)
colTrue = QColor(*self.theTheme.statUnsaved)
colNone = QColor(*self.theTheme.statNone)
colTrue = QColor(*self.theTheme.statUnsaved)
colFalse = QColor(*self.theTheme.statSaved)
iPx = self.theTheme.baseIconSize
@@ -243,8 +243,8 @@ class StatusLED(QAbstractButton):
self._colNone = colNone
self._colGood = colGood
self._colBad = colBad
self._theCol = colNone
self._colBad = colBad
self._theCol = colNone
self.setFixedWidth(sW)
self.setFixedHeight(sH)
+9 -9
View File
@@ -25,9 +25,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import nw
import os
import logging
import configparser
import os
from math import ceil
from functools import partial
@@ -272,7 +272,7 @@ class GuiTheme:
cssData = ""
try:
if os.path.isfile(self.cssFile):
with open(self.cssFile, mode="r", encoding="utf8") as inFile:
with open(self.cssFile, mode="r", encoding="utf-8") as inFile:
cssData = inFile.read()
except Exception:
logger.error("Could not load theme css file")
@@ -282,7 +282,7 @@ class GuiTheme:
# Config File
confParser = configparser.ConfigParser()
try:
with open(self.confFile, mode="r", encoding="utf8") as inFile:
with open(self.confFile, mode="r", encoding="utf-8") as inFile:
confParser.read_file(inFile)
except Exception:
logger.error("Could not load theme settings from: %s", self.confFile)
@@ -340,7 +340,7 @@ class GuiTheme:
confParser = configparser.ConfigParser()
try:
with open(self.syntaxFile, mode="r", encoding="utf8") as inFile:
with open(self.syntaxFile, mode="r", encoding="utf-8") as inFile:
confParser.read_file(inFile)
except Exception:
logger.error("Could not load syntax colours from: %s", self.syntaxFile)
@@ -395,7 +395,7 @@ class GuiTheme:
)
logger.verbose("Checking theme config for '%s'", themeDir)
try:
with open(themeConf, mode="r", encoding="utf8") as inFile:
with open(themeConf, mode="r", encoding="utf-8") as inFile:
confParser.read_file(inFile)
except Exception as e:
self.makeAlert([
@@ -421,14 +421,14 @@ class GuiTheme:
return self.syntaxList
confParser = configparser.ConfigParser()
syntaxDir = os.path.join(self.mainConf.themeRoot, self.syntaxPath)
syntaxDir = os.path.join(self.mainConf.themeRoot, self.syntaxPath)
for syntaxFile in os.listdir(syntaxDir):
syntaxPath = os.path.join(syntaxDir, syntaxFile)
if not os.path.isfile(syntaxPath):
continue
logger.verbose("Checking theme syntax for '%s'", syntaxFile)
try:
with open(syntaxPath, mode="r", encoding="utf8") as inFile:
with open(syntaxPath, mode="r", encoding="utf-8") as inFile:
confParser.read_file(inFile)
except Exception as e:
self.makeAlert([
@@ -646,7 +646,7 @@ class GuiIcons:
# Config File
confParser = configparser.ConfigParser()
try:
with open(self.confFile, mode="r", encoding="utf8") as inFile:
with open(self.confFile, mode="r", encoding="utf-8") as inFile:
confParser.read_file(inFile)
except Exception:
logger.error("Could not load icon theme settings from: %s", self.confFile)
@@ -744,7 +744,7 @@ class GuiIcons:
themeConf = os.path.join(themePath, self.confName)
logger.verbose("Checking icon theme config for '%s'", themeDir)
try:
with open(themeConf, mode="r", encoding="utf8") as inFile:
with open(themeConf, mode="r", encoding="utf-8") as inFile:
confParser.read_file(inFile)
except Exception as e:
self.makeAlert([
+26 -27
View File
@@ -24,11 +24,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import nw
import logging
import os
import logging
from datetime import datetime
from time import time
from datetime import datetime
from PyQt5.QtCore import Qt, QTimer, QSize, QThreadPool, pyqtSlot
from PyQt5.QtGui import QIcon, QPixmap, QColor, QKeySequence, QCursor
@@ -71,15 +71,12 @@ class GuiMain(QMainWindow):
logger.info("OS: %s", self.mainConf.osType)
logger.info("Kernel: %s", self.mainConf.kernelVer)
logger.info("Host: %s", self.mainConf.hostName)
logger.info(
"Qt5 Version: %s (%d)", self.mainConf.verQtString, self.mainConf.verQtValue
)
logger.info(
"PyQt5 Version: %s (%d)", self.mainConf.verPyQtString, self.mainConf.verPyQtValue
)
logger.info(
"Python Version: %s (0x%x)", self.mainConf.verPyString, self.mainConf.verPyHexVal
)
logger.info("Qt5 Version: %s (%d)",
self.mainConf.verQtString, self.mainConf.verQtValue)
logger.info("PyQt5 Version: %s (%d)",
self.mainConf.verPyQtString, self.mainConf.verPyQtValue)
logger.info("Python Version: %s (0x%x)",
self.mainConf.verPyString, self.mainConf.verPyHexVal)
logger.info("GUI Language: %s", self.mainConf.guiLang)
# Core Classes
@@ -137,7 +134,7 @@ class GuiMain(QMainWindow):
# Project Tree Tabs
self.projTabs = QTabWidget()
self.projTabs.setTabPosition(QTabWidget.South)
self.projTabs.setStyleSheet(r"QTabWidget::pane {border: 0;};")
self.projTabs.setStyleSheet("QTabWidget::pane {border: 0;};")
self.projTabs.addTab(self.treeView, self.tr("Project"))
self.projTabs.addTab(self.novelView, self.tr("Novel"))
self.projTabs.currentChanged.connect(self._projTabsChanged)
@@ -152,7 +149,7 @@ class GuiMain(QMainWindow):
self.treeButtons.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.treeButtons.setIconSize(QSize(btnSize, btnSize))
self.treeButtons.setContentsMargins(0, 0, 0, 0)
self.treeButtons.setStyleSheet(r"QToolBar {padding: 0;}")
self.treeButtons.setStyleSheet("QToolBar {padding: 0;}")
self.projTabs.setCornerWidget(self.treeButtons, Qt.BottomRightCorner)
self.projDetailsBtn = QAction(self.tr("Project Details"))
@@ -199,7 +196,7 @@ class GuiMain(QMainWindow):
# Main Tabs : Editor / Outline
self.mainTabs = QTabWidget()
self.mainTabs.setTabPosition(QTabWidget.East)
self.mainTabs.setStyleSheet(r"QTabWidget::pane {border: 0;}")
self.mainTabs.setStyleSheet("QTabWidget::pane {border: 0;}")
self.mainTabs.addTab(self.splitDocs, self.tr("Editor"))
self.mainTabs.addTab(self.splitOutline, self.tr("Outline"))
self.mainTabs.currentChanged.connect(self._mainTabChanged)
@@ -415,7 +412,7 @@ class GuiMain(QMainWindow):
self.saveDocument()
if self.theProject.projAltered:
saveOK = self.saveProject()
saveOK = self.saveProject()
doBackup = False
if self.theProject.doBackup and self.mainConf.backupOnClose:
doBackup = True
@@ -438,7 +435,7 @@ class GuiMain(QMainWindow):
self.theProject.closeProject(self.idleTime)
self.idleRefTime = time()
self.idleTime = 0.0
self.idleTime = 0.0
self.theIndex.clearIndex()
self.clearGUI()
@@ -490,14 +487,16 @@ class GuiMain(QMainWindow):
self, self.tr("Project Locked"),
"%s<br><br>%s<br>%s" % (
self.tr(
"The project is already open by another instance of novelWriter, and "
"is therefore locked. Override lock and continue anyway?"
"The project is already open by another instance of "
"novelWriter, and is therefore locked. Override lock "
"and continue anyway?"
),
self.tr(
"Note: If the program or the computer previously crashed, the lock "
"can safely be overridden. If, however, another instance of "
"novelWriter has the project open, overriding the lock may corrupt "
"the project, and is not recommended."
"Note: If the program or the computer previously "
"crashed, the lock can safely be overridden. If, "
"however, another instance of novelWriter has the "
"project open, overriding the lock may corrupt the "
"project, and is not recommended."
),
lockDetails
),
@@ -510,9 +509,9 @@ class GuiMain(QMainWindow):
return False
# Project is loaded
self.hasProject = True
self.hasProject = True
self.idleRefTime = time()
self.idleTime = 0.0
self.idleTime = 0.0
# Load the tag index
self.theIndex.loadIndex()
@@ -721,7 +720,7 @@ class GuiMain(QMainWindow):
theText = None
try:
with open(loadFile, mode="rt", encoding="utf8") as inFile:
with open(loadFile, mode="rt", encoding="utf-8") as inFile:
theText = inFile.read()
self.mainConf.setLastPath(loadFile)
except Exception as e:
@@ -740,8 +739,8 @@ class GuiMain(QMainWindow):
msgYes = self.askQuestion(
self.tr("Import Document"),
self.tr(
"Importing the file will overwrite the current content of the document. "
"Do you want to proceed?"
"Importing the file will overwrite the current content of "
"the document. Do you want to proceed?"
)
)
if not msgYes:
+23 -27
View File
@@ -24,24 +24,24 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import nw
import logging
import json
import os
import json
import logging
from time import time
from datetime import datetime
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
from PyQt5.QtGui import (
QPalette, QColor, QFont, QCursor, QFontInfo
)
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import (
qApp, QDialog, QVBoxLayout, QHBoxLayout, QTextBrowser, QPushButton, QLabel,
QLineEdit, QGroupBox, QGridLayout, QProgressBar, QMenu, QAction,
QFileDialog, QFontDialog, QSpinBox, QScrollArea, QSplitter, QWidget,
QSizePolicy, QDoubleSpinBox, QComboBox
)
from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
from nw.core import ToHtml, ToOdt, ToMarkdown
from nw.enum import nwAlert, nwItemType, nwItemLayout, nwItemClass
@@ -55,14 +55,12 @@ logger = logging.getLogger(__name__)
class GuiBuildNovel(QDialog):
FMT_PDF = 1 # Print to PDF
FMT_ODT = 2 # Open Document file
FMT_FODT = 3 # Flat Open Document file
FMT_HTM = 4 # HTML5
FMT_NWD = 5 # nW Markdown
FMT_MD = 6 # Standard Markdown
FMT_GH = 7 # GitHub Markdown
FMT_JSON_H = 8 # HTML5 wrapped in JSON
FMT_JSON_M = 9 # nW Markdown wrapped in JSON
@@ -560,8 +558,8 @@ class GuiBuildNovel(QDialog):
"""Load the previously generated document from cache.
"""
if self._loadCache():
textFont = self.textFont.text()
textSize = self.textSize.value()
textFont = self.textFont.text()
textSize = self.textSize.value()
justifyText = self.justifyText.isChecked()
self.docView.setTextFont(textFont, textSize)
self.docView.setJustify(justifyText)
@@ -596,14 +594,14 @@ class GuiBuildNovel(QDialog):
"""
# Get Settings
justifyText = self.justifyText.isChecked()
noStyling = self.noStyling.isChecked()
textFont = self.textFont.text()
textSize = self.textSize.value()
noStyling = self.noStyling.isChecked()
textFont = self.textFont.text()
textSize = self.textSize.value()
replaceTabs = self.replaceTabs.isChecked()
self.htmlText = []
self.htmlText = []
self.htmlStyle = []
self.htmlSize = 0
self.htmlSize = 0
# Build Preview
# =============
@@ -672,7 +670,7 @@ class GuiBuildNovel(QDialog):
textFixed = fontInfo.fixedPitch()
isHtml = isinstance(bldObj, ToHtml)
isOdt = isinstance(bldObj, ToOdt)
isOdt = isinstance(bldObj, ToOdt)
bldObj.setTitleFormat(fmtTitle)
bldObj.setChapterFormat(fmtChapter)
@@ -706,7 +704,7 @@ class GuiBuildNovel(QDialog):
for nItt, tItem in enumerate(self.theProject.projTree):
noteRoot = noteFiles
noteRoot = noteFiles
noteRoot &= tItem.itemType == nwItemType.ROOT
noteRoot &= tItem.itemClass != nwItemClass.NOVEL
noteRoot &= tItem.itemClass != nwItemClass.ARCHIVE
@@ -848,12 +846,12 @@ class GuiBuildNovel(QDialog):
# ==================
cleanName = makeFileNameSafe(self.theProject.projName)
fileName = "%s.%s" % (cleanName, fileExt)
saveDir = self.mainConf.lastPath
fileName = "%s.%s" % (cleanName, fileExt)
saveDir = self.mainConf.lastPath
if not os.path.isdir(saveDir):
saveDir = os.path.expanduser("~")
savePath = os.path.join(saveDir, fileName)
savePath = os.path.join(saveDir, fileName)
savePath, _ = QFileDialog.getSaveFileName(
self, self.tr("Save Document As"), savePath
)
@@ -967,7 +965,7 @@ class GuiBuildNovel(QDialog):
}
try:
with open(savePath, mode="w", encoding="utf8") as outFile:
with open(savePath, mode="w", encoding="utf-8") as outFile:
outFile.write(json.dumps(jsonData, indent=2))
wSuccess = True
except Exception as e:
@@ -1045,10 +1043,9 @@ class GuiBuildNovel(QDialog):
buildCache = os.path.join(self.theProject.projCache, nwFiles.BUILD_CACHE)
dataCount = 0
if os.path.isfile(buildCache):
logger.debug("Loading build cache")
try:
with open(buildCache, mode="r", encoding="utf8") as inFile:
with open(buildCache, mode="r", encoding="utf-8") as inFile:
theJson = inFile.read()
theData = json.loads(theJson)
except Exception:
@@ -1071,10 +1068,9 @@ class GuiBuildNovel(QDialog):
"""Save the current data to cache.
"""
buildCache = os.path.join(self.theProject.projCache, nwFiles.BUILD_CACHE)
logger.debug("Saving build cache")
try:
with open(buildCache, mode="w+", encoding="utf8") as outFile:
with open(buildCache, mode="w+", encoding="utf-8") as outFile:
outFile.write(json.dumps({
"buildTime": self.buildTime,
"htmlStyle": self.htmlStyle,
@@ -1311,10 +1307,10 @@ class GuiBuildNovelDocView(QTextBrowser):
"""Set the stylesheet for the preview document.
"""
if not theStyles:
theStyles.append(r"h1, h2 {color: rgb(66, 113, 174);}")
theStyles.append(r"h3, h4 {color: rgb(50, 50, 50);}")
theStyles.append(r"a {color: rgb(66, 113, 174);}")
theStyles.append(r".tags {color: rgb(245, 135, 31); font-weight: bold;}")
theStyles.append("h1, h2 {color: rgb(66, 113, 174);}")
theStyles.append("h3, h4 {color: rgb(50, 50, 50);}")
theStyles.append("a {color: rgb(66, 113, 174);}")
theStyles.append(".tags {color: rgb(245, 135, 31); font-weight: bold;}")
self.qDocument.setDefaultStyleSheet("\n".join(theStyles))
+1 -1
View File
@@ -24,8 +24,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import nw
import logging
import os
import logging
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
+9 -9
View File
@@ -24,14 +24,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import nw
import logging
import json
import os
import json
import logging
from datetime import datetime
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QCursor
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
qApp, QDialog, QTreeWidget, QTreeWidgetItem, QDialogButtonBox, QGridLayout,
QLabel, QGroupBox, QMenu, QAction, QFileDialog, QSpinBox, QHBoxLayout
@@ -132,7 +132,7 @@ class GuiWritingStats(QDialog):
self.barImage.fill(self.palette().highlight().color())
# Session Info
self.infoBox = QGroupBox(self.tr("Sum Totals"), self)
self.infoBox = QGroupBox(self.tr("Sum Totals"), self)
self.infoForm = QGridLayout(self)
self.infoBox.setLayout(self.infoForm)
@@ -186,7 +186,7 @@ class GuiWritingStats(QDialog):
# Filter Options
sPx = self.theTheme.baseIconSize
self.filterBox = QGroupBox(self.tr("Filters"), self)
self.filterBox = QGroupBox(self.tr("Filters"), self)
self.filterForm = QGridLayout(self)
self.filterBox.setLayout(self.filterForm)
@@ -382,7 +382,7 @@ class GuiWritingStats(QDialog):
errMsg = ""
try:
with open(savePath, mode="w", encoding="utf8") as outFile:
with open(savePath, mode="w", encoding="utf-8") as outFile:
if dataFmt == self.FMT_JSON:
jsonData = []
for _, sD, tT, wD, wA, wB, tI in self.filterData:
@@ -436,8 +436,8 @@ class GuiWritingStats(QDialog):
ttNovel = 0
ttNotes = 0
ttTime = 0
ttIdle = 0
ttTime = 0
ttIdle = 0
logFile = os.path.join(self.theProject.projMeta, nwFiles.SESS_STATS)
if not os.path.isfile(logFile):
@@ -445,7 +445,7 @@ class GuiWritingStats(QDialog):
return False
try:
with open(logFile, mode="r", encoding="utf8") as inFile:
with open(logFile, mode="r", encoding="utf-8") as inFile:
for inLine in inFile:
if inLine.startswith("#"):
if inLine.startswith("# Offset"):