diff --git a/novelwriter/__init__.py b/novelwriter/__init__.py index c86bab39..8597a55c 100644 --- a/novelwriter/__init__.py +++ b/novelwriter/__init__.py @@ -64,12 +64,6 @@ __hexversion__ = "0x020007f0" __date__ = "2023-04-16" __status__ = "Stable" __domain__ = "novelwriter.io" -__url__ = "https://novelwriter.io" -__docurl__ = "https://docs.novelwriter.io/" -__sourceurl__ = "https://github.com/vkbo/novelWriter" -__issuesurl__ = "https://github.com/vkbo/novelWriter/issues" -__helpurl__ = "https://github.com/vkbo/novelWriter/discussions" -__releaseurl__ = "https://github.com/vkbo/novelWriter/releases/latest" logger = logging.getLogger(__name__) diff --git a/novelwriter/config.py b/novelwriter/config.py index eb84443b..89019ce4 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -430,10 +430,10 @@ class Config: """ logger.debug("Initialising Config ...") if isinstance(confPath, (str, Path)): - logger.info("Setting config from alternative path: %s", confPath) + logger.info("Setting alternative config path: %s", confPath) self._confPath = Path(confPath) if isinstance(dataPath, (str, Path)): - logger.info("Setting data path from alternative path: %s", dataPath) + logger.info("Setting alternative data path: %s", dataPath) self._dataPath = Path(dataPath) logger.debug("Config Path: %s", self._confPath) @@ -776,8 +776,8 @@ class Config: class RecentProjects: - def __init__(self, mainConf): - self.mainConf = mainConf + def __init__(self, config): + self._conf = config self._data = {} return @@ -786,7 +786,7 @@ class RecentProjects: """ self._data = {} - cacheFile = self.mainConf.dataPath(nwFiles.RECENT_FILE) + cacheFile = self._conf.dataPath(nwFiles.RECENT_FILE) if not cacheFile.is_file(): return True @@ -809,7 +809,7 @@ class RecentProjects: def saveCache(self): """Save the cache dictionary of recent projects. """ - cacheFile = self.mainConf.dataPath(nwFiles.RECENT_FILE) + cacheFile = self._conf.dataPath(nwFiles.RECENT_FILE) cacheTemp = cacheFile.with_suffix(".tmp") try: with open(cacheTemp, mode="w+", encoding="utf-8") as outFile: diff --git a/novelwriter/constants.py b/novelwriter/constants.py index ed7604ca..a073307e 100644 --- a/novelwriter/constants.py +++ b/novelwriter/constants.py @@ -45,6 +45,14 @@ class nwConst: MAX_DOCSIZE = 5000000 # Maxium size of a single document MAX_BUILDSIZE = 10000000 # Maxium size of a project build + # URLs + URL_WEB = "https://novelwriter.io" + URL_DOCS = "https://docs.novelwriter.io" + URL_CODE = "https://github.com/vkbo/novelWriter" + URL_REPORT = "https://github.com/vkbo/novelWriter/issues" + URL_HELP = "https://github.com/vkbo/novelWriter/discussions" + URL_RELEASE = "https://github.com/vkbo/novelWriter/releases/latest" + # END Class nwConst diff --git a/novelwriter/core/coretools.py b/novelwriter/core/coretools.py index 864487ce..627e6f75 100644 --- a/novelwriter/core/coretools.py +++ b/novelwriter/core/coretools.py @@ -27,13 +27,13 @@ along with this program. If not, see . import shutil import logging -import novelwriter from time import time from functools import partial from PyQt5.QtCore import QCoreApplication +from novelwriter import CONFIG from novelwriter.enum import nwAlert from novelwriter.common import minmax, simplified from novelwriter.constants import nwItemClass @@ -268,12 +268,8 @@ class ProjectBuilder: """ def __init__(self, mainGui): - self.mainGui = mainGui - self.mainConf = novelwriter.CONFIG - self.tr = partial(QCoreApplication.translate, "NWProject") - return ## @@ -431,7 +427,7 @@ class ProjectBuilder: logger.error("No project path set for the example project") return False - pkgSample = self.mainConf.assetPath("sample.zip") + pkgSample = CONFIG.assetPath("sample.zip") if pkgSample.is_file(): try: shutil.unpack_archive(pkgSample, projPath) diff --git a/novelwriter/core/docbuild.py b/novelwriter/core/docbuild.py index a6ad864b..64f4326a 100644 --- a/novelwriter/core/docbuild.py +++ b/novelwriter/core/docbuild.py @@ -24,10 +24,10 @@ along with this program. If not, see . """ import logging -import novelwriter from PyQt5.QtGui import QFont, QFontInfo +from novelwriter import CONFIG from novelwriter.error import formatException from novelwriter.core.tomd import ToMarkdown from novelwriter.core.toodt import ToOdt @@ -40,7 +40,6 @@ class NWBuildDocument: def __init__(self, project): - self._conf = novelwriter.CONFIG self._project = project self._build = {} self._documents = [] @@ -164,8 +163,8 @@ class NWBuildDocument: buildLang = self._build.get("format.buildLang", "en_GB") hideScene = self._build.get("format.hideScene", False) hideSection = self._build.get("format.hideSection", False) - textFont = self._build.get("format.textFont", self._conf.textFont) - textSize = self._build.get("format.textSize", self._conf.textSize) + textFont = self._build.get("format.textFont", CONFIG.textFont) + textSize = self._build.get("format.textSize", CONFIG.textSize) lineHeight = self._build.get("format.lineHeight", 1.15) justifyText = self._build.get("format.justifyText", False) noStyling = self._build.get("format.noStyling", False) diff --git a/novelwriter/core/project.py b/novelwriter/core/project.py index dea9737d..badeba21 100644 --- a/novelwriter/core/project.py +++ b/novelwriter/core/project.py @@ -25,7 +25,6 @@ along with this program. If not, see . import json import logging -import novelwriter from time import time from pathlib import Path @@ -33,6 +32,7 @@ from functools import partial from PyQt5.QtCore import QCoreApplication, QObject, pyqtSignal +from novelwriter import CONFIG, __version__, __hexversion__ from novelwriter.enum import nwItemType, nwItemClass, nwItemLayout, nwAlert from novelwriter.error import logException from novelwriter.constants import trConst, nwFiles, nwLabels @@ -58,8 +58,7 @@ class NWProject(QObject): super().__init__(parent=mainGui) # Internal - self.mainConf = novelwriter.CONFIG - self.mainGui = mainGui + self.mainGui = mainGui # Core Elements self._options = OptionState(self) # Project-specific GUI options @@ -328,7 +327,7 @@ class NWProject(QObject): # Check novelWriter Version # ========================= - if xmlReader.hexVersion > hexToInt(novelwriter.__hexversion__): + if xmlReader.hexVersion > hexToInt(__hexversion__): msgYes = self.mainGui.askQuestion( self.tr("Version Conflict"), self.tr( @@ -337,7 +336,7 @@ class NWProject(QObject): "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, novelwriter.__version__) + ).format(appVersion, __version__) ) if not msgYes: self.clearProject() @@ -351,7 +350,7 @@ class NWProject(QObject): self._loadProjectLocalisation() # Update recent projects - self.mainConf.recentProjects.update( + CONFIG.recentProjects.update( self._storage.storagePath, self._data.name, sum(self._data.initCounts), time() ) @@ -422,7 +421,7 @@ class NWProject(QObject): self._storage.runPostSaveTasks(autoSave=autoSave) # Update recent projects - self.mainConf.recentProjects.update( + CONFIG.recentProjects.update( self._storage.storagePath, self._data.name, sum(self._data.currCounts), saveTime ) @@ -455,7 +454,7 @@ class NWProject(QObject): logger.info("Backing up project") self.mainGui.setStatus(self.tr("Backing up project ...")) - backupPath = self.mainConf.backupPath() + backupPath = CONFIG.backupPath() if not isinstance(backupPath, Path): self.mainGui.makeAlert(self.tr( "Cannot backup project because no valid backup path is set. " @@ -677,13 +676,13 @@ class NWProject(QObject): def _loadProjectLocalisation(self): """Load the language data for the current project language. """ - if self._data.language is None or self.mainConf._nwLangPath is None: + if self._data.language is None or CONFIG._nwLangPath is None: self._langData = {} return False - langFile = Path(self.mainConf._nwLangPath) / f"project_{self._data.language}.json" + langFile = Path(CONFIG._nwLangPath) / f"project_{self._data.language}.json" if not langFile.is_file(): - langFile = Path(self.mainConf._nwLangPath) / "project_en_GB.json" + langFile = Path(CONFIG._nwLangPath) / "project_en_GB.json" try: with open(langFile, mode="r", encoding="utf-8") as inFile: diff --git a/novelwriter/core/projectxml.py b/novelwriter/core/projectxml.py index d3855cf0..581a0ef7 100644 --- a/novelwriter/core/projectxml.py +++ b/novelwriter/core/projectxml.py @@ -26,13 +26,13 @@ along with this program. If not, see . """ import logging -import novelwriter from enum import Enum from lxml import etree from time import time from pathlib import Path +from novelwriter import __version__, __hexversion__ from novelwriter.common import ( checkBool, checkInt, checkString, checkStringNone, formatTimeStamp, hexToInt, simplified, yesNo @@ -501,8 +501,8 @@ class ProjectXMLWriter: logger.debug("Writing project XML") xRoot = etree.Element("novelWriterXML", attrib={ - "appVersion": str(novelwriter.__version__), - "hexVersion": str(novelwriter.__hexversion__), + "appVersion": str(__version__), + "hexVersion": str(__hexversion__), "fileVersion": FILE_VERSION, "timeStamp": formatTimeStamp(saveTime), }) diff --git a/novelwriter/core/status.py b/novelwriter/core/status.py index edfede2c..a1e99899 100644 --- a/novelwriter/core/status.py +++ b/novelwriter/core/status.py @@ -26,11 +26,11 @@ along with this program. If not, see . import random import logging -import novelwriter from PyQt5.QtGui import QIcon, QPainter, QPainterPath, QPixmap, QColor from PyQt5.QtCore import QRectF, Qt +from novelwriter import CONFIG from novelwriter.common import minmax, simplified logger = logging.getLogger(__name__) @@ -47,11 +47,11 @@ class NWStatus: self._store = {} self._default = None - self._iPX = novelwriter.CONFIG.pxInt(24) + self._iPX = CONFIG.pxInt(24) - pA = novelwriter.CONFIG.pxInt(2) - pB = novelwriter.CONFIG.pxInt(20) - pR = float(novelwriter.CONFIG.pxInt(4)) + pA = CONFIG.pxInt(2) + pB = CONFIG.pxInt(20) + pR = float(CONFIG.pxInt(4)) self._iconPath = QPainterPath() self._iconPath.addRoundedRect(QRectF(pA, pA, pB, pB), pR, pR) diff --git a/novelwriter/core/storage.py b/novelwriter/core/storage.py index 2cd4c3d9..a203cf9b 100644 --- a/novelwriter/core/storage.py +++ b/novelwriter/core/storage.py @@ -24,12 +24,12 @@ along with this program. If not, see . """ import logging -import novelwriter from time import time from pathlib import Path from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile +from novelwriter import CONFIG from novelwriter.error import logException from novelwriter.common import minmax from novelwriter.constants import nwFiles @@ -47,7 +47,6 @@ class NWStorage: def __init__(self, theProject): - self.mainConf = novelwriter.CONFIG self.theProject = theProject self._storagePath = None @@ -220,8 +219,8 @@ class NWStorage: return False data = [ - self.mainConf.hostName, self.mainConf.osType, - self.mainConf.kernelVer, str(int(time())) + CONFIG.hostName, CONFIG.osType, + CONFIG.kernelVer, str(int(time())) ] try: self._lockFilePath.write_text(";".join(data), encoding="utf-8") diff --git a/novelwriter/core/tohtml.py b/novelwriter/core/tohtml.py index 30fb63dc..cca296a6 100644 --- a/novelwriter/core/tohtml.py +++ b/novelwriter/core/tohtml.py @@ -25,6 +25,7 @@ along with this program. If not, see . import logging +from novelwriter import CONFIG from novelwriter.constants import nwKeyWords, nwLabels, nwHtmlUnicode from novelwriter.core.tokenizer import Tokenizer, stripEscape @@ -204,9 +205,9 @@ class ToHtml(Tokenizer): aStyle.append("margin-top: 0;") if tStyle & self.A_IND_L: - aStyle.append(f"margin-left: {self.mainConf.tabWidth:d}px;") + aStyle.append(f"margin-left: {CONFIG.tabWidth:d}px;") if tStyle & self.A_IND_R: - aStyle.append(f"margin-right: {self.mainConf.tabWidth:d}px;") + aStyle.append(f"margin-right: {CONFIG.tabWidth:d}px;") if len(aStyle) > 0: stVals = " ".join(aStyle) diff --git a/novelwriter/core/tokenizer.py b/novelwriter/core/tokenizer.py index 56886657..ffd697c4 100644 --- a/novelwriter/core/tokenizer.py +++ b/novelwriter/core/tokenizer.py @@ -25,7 +25,6 @@ along with this program. If not, see . import re import logging -import novelwriter from abc import ABC, abstractmethod from operator import itemgetter @@ -92,7 +91,6 @@ class Tokenizer(ABC): def __init__(self, theProject): self.theProject = theProject - self.mainConf = novelwriter.CONFIG # Data Variables self._theText = "" # The raw text to be tokenized diff --git a/novelwriter/core/toodt.py b/novelwriter/core/toodt.py index 6170c7a2..4251d066 100644 --- a/novelwriter/core/toodt.py +++ b/novelwriter/core/toodt.py @@ -24,13 +24,13 @@ along with this program. If not, see . """ import logging -import novelwriter from lxml import etree from hashlib import sha256 from zipfile import ZipFile from datetime import datetime +from novelwriter import __version__ from novelwriter.constants import nwKeyWords, nwLabels from novelwriter.core.tokenizer import Tokenizer, stripEscape @@ -336,7 +336,7 @@ class ToOdt(Tokenizer): xMeta.text = timeStamp xMeta = etree.SubElement(self._xMeta, _mkTag("meta", "generator")) - xMeta.text = f"novelWriter/{novelwriter.__version__}" + xMeta.text = f"novelWriter/{__version__}" xMeta = etree.SubElement(self._xMeta, _mkTag("meta", "initial-creator")) xMeta.text = self.theProject.data.author diff --git a/novelwriter/dialogs/about.py b/novelwriter/dialogs/about.py index e482b897..607cada2 100644 --- a/novelwriter/dialogs/about.py +++ b/novelwriter/dialogs/about.py @@ -35,7 +35,9 @@ from PyQt5.QtWidgets import ( QTextBrowser, QLabel ) +from novelwriter import CONFIG from novelwriter.common import readTextFile +from novelwriter.constants import nwConst logger = logging.getLogger(__name__) @@ -48,19 +50,18 @@ class GuiAbout(QDialog): logger.debug("Initialising GuiAbout ...") self.setObjectName("GuiAbout") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.outerBox = QVBoxLayout() self.innerBox = QHBoxLayout() - self.innerBox.setSpacing(self.mainConf.pxInt(16)) + self.innerBox.setSpacing(CONFIG.pxInt(16)) self.setWindowTitle(self.tr("About novelWriter")) - self.setMinimumWidth(self.mainConf.pxInt(650)) - self.setMinimumHeight(self.mainConf.pxInt(600)) + self.setMinimumWidth(CONFIG.pxInt(650)) + self.setMinimumHeight(CONFIG.pxInt(600)) - nPx = self.mainConf.pxInt(96) + nPx = CONFIG.pxInt(96) self.nwIcon = QLabel() self.nwIcon.setPixmap(self.mainGui.mainTheme.getPixmap("novelwriter", (nPx, nPx))) self.lblName = QLabel("novelWriter") @@ -68,7 +69,7 @@ class GuiAbout(QDialog): self.lblDate = QLabel(datetime.strptime(novelwriter.__date__, "%Y-%m-%d").strftime("%x")) self.leftBox = QVBoxLayout() - self.leftBox.setSpacing(self.mainConf.pxInt(4)) + self.leftBox.setSpacing(CONFIG.pxInt(4)) self.leftBox.addWidget(self.nwIcon, 0, Qt.AlignCenter) self.leftBox.addWidget(self.lblName, 0, Qt.AlignCenter) self.leftBox.addWidget(self.lblVers, 0, Qt.AlignCenter) @@ -79,19 +80,19 @@ class GuiAbout(QDialog): # Pages self.pageAbout = QTextBrowser() self.pageAbout.setOpenExternalLinks(True) - self.pageAbout.document().setDocumentMargin(self.mainConf.pxInt(16)) + self.pageAbout.document().setDocumentMargin(CONFIG.pxInt(16)) self.pageNotes = QTextBrowser() self.pageNotes.setOpenExternalLinks(True) - self.pageNotes.document().setDocumentMargin(self.mainConf.pxInt(16)) + self.pageNotes.document().setDocumentMargin(CONFIG.pxInt(16)) self.pageCredits = QTextBrowser() self.pageCredits.setOpenExternalLinks(True) - self.pageCredits.document().setDocumentMargin(self.mainConf.pxInt(16)) + self.pageCredits.document().setDocumentMargin(CONFIG.pxInt(16)) self.pageLicense = QTextBrowser() self.pageLicense.setOpenExternalLinks(True) - self.pageLicense.document().setDocumentMargin(self.mainConf.pxInt(16)) + self.pageLicense.document().setDocumentMargin(CONFIG.pxInt(16)) # Main Tab Area self.tabBox = QTabWidget() @@ -150,7 +151,7 @@ class GuiAbout(QDialog): title1=self.tr("About novelWriter"), copy=novelwriter.__copyright__, link=self.tr("Website: {0}").format( - f"{novelwriter.__domain__}" + f"{novelwriter.__domain__}" ), intro=self.tr( "novelWriter is a markdown-like text editor designed for organising and " @@ -182,7 +183,7 @@ class GuiAbout(QDialog): def _fillNotesPage(self): """Load the content for the Release Notes page. """ - docPath = self.mainConf.assetPath("text") / "release_notes.htm" + docPath = CONFIG.assetPath("text") / "release_notes.htm" docText = readTextFile(docPath) if docText: self.pageNotes.setHtml(docText) @@ -193,7 +194,7 @@ class GuiAbout(QDialog): def _fillCreditsPage(self): """Load the content for the Credits page. """ - docPath = self.mainConf.assetPath("text") / "credits_en.htm" + docPath = CONFIG.assetPath("text") / "credits_en.htm" docText = readTextFile(docPath) if docText: self.pageCredits.setHtml(docText) @@ -204,7 +205,7 @@ class GuiAbout(QDialog): def _fillLicensePage(self): """Load the content for the Licence page. """ - docPath = self.mainConf.assetPath("text") / "gplv3_en.htm" + docPath = CONFIG.assetPath("text") / "gplv3_en.htm" docText = readTextFile(docPath) if docText: self.pageLicense.setHtml(docText) diff --git a/novelwriter/dialogs/docmerge.py b/novelwriter/dialogs/docmerge.py index db2099e0..32d7770c 100644 --- a/novelwriter/dialogs/docmerge.py +++ b/novelwriter/dialogs/docmerge.py @@ -25,7 +25,6 @@ along with this program. If not, see . """ import logging -import novelwriter from PyQt5.QtCore import Qt, QSize from PyQt5.QtWidgets import ( @@ -33,6 +32,7 @@ from PyQt5.QtWidgets import ( QListWidget, QListWidgetItem, QVBoxLayout, ) +from novelwriter import CONFIG from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.configlayout import NHelpLabel @@ -47,7 +47,6 @@ class GuiDocMerge(QDialog): logger.debug("Initialising GuiDocMerge ...") self.setObjectName("GuiDocMerge") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.theProject = mainGui.theProject @@ -62,14 +61,14 @@ class GuiDocMerge(QDialog): ), self.mainTheme.helpText) iPx = self.mainTheme.baseIconSize - hSp = self.mainConf.pxInt(12) - vSp = self.mainConf.pxInt(8) - bSp = self.mainConf.pxInt(12) + hSp = CONFIG.pxInt(12) + vSp = CONFIG.pxInt(8) + bSp = CONFIG.pxInt(12) self.listBox = QListWidget() self.listBox.setIconSize(QSize(iPx, iPx)) - self.listBox.setMinimumWidth(self.mainConf.pxInt(400)) - self.listBox.setMinimumHeight(self.mainConf.pxInt(180)) + self.listBox.setMinimumWidth(CONFIG.pxInt(400)) + self.listBox.setMinimumHeight(CONFIG.pxInt(180)) self.listBox.setSelectionBehavior(QAbstractItemView.SelectRows) self.listBox.setSelectionMode(QAbstractItemView.SingleSelection) self.listBox.setDragDropMode(QAbstractItemView.InternalMove) diff --git a/novelwriter/dialogs/docsplit.py b/novelwriter/dialogs/docsplit.py index f4fb8327..c1f97e2a 100644 --- a/novelwriter/dialogs/docsplit.py +++ b/novelwriter/dialogs/docsplit.py @@ -25,7 +25,6 @@ along with this program. If not, see . """ import logging -import novelwriter from PyQt5.QtCore import Qt from PyQt5.QtWidgets import ( @@ -33,6 +32,7 @@ from PyQt5.QtWidgets import ( QListWidgetItem, QDialogButtonBox, QLabel, QGridLayout ) +from novelwriter import CONFIG from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.configlayout import NHelpLabel @@ -51,7 +51,6 @@ class GuiDocSplit(QDialog): logger.debug("Initialising GuiDocSplit ...") self.setObjectName("GuiDocSplit") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.theProject = mainGui.theProject @@ -69,9 +68,9 @@ class GuiDocSplit(QDialog): # Values iPx = self.mainTheme.baseIconSize - hSp = self.mainConf.pxInt(12) - vSp = self.mainConf.pxInt(8) - bSp = self.mainConf.pxInt(12) + hSp = CONFIG.pxInt(12) + vSp = CONFIG.pxInt(8) + bSp = CONFIG.pxInt(12) pOptions = self.theProject.options spLevel = pOptions.getInt("GuiDocSplit", "spLevel", 3) @@ -81,8 +80,8 @@ class GuiDocSplit(QDialog): # Header Selection self.listBox = QListWidget() self.listBox.setDragDropMode(QAbstractItemView.NoDragDrop) - self.listBox.setMinimumWidth(self.mainConf.pxInt(400)) - self.listBox.setMinimumHeight(self.mainConf.pxInt(180)) + self.listBox.setMinimumWidth(CONFIG.pxInt(400)) + self.listBox.setMinimumHeight(CONFIG.pxInt(180)) self.splitLevel = QComboBox(self) self.splitLevel.addItem(self.tr("Split on Header Level 1 (Title)"), 1) diff --git a/novelwriter/dialogs/editlabel.py b/novelwriter/dialogs/editlabel.py index d2551441..58c72890 100644 --- a/novelwriter/dialogs/editlabel.py +++ b/novelwriter/dialogs/editlabel.py @@ -24,12 +24,13 @@ along with this program. If not, see . """ import logging -import novelwriter from PyQt5.QtWidgets import ( QDialog, QVBoxLayout, QLineEdit, QLabel, QDialogButtonBox, QHBoxLayout ) +from novelwriter import CONFIG + logger = logging.getLogger(__name__) @@ -41,8 +42,8 @@ class GuiEditLabel(QDialog): self.setObjectName("GuiEditLabel") self.setWindowTitle(self.tr("Item Label")) - mVd = novelwriter.CONFIG.pxInt(220) - mSp = novelwriter.CONFIG.pxInt(12) + mVd = CONFIG.pxInt(220) + mSp = CONFIG.pxInt(12) # Item Label self.labelValue = QLineEdit() diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index c450e455..b6b252de 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -24,7 +24,6 @@ along with this program. If not, see . """ import logging -import novelwriter from PyQt5.QtGui import QFont from PyQt5.QtCore import Qt, QLocale @@ -33,6 +32,7 @@ from PyQt5.QtWidgets import ( QLineEdit, QFileDialog, QFontDialog, QDoubleSpinBox ) +from novelwriter import CONFIG from novelwriter.dialogs.quotes import GuiQuoteSelect from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.pageddialog import NPagedDialog @@ -49,7 +49,6 @@ class GuiPreferences(NPagedDialog): logger.debug("Initialising GuiPreferences ...") self.setObjectName("GuiPreferences") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.theProject = mainGui.theProject @@ -76,7 +75,7 @@ class GuiPreferences(NPagedDialog): self.buttonBox.rejected.connect(self._doClose) self.addControls(self.buttonBox) - self.resize(*self.mainConf.preferencesWinSize) + self.resize(*CONFIG.preferencesWinSize) # Settings self._updateTheme = False @@ -127,7 +126,7 @@ class GuiPreferences(NPagedDialog): self.tabQuote.saveValues() self._saveWindowSize() - self.mainConf.saveConfig() + CONFIG.saveConfig() self.accept() return @@ -146,7 +145,7 @@ class GuiPreferences(NPagedDialog): def _saveWindowSize(self): """Save the dialog window size. """ - self.mainConf.setPreferencesWinSize(self.width(), self.height()) + CONFIG.setPreferencesWinSize(self.width(), self.height()) return # END Class GuiPreferences @@ -157,7 +156,6 @@ class GuiPreferencesGeneral(QWidget): def __init__(self, prefsGui): super().__init__(parent=prefsGui) - self.mainConf = novelwriter.CONFIG self.prefsGui = prefsGui self.mainGui = prefsGui.mainGui self.mainTheme = prefsGui.mainGui.mainTheme @@ -170,15 +168,15 @@ class GuiPreferencesGeneral(QWidget): # Look and Feel # ============= self.mainForm.addGroupLabel(self.tr("Look and Feel")) - minWidth = self.mainConf.pxInt(200) + minWidth = CONFIG.pxInt(200) # Select Locale self.guiLocale = QComboBox() self.guiLocale.setMinimumWidth(minWidth) - theLangs = self.mainConf.listLanguages(self.mainConf.LANG_NW) + theLangs = CONFIG.listLanguages(CONFIG.LANG_NW) for lang, langName in theLangs: self.guiLocale.addItem(langName, lang) - langIdx = self.guiLocale.findData(self.mainConf.guiLocale) + langIdx = self.guiLocale.findData(CONFIG.guiLocale) if langIdx != -1: self.guiLocale.setCurrentIndex(langIdx) @@ -194,7 +192,7 @@ class GuiPreferencesGeneral(QWidget): self.theThemes = self.mainTheme.listThemes() for themeDir, themeName in self.theThemes: self.guiTheme.addItem(themeName, themeDir) - themeIdx = self.guiTheme.findData(self.mainConf.guiTheme) + themeIdx = self.guiTheme.findData(CONFIG.guiTheme) if themeIdx != -1: self.guiTheme.setCurrentIndex(themeIdx) @@ -206,11 +204,11 @@ class GuiPreferencesGeneral(QWidget): # Editor Theme self.guiSyntax = QComboBox() - self.guiSyntax.setMinimumWidth(self.mainConf.pxInt(200)) + self.guiSyntax.setMinimumWidth(CONFIG.pxInt(200)) self.theSyntaxes = self.mainTheme.listSyntax() for syntaxFile, syntaxName in self.theSyntaxes: self.guiSyntax.addItem(syntaxName, syntaxFile) - syntaxIdx = self.guiSyntax.findData(self.mainConf.guiSyntax) + syntaxIdx = self.guiSyntax.findData(CONFIG.guiSyntax) if syntaxIdx != -1: self.guiSyntax.setCurrentIndex(syntaxIdx) @@ -223,8 +221,8 @@ class GuiPreferencesGeneral(QWidget): # Font Family self.guiFont = QLineEdit() self.guiFont.setReadOnly(True) - self.guiFont.setFixedWidth(self.mainConf.pxInt(162)) - self.guiFont.setText(self.mainConf.guiFont) + self.guiFont.setFixedWidth(CONFIG.pxInt(162)) + self.guiFont.setText(CONFIG.guiFont) self.fontButton = QPushButton("...") self.fontButton.setMaximumWidth(int(2.5*self.mainTheme.getTextWidth("..."))) self.fontButton.clicked.connect(self._selectFont) @@ -240,7 +238,7 @@ class GuiPreferencesGeneral(QWidget): self.guiFontSize.setMinimum(8) self.guiFontSize.setMaximum(60) self.guiFontSize.setSingleStep(1) - self.guiFontSize.setValue(self.mainConf.guiFontSize) + self.guiFontSize.setValue(CONFIG.guiFontSize) self.mainForm.addRow( self.tr("Font size"), self.guiFontSize, @@ -253,7 +251,7 @@ class GuiPreferencesGeneral(QWidget): self.mainForm.addGroupLabel(self.tr("GUI Settings")) self.emphLabels = NSwitch() - self.emphLabels.setChecked(self.mainConf.emphLabels) + self.emphLabels.setChecked(CONFIG.emphLabels) self.mainForm.addRow( self.tr("Emphasise partition and chapter labels"), self.emphLabels, @@ -261,7 +259,7 @@ class GuiPreferencesGeneral(QWidget): ) self.showFullPath = NSwitch() - self.showFullPath.setChecked(self.mainConf.showFullPath) + self.showFullPath.setChecked(CONFIG.showFullPath) self.mainForm.addRow( self.tr("Show full path in document header"), self.showFullPath, @@ -269,7 +267,7 @@ class GuiPreferencesGeneral(QWidget): ) self.hideVScroll = NSwitch() - self.hideVScroll.setChecked(self.mainConf.hideVScroll) + self.hideVScroll.setChecked(CONFIG.hideVScroll) self.mainForm.addRow( self.tr("Hide vertical scroll bars in main windows"), self.hideVScroll, @@ -277,7 +275,7 @@ class GuiPreferencesGeneral(QWidget): ) self.hideHScroll = NSwitch() - self.hideHScroll.setChecked(self.mainConf.hideHScroll) + self.hideHScroll.setChecked(CONFIG.hideHScroll) self.mainForm.addRow( self.tr("Hide horizontal scroll bars in main windows"), self.hideHScroll, @@ -297,22 +295,22 @@ class GuiPreferencesGeneral(QWidget): emphLabels = self.emphLabels.isChecked() # Update Flags - self.prefsGui._updateTheme |= self.mainConf.guiTheme != guiTheme - self.prefsGui._updateSyntax |= self.mainConf.guiSyntax != guiSyntax - self.prefsGui._needsRestart |= self.mainConf.guiLocale != guiLocale - self.prefsGui._needsRestart |= self.mainConf.guiFont != guiFont - self.prefsGui._needsRestart |= self.mainConf.guiFontSize != guiFontSize - self.prefsGui._refreshTree |= self.mainConf.emphLabels != emphLabels + self.prefsGui._updateTheme |= CONFIG.guiTheme != guiTheme + self.prefsGui._updateSyntax |= CONFIG.guiSyntax != guiSyntax + self.prefsGui._needsRestart |= CONFIG.guiLocale != guiLocale + self.prefsGui._needsRestart |= CONFIG.guiFont != guiFont + self.prefsGui._needsRestart |= CONFIG.guiFontSize != guiFontSize + self.prefsGui._refreshTree |= CONFIG.emphLabels != emphLabels - self.mainConf.guiLocale = guiLocale - self.mainConf.guiTheme = guiTheme - self.mainConf.guiSyntax = guiSyntax - self.mainConf.guiFont = guiFont - self.mainConf.guiFontSize = guiFontSize - self.mainConf.emphLabels = emphLabels - self.mainConf.showFullPath = self.showFullPath.isChecked() - self.mainConf.hideVScroll = self.hideVScroll.isChecked() - self.mainConf.hideHScroll = self.hideHScroll.isChecked() + CONFIG.guiLocale = guiLocale + CONFIG.guiTheme = guiTheme + CONFIG.guiSyntax = guiSyntax + CONFIG.guiFont = guiFont + CONFIG.guiFontSize = guiFontSize + CONFIG.emphLabels = emphLabels + CONFIG.showFullPath = self.showFullPath.isChecked() + CONFIG.hideVScroll = self.hideVScroll.isChecked() + CONFIG.hideHScroll = self.hideHScroll.isChecked() return @@ -324,8 +322,8 @@ class GuiPreferencesGeneral(QWidget): """Open the QFontDialog and set a font for the font style. """ currFont = QFont() - currFont.setFamily(self.mainConf.guiFont) - currFont.setPointSize(self.mainConf.guiFontSize) + currFont.setFamily(CONFIG.guiFont) + currFont.setPointSize(CONFIG.guiFontSize) theFont, theStatus = QFontDialog.getFont(currFont, self) if theStatus: self.guiFont.setText(theFont.family()) @@ -340,7 +338,6 @@ class GuiPreferencesProjects(QWidget): def __init__(self, prefsGui): super().__init__(parent=prefsGui) - self.mainConf = novelwriter.CONFIG self.mainGui = prefsGui.mainGui self.mainTheme = prefsGui.mainGui.mainTheme @@ -358,7 +355,7 @@ class GuiPreferencesProjects(QWidget): self.autoSaveDoc.setMinimum(5) self.autoSaveDoc.setMaximum(600) self.autoSaveDoc.setSingleStep(1) - self.autoSaveDoc.setValue(self.mainConf.autoSaveDoc) + self.autoSaveDoc.setValue(CONFIG.autoSaveDoc) self.mainForm.addRow( self.tr("Save document interval"), self.autoSaveDoc, @@ -371,7 +368,7 @@ class GuiPreferencesProjects(QWidget): self.autoSaveProj.setMinimum(5) self.autoSaveProj.setMaximum(600) self.autoSaveProj.setSingleStep(1) - self.autoSaveProj.setValue(self.mainConf.autoSaveProj) + self.autoSaveProj.setValue(CONFIG.autoSaveProj) self.mainForm.addRow( self.tr("Save project interval"), self.autoSaveProj, @@ -384,7 +381,7 @@ class GuiPreferencesProjects(QWidget): self.mainForm.addGroupLabel(self.tr("Project Backup")) # Backup Path - self.backupPath = self.mainConf.backupPath() + self.backupPath = CONFIG.backupPath() self.backupGetPath = QPushButton(self.tr("Browse")) self.backupGetPath.clicked.connect(self._backupFolder) self.backupPathRow = self.mainForm.addRow( @@ -395,7 +392,7 @@ class GuiPreferencesProjects(QWidget): # Run when closing self.backupOnClose = NSwitch() - self.backupOnClose.setChecked(self.mainConf.backupOnClose) + self.backupOnClose.setChecked(CONFIG.backupOnClose) self.backupOnClose.toggled.connect(self._toggledBackupOnClose) self.mainForm.addRow( self.tr("Run backup when the project is closed"), @@ -406,8 +403,8 @@ class GuiPreferencesProjects(QWidget): # Ask before backup # Only enabled when "Run when closing" is checked self.askBeforeBackup = NSwitch() - self.askBeforeBackup.setChecked(self.mainConf.askBeforeBackup) - self.askBeforeBackup.setEnabled(self.mainConf.backupOnClose) + self.askBeforeBackup.setChecked(CONFIG.askBeforeBackup) + self.askBeforeBackup.setEnabled(CONFIG.backupOnClose) self.mainForm.addRow( self.tr("Ask before running backup"), self.askBeforeBackup, @@ -420,7 +417,7 @@ class GuiPreferencesProjects(QWidget): # Pause when idle self.stopWhenIdle = NSwitch() - self.stopWhenIdle.setChecked(self.mainConf.stopWhenIdle) + self.stopWhenIdle.setChecked(CONFIG.stopWhenIdle) self.mainForm.addRow( self.tr("Pause the session timer when not writing"), self.stopWhenIdle, @@ -433,7 +430,7 @@ class GuiPreferencesProjects(QWidget): self.userIdleTime.setMaximum(600.0) self.userIdleTime.setSingleStep(0.5) self.userIdleTime.setDecimals(1) - self.userIdleTime.setValue(self.mainConf.userIdleTime/60.0) + self.userIdleTime.setValue(CONFIG.userIdleTime/60.0) self.mainForm.addRow( self.tr("Editor inactive time before pausing timer"), self.userIdleTime, @@ -447,17 +444,17 @@ class GuiPreferencesProjects(QWidget): """Save the values set for this tab. """ # Automatic Save - self.mainConf.autoSaveDoc = self.autoSaveDoc.value() - self.mainConf.autoSaveProj = self.autoSaveProj.value() + CONFIG.autoSaveDoc = self.autoSaveDoc.value() + CONFIG.autoSaveProj = self.autoSaveProj.value() # Project Backup - self.mainConf.setBackupPath(self.backupPath) - self.mainConf.backupOnClose = self.backupOnClose.isChecked() - self.mainConf.askBeforeBackup = self.askBeforeBackup.isChecked() + CONFIG.setBackupPath(self.backupPath) + CONFIG.backupOnClose = self.backupOnClose.isChecked() + CONFIG.askBeforeBackup = self.askBeforeBackup.isChecked() # Session Timer - self.mainConf.stopWhenIdle = self.stopWhenIdle.isChecked() - self.mainConf.userIdleTime = round(self.userIdleTime.value() * 60) + CONFIG.stopWhenIdle = self.stopWhenIdle.isChecked() + CONFIG.userIdleTime = round(self.userIdleTime.value() * 60) return @@ -496,7 +493,6 @@ class GuiPreferencesDocuments(QWidget): def __init__(self, prefsGui): super().__init__(parent=prefsGui) - self.mainConf = novelwriter.CONFIG self.mainGui = prefsGui.mainGui self.mainTheme = prefsGui.mainGui.mainTheme @@ -512,8 +508,8 @@ class GuiPreferencesDocuments(QWidget): # Font Family self.textFont = QLineEdit() self.textFont.setReadOnly(True) - self.textFont.setFixedWidth(self.mainConf.pxInt(162)) - self.textFont.setText(self.mainConf.textFont) + self.textFont.setFixedWidth(CONFIG.pxInt(162)) + self.textFont.setText(CONFIG.textFont) self.fontButton = QPushButton("...") self.fontButton.setMaximumWidth(int(2.5*self.mainTheme.getTextWidth("..."))) self.fontButton.clicked.connect(self._selectFont) @@ -529,7 +525,7 @@ class GuiPreferencesDocuments(QWidget): self.textSize.setMinimum(8) self.textSize.setMaximum(60) self.textSize.setSingleStep(1) - self.textSize.setValue(self.mainConf.textSize) + self.textSize.setValue(CONFIG.textSize) self.mainForm.addRow( self.tr("Font size"), self.textSize, @@ -546,7 +542,7 @@ class GuiPreferencesDocuments(QWidget): self.textWidth.setMinimum(0) self.textWidth.setMaximum(10000) self.textWidth.setSingleStep(10) - self.textWidth.setValue(self.mainConf.textWidth) + self.textWidth.setValue(CONFIG.textWidth) self.mainForm.addRow( self.tr("Maximum text width in \"Normal Mode\""), self.textWidth, @@ -559,7 +555,7 @@ class GuiPreferencesDocuments(QWidget): self.focusWidth.setMinimum(200) self.focusWidth.setMaximum(10000) self.focusWidth.setSingleStep(10) - self.focusWidth.setValue(self.mainConf.focusWidth) + self.focusWidth.setValue(CONFIG.focusWidth) self.mainForm.addRow( self.tr("Maximum text width in \"Focus Mode\""), self.focusWidth, @@ -569,7 +565,7 @@ class GuiPreferencesDocuments(QWidget): # Focus Mode Footer self.hideFocusFooter = NSwitch() - self.hideFocusFooter.setChecked(self.mainConf.hideFocusFooter) + self.hideFocusFooter.setChecked(CONFIG.hideFocusFooter) self.mainForm.addRow( self.tr("Hide document footer in \"Focus Mode\""), self.hideFocusFooter, @@ -578,7 +574,7 @@ class GuiPreferencesDocuments(QWidget): # Justify Text self.doJustify = NSwitch() - self.doJustify.setChecked(self.mainConf.doJustify) + self.doJustify.setChecked(CONFIG.doJustify) self.mainForm.addRow( self.tr("Justify the text margins"), self.doJustify, @@ -590,7 +586,7 @@ class GuiPreferencesDocuments(QWidget): self.textMargin.setMinimum(0) self.textMargin.setMaximum(900) self.textMargin.setSingleStep(1) - self.textMargin.setValue(self.mainConf.textMargin) + self.textMargin.setValue(CONFIG.textMargin) self.mainForm.addRow( self.tr("Minimum text margin"), self.textMargin, @@ -603,7 +599,7 @@ class GuiPreferencesDocuments(QWidget): self.tabWidth.setMinimum(0) self.tabWidth.setMaximum(200) self.tabWidth.setSingleStep(1) - self.tabWidth.setValue(self.mainConf.tabWidth) + self.tabWidth.setValue(CONFIG.tabWidth) self.mainForm.addRow( self.tr("Tab width"), self.tabWidth, @@ -617,16 +613,16 @@ class GuiPreferencesDocuments(QWidget): """Save the values set for this tab. """ # Text Style - self.mainConf.textFont = self.textFont.text() - self.mainConf.textSize = self.textSize.value() + CONFIG.textFont = self.textFont.text() + CONFIG.textSize = self.textSize.value() # Text Flow - self.mainConf.textWidth = self.textWidth.value() - self.mainConf.focusWidth = self.focusWidth.value() - self.mainConf.hideFocusFooter = self.hideFocusFooter.isChecked() - self.mainConf.doJustify = self.doJustify.isChecked() - self.mainConf.textMargin = self.textMargin.value() - self.mainConf.tabWidth = self.tabWidth.value() + CONFIG.textWidth = self.textWidth.value() + CONFIG.focusWidth = self.focusWidth.value() + CONFIG.hideFocusFooter = self.hideFocusFooter.isChecked() + CONFIG.doJustify = self.doJustify.isChecked() + CONFIG.textMargin = self.textMargin.value() + CONFIG.tabWidth = self.tabWidth.value() return @@ -638,8 +634,8 @@ class GuiPreferencesDocuments(QWidget): """Open the QFontDialog and set a font for the font style. """ currFont = QFont() - currFont.setFamily(self.mainConf.textFont) - currFont.setPointSize(self.mainConf.textSize) + currFont.setFamily(CONFIG.textFont) + currFont.setPointSize(CONFIG.textSize) theFont, theStatus = QFontDialog.getFont(currFont, self) if theStatus: self.textFont.setText(theFont.family()) @@ -655,7 +651,6 @@ class GuiPreferencesEditor(QWidget): def __init__(self, prefsGui): super().__init__(parent=prefsGui) - self.mainConf = novelwriter.CONFIG self.mainGui = prefsGui.mainGui self.mainTheme = prefsGui.mainGui.mainTheme @@ -664,7 +659,7 @@ class GuiPreferencesEditor(QWidget): self.mainForm.setHelpTextStyle(self.mainTheme.helpText) self.setLayout(self.mainForm) - mW = self.mainConf.pxInt(250) + mW = CONFIG.pxInt(250) # Spell Checking # ============== @@ -675,7 +670,7 @@ class GuiPreferencesEditor(QWidget): self.spellLanguage.setMaximumWidth(mW) langAvail = self.mainGui.docEditor.spEnchant.listDictionaries() - if self.mainConf.hasEnchant: + if CONFIG.hasEnchant: if langAvail: for spTag, spProv in langAvail: qLocal = QLocale(spTag) @@ -688,7 +683,7 @@ class GuiPreferencesEditor(QWidget): self.spellLanguage.addItem(self.tr("Not installed"), "") self.spellLanguage.setEnabled(False) - spellIdx = self.spellLanguage.findData(self.mainConf.spellLanguage) + spellIdx = self.spellLanguage.findData(CONFIG.spellLanguage) if spellIdx != -1: self.spellLanguage.setCurrentIndex(spellIdx) @@ -703,7 +698,7 @@ class GuiPreferencesEditor(QWidget): self.bigDocLimit.setMinimum(10) self.bigDocLimit.setMaximum(10000) self.bigDocLimit.setSingleStep(10) - self.bigDocLimit.setValue(self.mainConf.bigDocLimit) + self.bigDocLimit.setValue(CONFIG.bigDocLimit) self.mainForm.addRow( self.tr("Big document limit"), self.bigDocLimit, @@ -721,7 +716,7 @@ class GuiPreferencesEditor(QWidget): self.wordCountTimer.setMinimum(2.0) self.wordCountTimer.setMaximum(600.0) self.wordCountTimer.setSingleStep(0.1) - self.wordCountTimer.setValue(self.mainConf.wordCountTimer) + self.wordCountTimer.setValue(CONFIG.wordCountTimer) self.mainForm.addRow( self.tr("Word count interval"), self.wordCountTimer, @@ -730,7 +725,7 @@ class GuiPreferencesEditor(QWidget): # Include Notes in Word Count self.incNotesWCount = NSwitch() - self.incNotesWCount.setChecked(self.mainConf.incNotesWCount) + self.incNotesWCount.setChecked(CONFIG.incNotesWCount) self.mainForm.addRow( self.tr("Include project notes in status bar word count"), self.incNotesWCount @@ -742,7 +737,7 @@ class GuiPreferencesEditor(QWidget): # Show Tabs and Spaces self.showTabsNSpaces = NSwitch() - self.showTabsNSpaces.setChecked(self.mainConf.showTabsNSpaces) + self.showTabsNSpaces.setChecked(CONFIG.showTabsNSpaces) self.mainForm.addRow( self.tr("Show tabs and spaces"), self.showTabsNSpaces @@ -750,7 +745,7 @@ class GuiPreferencesEditor(QWidget): # Show Line Endings self.showLineEndings = NSwitch() - self.showLineEndings.setChecked(self.mainConf.showLineEndings) + self.showLineEndings.setChecked(CONFIG.showLineEndings) self.mainForm.addRow( self.tr("Show line endings"), self.showLineEndings @@ -765,7 +760,7 @@ class GuiPreferencesEditor(QWidget): self.scrollPastEnd.setMinimum(0) self.scrollPastEnd.setMaximum(100) self.scrollPastEnd.setSingleStep(1) - self.scrollPastEnd.setValue(int(self.mainConf.scrollPastEnd)) + self.scrollPastEnd.setValue(int(CONFIG.scrollPastEnd)) self.mainForm.addRow( self.tr("Scroll past end of the document"), self.scrollPastEnd, @@ -775,7 +770,7 @@ class GuiPreferencesEditor(QWidget): # Typewriter Scrolling self.autoScroll = NSwitch() - self.autoScroll.setChecked(self.mainConf.autoScroll) + self.autoScroll.setChecked(CONFIG.autoScroll) self.mainForm.addRow( self.tr("Typewriter style scrolling when you type"), self.autoScroll, @@ -787,7 +782,7 @@ class GuiPreferencesEditor(QWidget): self.autoScrollPos.setMinimum(10) self.autoScrollPos.setMaximum(90) self.autoScrollPos.setSingleStep(1) - self.autoScrollPos.setValue(int(self.mainConf.autoScrollPos)) + self.autoScrollPos.setValue(int(CONFIG.autoScrollPos)) self.mainForm.addRow( self.tr("Minimum position for Typewriter scrolling"), self.autoScrollPos, @@ -801,21 +796,21 @@ class GuiPreferencesEditor(QWidget): """Save the values set for this tab. """ # Spell Checking - self.mainConf.spellLanguage = self.spellLanguage.currentData() - self.mainConf.bigDocLimit = self.bigDocLimit.value() + CONFIG.spellLanguage = self.spellLanguage.currentData() + CONFIG.bigDocLimit = self.bigDocLimit.value() # Word Count - self.mainConf.wordCountTimer = self.wordCountTimer.value() - self.mainConf.incNotesWCount = self.incNotesWCount.isChecked() + CONFIG.wordCountTimer = self.wordCountTimer.value() + CONFIG.incNotesWCount = self.incNotesWCount.isChecked() # Writing Guides - self.mainConf.showTabsNSpaces = self.showTabsNSpaces.isChecked() - self.mainConf.showLineEndings = self.showLineEndings.isChecked() + CONFIG.showTabsNSpaces = self.showTabsNSpaces.isChecked() + CONFIG.showLineEndings = self.showLineEndings.isChecked() # Scroll Behaviour - self.mainConf.scrollPastEnd = self.scrollPastEnd.value() - self.mainConf.autoScroll = self.autoScroll.isChecked() - self.mainConf.autoScrollPos = self.autoScrollPos.value() + CONFIG.scrollPastEnd = self.scrollPastEnd.value() + CONFIG.autoScroll = self.autoScroll.isChecked() + CONFIG.autoScrollPos = self.autoScrollPos.value() return @@ -827,7 +822,6 @@ class GuiPreferencesSyntax(QWidget): def __init__(self, prefsGui): super().__init__(parent=prefsGui) - self.mainConf = novelwriter.CONFIG self.prefsGui = prefsGui self.mainGui = prefsGui.mainGui self.mainTheme = prefsGui.mainGui.mainTheme @@ -842,7 +836,7 @@ class GuiPreferencesSyntax(QWidget): self.mainForm.addGroupLabel(self.tr("Quotes & Dialogue")) self.highlightQuotes = NSwitch() - self.highlightQuotes.setChecked(self.mainConf.highlightQuotes) + self.highlightQuotes.setChecked(CONFIG.highlightQuotes) self.highlightQuotes.toggled.connect(self._toggleHighlightQuotes) self.mainForm.addRow( self.tr("Highlight text wrapped in quotes"), @@ -851,7 +845,7 @@ class GuiPreferencesSyntax(QWidget): ) self.allowOpenSQuote = NSwitch() - self.allowOpenSQuote.setChecked(self.mainConf.allowOpenSQuote) + self.allowOpenSQuote.setChecked(CONFIG.allowOpenSQuote) self.mainForm.addRow( self.tr("Allow open-ended single quotes"), self.allowOpenSQuote, @@ -859,7 +853,7 @@ class GuiPreferencesSyntax(QWidget): ) self.allowOpenDQuote = NSwitch() - self.allowOpenDQuote.setChecked(self.mainConf.allowOpenDQuote) + self.allowOpenDQuote.setChecked(CONFIG.allowOpenDQuote) self.mainForm.addRow( self.tr("Allow open-ended double quotes"), self.allowOpenDQuote, @@ -871,7 +865,7 @@ class GuiPreferencesSyntax(QWidget): self.mainForm.addGroupLabel(self.tr("Text Emphasis")) self.highlightEmph = NSwitch() - self.highlightEmph.setChecked(self.mainConf.highlightEmph) + self.highlightEmph.setChecked(CONFIG.highlightEmph) self.mainForm.addRow( self.tr("Add highlight colour to emphasised text"), self.highlightEmph, @@ -884,7 +878,7 @@ class GuiPreferencesSyntax(QWidget): self.mainForm.addGroupLabel(self.tr("Text Errors")) self.showMultiSpaces = NSwitch() - self.showMultiSpaces.setChecked(self.mainConf.showMultiSpaces) + self.showMultiSpaces.setChecked(CONFIG.showMultiSpaces) self.mainForm.addRow( self.tr("Highlight multiple or trailing spaces"), self.showMultiSpaces, @@ -902,15 +896,15 @@ class GuiPreferencesSyntax(QWidget): highlightEmph = self.highlightEmph.isChecked() showMultiSpaces = self.showMultiSpaces.isChecked() - self.prefsGui._updateSyntax |= self.mainConf.highlightQuotes != highlightQuotes - self.prefsGui._updateSyntax |= self.mainConf.highlightEmph != highlightEmph - self.prefsGui._updateSyntax |= self.mainConf.showMultiSpaces != showMultiSpaces + self.prefsGui._updateSyntax |= CONFIG.highlightQuotes != highlightQuotes + self.prefsGui._updateSyntax |= CONFIG.highlightEmph != highlightEmph + self.prefsGui._updateSyntax |= CONFIG.showMultiSpaces != showMultiSpaces - self.mainConf.highlightQuotes = highlightQuotes - self.mainConf.allowOpenSQuote = allowOpenSQuote - self.mainConf.allowOpenDQuote = allowOpenDQuote - self.mainConf.highlightEmph = highlightEmph - self.mainConf.showMultiSpaces = showMultiSpaces + CONFIG.highlightQuotes = highlightQuotes + CONFIG.allowOpenSQuote = allowOpenSQuote + CONFIG.allowOpenDQuote = allowOpenDQuote + CONFIG.highlightEmph = highlightEmph + CONFIG.showMultiSpaces = showMultiSpaces return @@ -934,7 +928,6 @@ class GuiPreferencesAutomation(QWidget): def __init__(self, prefsGui): super().__init__(parent=prefsGui) - self.mainConf = novelwriter.CONFIG self.mainGui = prefsGui.mainGui self.mainTheme = prefsGui.mainGui.mainTheme @@ -949,7 +942,7 @@ class GuiPreferencesAutomation(QWidget): # Auto-Select Word Under Cursor self.autoSelect = NSwitch() - self.autoSelect.setChecked(self.mainConf.autoSelect) + self.autoSelect.setChecked(CONFIG.autoSelect) self.mainForm.addRow( self.tr("Auto-select word under cursor"), self.autoSelect, @@ -958,7 +951,7 @@ class GuiPreferencesAutomation(QWidget): # Auto-Replace as You Type Main Switch self.doReplace = NSwitch() - self.doReplace.setChecked(self.mainConf.doReplace) + self.doReplace.setChecked(CONFIG.doReplace) self.doReplace.toggled.connect(self._toggleAutoReplaceMain) self.mainForm.addRow( self.tr("Auto-replace text as you type"), @@ -972,8 +965,8 @@ class GuiPreferencesAutomation(QWidget): # Auto-Replace Single Quotes self.doReplaceSQuote = NSwitch() - self.doReplaceSQuote.setChecked(self.mainConf.doReplaceSQuote) - self.doReplaceSQuote.setEnabled(self.mainConf.doReplace) + self.doReplaceSQuote.setChecked(CONFIG.doReplaceSQuote) + self.doReplaceSQuote.setEnabled(CONFIG.doReplace) self.mainForm.addRow( self.tr("Auto-replace single quotes"), self.doReplaceSQuote, @@ -982,8 +975,8 @@ class GuiPreferencesAutomation(QWidget): # Auto-Replace Double Quotes self.doReplaceDQuote = NSwitch() - self.doReplaceDQuote.setChecked(self.mainConf.doReplaceDQuote) - self.doReplaceDQuote.setEnabled(self.mainConf.doReplace) + self.doReplaceDQuote.setChecked(CONFIG.doReplaceDQuote) + self.doReplaceDQuote.setEnabled(CONFIG.doReplace) self.mainForm.addRow( self.tr("Auto-replace double quotes"), self.doReplaceDQuote, @@ -992,8 +985,8 @@ class GuiPreferencesAutomation(QWidget): # Auto-Replace Hyphens self.doReplaceDash = NSwitch() - self.doReplaceDash.setChecked(self.mainConf.doReplaceDash) - self.doReplaceDash.setEnabled(self.mainConf.doReplace) + self.doReplaceDash.setChecked(CONFIG.doReplaceDash) + self.doReplaceDash.setEnabled(CONFIG.doReplace) self.mainForm.addRow( self.tr("Auto-replace dashes"), self.doReplaceDash, @@ -1002,8 +995,8 @@ class GuiPreferencesAutomation(QWidget): # Auto-Replace Dots self.doReplaceDots = NSwitch() - self.doReplaceDots.setChecked(self.mainConf.doReplaceDots) - self.doReplaceDots.setEnabled(self.mainConf.doReplace) + self.doReplaceDots.setChecked(CONFIG.doReplaceDots) + self.doReplaceDots.setEnabled(CONFIG.doReplace) self.mainForm.addRow( self.tr("Auto-replace dots"), self.doReplaceDots, @@ -1017,7 +1010,7 @@ class GuiPreferencesAutomation(QWidget): # Pad Before self.fmtPadBefore = QLineEdit() self.fmtPadBefore.setMaxLength(32) - self.fmtPadBefore.setText(self.mainConf.fmtPadBefore) + self.fmtPadBefore.setText(CONFIG.fmtPadBefore) self.mainForm.addRow( self.tr("Insert non-breaking space before"), self.fmtPadBefore, @@ -1027,7 +1020,7 @@ class GuiPreferencesAutomation(QWidget): # Pad After self.fmtPadAfter = QLineEdit() self.fmtPadAfter.setMaxLength(32) - self.fmtPadAfter.setText(self.mainConf.fmtPadAfter) + self.fmtPadAfter.setText(CONFIG.fmtPadAfter) self.mainForm.addRow( self.tr("Insert non-breaking space after"), self.fmtPadAfter, @@ -1036,8 +1029,8 @@ class GuiPreferencesAutomation(QWidget): # Use Thin Space self.fmtPadThin = NSwitch() - self.fmtPadThin.setChecked(self.mainConf.fmtPadThin) - self.fmtPadThin.setEnabled(self.mainConf.doReplace) + self.fmtPadThin.setChecked(CONFIG.fmtPadThin) + self.fmtPadThin.setEnabled(CONFIG.doReplace) self.mainForm.addRow( self.tr("Use thin space instead"), self.fmtPadThin, @@ -1050,19 +1043,19 @@ class GuiPreferencesAutomation(QWidget): """Save the values set for this tab. """ # Automatic Features - self.mainConf.autoSelect = self.autoSelect.isChecked() - self.mainConf.doReplace = self.doReplace.isChecked() + CONFIG.autoSelect = self.autoSelect.isChecked() + CONFIG.doReplace = self.doReplace.isChecked() # Replace as You Type - self.mainConf.doReplaceSQuote = self.doReplaceSQuote.isChecked() - self.mainConf.doReplaceDQuote = self.doReplaceDQuote.isChecked() - self.mainConf.doReplaceDash = self.doReplaceDash.isChecked() - self.mainConf.doReplaceDots = self.doReplaceDots.isChecked() + CONFIG.doReplaceSQuote = self.doReplaceSQuote.isChecked() + CONFIG.doReplaceDQuote = self.doReplaceDQuote.isChecked() + CONFIG.doReplaceDash = self.doReplaceDash.isChecked() + CONFIG.doReplaceDots = self.doReplaceDots.isChecked() # Automatic Padding - self.mainConf.fmtPadBefore = self.fmtPadBefore.text().strip() - self.mainConf.fmtPadAfter = self.fmtPadAfter.text().strip() - self.mainConf.fmtPadThin = self.fmtPadThin.isChecked() + CONFIG.fmtPadBefore = self.fmtPadBefore.text().strip() + CONFIG.fmtPadAfter = self.fmtPadAfter.text().strip() + CONFIG.fmtPadThin = self.fmtPadThin.isChecked() return @@ -1089,7 +1082,6 @@ class GuiPreferencesQuotes(QWidget): def __init__(self, prefsGui): super().__init__(parent=prefsGui) - self.mainConf = novelwriter.CONFIG self.mainGui = prefsGui.mainGui self.mainTheme = prefsGui.mainGui.mainTheme @@ -1102,7 +1094,7 @@ class GuiPreferencesQuotes(QWidget): # =============== self.mainForm.addGroupLabel(self.tr("Quotation Style")) - qWidth = self.mainConf.pxInt(40) + qWidth = CONFIG.pxInt(40) bWidth = int(2.5*self.mainTheme.getTextWidth("...")) self.quoteSym = {} @@ -1112,7 +1104,7 @@ class GuiPreferencesQuotes(QWidget): self.quoteSym["SO"].setReadOnly(True) self.quoteSym["SO"].setFixedWidth(qWidth) self.quoteSym["SO"].setAlignment(Qt.AlignCenter) - self.quoteSym["SO"].setText(self.mainConf.fmtSQuoteOpen) + self.quoteSym["SO"].setText(CONFIG.fmtSQuoteOpen) self.btnSingleStyleO = QPushButton("...") self.btnSingleStyleO.setMaximumWidth(bWidth) self.btnSingleStyleO.clicked.connect(lambda: self._getQuote("SO")) @@ -1128,7 +1120,7 @@ class GuiPreferencesQuotes(QWidget): self.quoteSym["SC"].setReadOnly(True) self.quoteSym["SC"].setFixedWidth(qWidth) self.quoteSym["SC"].setAlignment(Qt.AlignCenter) - self.quoteSym["SC"].setText(self.mainConf.fmtSQuoteClose) + self.quoteSym["SC"].setText(CONFIG.fmtSQuoteClose) self.btnSingleStyleC = QPushButton("...") self.btnSingleStyleC.setMaximumWidth(bWidth) self.btnSingleStyleC.clicked.connect(lambda: self._getQuote("SC")) @@ -1145,7 +1137,7 @@ class GuiPreferencesQuotes(QWidget): self.quoteSym["DO"].setReadOnly(True) self.quoteSym["DO"].setFixedWidth(qWidth) self.quoteSym["DO"].setAlignment(Qt.AlignCenter) - self.quoteSym["DO"].setText(self.mainConf.fmtDQuoteOpen) + self.quoteSym["DO"].setText(CONFIG.fmtDQuoteOpen) self.btnDoubleStyleO = QPushButton("...") self.btnDoubleStyleO.setMaximumWidth(bWidth) self.btnDoubleStyleO.clicked.connect(lambda: self._getQuote("DO")) @@ -1161,7 +1153,7 @@ class GuiPreferencesQuotes(QWidget): self.quoteSym["DC"].setReadOnly(True) self.quoteSym["DC"].setFixedWidth(qWidth) self.quoteSym["DC"].setAlignment(Qt.AlignCenter) - self.quoteSym["DC"].setText(self.mainConf.fmtDQuoteClose) + self.quoteSym["DC"].setText(CONFIG.fmtDQuoteClose) self.btnDoubleStyleC = QPushButton("...") self.btnDoubleStyleC.setMaximumWidth(bWidth) self.btnDoubleStyleC.clicked.connect(lambda: self._getQuote("DC")) @@ -1178,10 +1170,10 @@ class GuiPreferencesQuotes(QWidget): """Save the values set for this tab. """ # Quotation Style - self.mainConf.fmtSQuoteOpen = self.quoteSym["SO"].text() - self.mainConf.fmtSQuoteClose = self.quoteSym["SC"].text() - self.mainConf.fmtDQuoteOpen = self.quoteSym["DO"].text() - self.mainConf.fmtDQuoteClose = self.quoteSym["DC"].text() + CONFIG.fmtSQuoteOpen = self.quoteSym["SO"].text() + CONFIG.fmtSQuoteClose = self.quoteSym["SC"].text() + CONFIG.fmtDQuoteOpen = self.quoteSym["DO"].text() + CONFIG.fmtDQuoteClose = self.quoteSym["DC"].text() return ## diff --git a/novelwriter/dialogs/projdetails.py b/novelwriter/dialogs/projdetails.py index d286b044..1ae21ab7 100644 --- a/novelwriter/dialogs/projdetails.py +++ b/novelwriter/dialogs/projdetails.py @@ -25,7 +25,6 @@ along with this program. If not, see . import math import logging -import novelwriter from PyQt5.QtCore import Qt, QSize, pyqtSlot from PyQt5.QtGui import QFont @@ -34,6 +33,7 @@ from PyQt5.QtWidgets import ( QLineEdit, QSpinBox, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget ) +from novelwriter import CONFIG from novelwriter.common import formatTime, numberToRoman from novelwriter.constants import nwUnicode from novelwriter.gui.components import NovelSelector @@ -51,21 +51,20 @@ class GuiProjectDetails(NPagedDialog): logger.debug("Initialising GuiProjectDetails ...") self.setObjectName("GuiProjectDetails") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.theProject = mainGui.theProject self.setWindowTitle(self.tr("Project Details")) - wW = self.mainConf.pxInt(600) - wH = self.mainConf.pxInt(400) + wW = CONFIG.pxInt(600) + wH = CONFIG.pxInt(400) pOptions = self.theProject.options self.setMinimumWidth(wW) self.setMinimumHeight(wH) self.resize( - self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "winWidth", wW)), - self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "winHeight", wH)) + CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "winWidth", wW)), + CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "winHeight", wH)) ) self.tabMain = GuiProjectDetailsMain(self.mainGui, self.theProject) @@ -108,15 +107,15 @@ class GuiProjectDetails(NPagedDialog): def _saveGuiSettings(self): """Save GUI settings. """ - winWidth = self.mainConf.rpxInt(self.width()) - winHeight = self.mainConf.rpxInt(self.height()) + winWidth = CONFIG.rpxInt(self.width()) + winHeight = CONFIG.rpxInt(self.height()) cColWidth = self.tabContents.getColumnSizes() - widthCol0 = self.mainConf.rpxInt(cColWidth[0]) - widthCol1 = self.mainConf.rpxInt(cColWidth[1]) - widthCol2 = self.mainConf.rpxInt(cColWidth[2]) - widthCol3 = self.mainConf.rpxInt(cColWidth[3]) - widthCol4 = self.mainConf.rpxInt(cColWidth[4]) + widthCol0 = CONFIG.rpxInt(cColWidth[0]) + widthCol1 = CONFIG.rpxInt(cColWidth[1]) + widthCol2 = CONFIG.rpxInt(cColWidth[2]) + widthCol3 = CONFIG.rpxInt(cColWidth[3]) + widthCol4 = CONFIG.rpxInt(cColWidth[4]) wordsPerPage = self.tabContents.wpValue.value() countFrom = self.tabContents.poValue.value() @@ -144,15 +143,14 @@ class GuiProjectDetailsMain(QWidget): def __init__(self, mainGui, theProject): super().__init__(parent=mainGui) - self.mainConf = novelwriter.CONFIG self.theProject = theProject self.mainGui = mainGui self.mainTheme = mainGui.mainTheme fPx = self.mainTheme.fontPixelSize fPt = self.mainTheme.fontPointSize - vPx = self.mainConf.pxInt(4) - hPx = self.mainConf.pxInt(12) + vPx = CONFIG.pxInt(4) + hPx = CONFIG.pxInt(12) # Header # ====== @@ -278,7 +276,6 @@ class GuiProjectDetailsContents(QWidget): def __init__(self, mainGui, theProject): super().__init__(parent=mainGui) - self.mainConf = novelwriter.CONFIG self.theProject = theProject self.mainGui = mainGui self.mainTheme = mainGui.mainTheme @@ -288,8 +285,8 @@ class GuiProjectDetailsContents(QWidget): self._currentRoot = None iPx = self.mainTheme.baseIconSize - hPx = self.mainConf.pxInt(12) - vPx = self.mainConf.pxInt(4) + hPx = CONFIG.pxInt(12) + vPx = CONFIG.pxInt(4) pOptions = self.theProject.options # Header @@ -298,7 +295,7 @@ class GuiProjectDetailsContents(QWidget): self.tocLabel = QLabel("%s" % self.tr("Table of Contents")) self.novelValue = NovelSelector(self, self.theProject, self.mainGui) - self.novelValue.setMinimumWidth(self.mainConf.pxInt(200)) + self.novelValue.setMinimumWidth(CONFIG.pxInt(200)) self.novelValue.novelSelectionChanged.connect(self._novelValueChanged) self.headBox = QHBoxLayout() @@ -332,11 +329,11 @@ class GuiProjectDetailsContents(QWidget): treeHeader.setStretchLastSection(True) treeHeader.setMinimumSectionSize(hPx) - wCol0 = self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol0", 200)) - wCol1 = self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol1", 60)) - wCol2 = self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol2", 60)) - wCol3 = self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol3", 60)) - wCol4 = self.mainConf.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol4", 90)) + wCol0 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol0", 200)) + wCol1 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol1", 60)) + wCol2 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol2", 60)) + wCol3 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol3", 60)) + wCol4 = CONFIG.pxInt(pOptions.getInt("GuiProjectDetails", "widthCol4", 90)) self.tocTree.setColumnWidth(0, wCol0) self.tocTree.setColumnWidth(1, wCol1) diff --git a/novelwriter/dialogs/projload.py b/novelwriter/dialogs/projload.py index d6f876c4..2dfd41f6 100644 --- a/novelwriter/dialogs/projload.py +++ b/novelwriter/dialogs/projload.py @@ -24,7 +24,6 @@ along with this program. If not, see . """ import logging -import novelwriter from pathlib import Path from datetime import datetime @@ -37,6 +36,7 @@ from PyQt5.QtWidgets import ( QFileDialog, QLineEdit ) +from novelwriter import CONFIG from novelwriter.common import formatInt from novelwriter.constants import nwFiles @@ -59,14 +59,13 @@ class GuiProjectLoad(QDialog): logger.debug("Initialising GuiProjectLoad ...") self.setObjectName("GuiProjectLoad") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.openState = self.NONE_STATE self.openPath = None - sPx = self.mainConf.pxInt(16) - nPx = self.mainConf.pxInt(96) + sPx = CONFIG.pxInt(16) + nPx = CONFIG.pxInt(96) iPx = self.mainTheme.baseIconSize self.outerBox = QVBoxLayout() @@ -75,8 +74,8 @@ class GuiProjectLoad(QDialog): self.innerBox.setSpacing(sPx) self.setWindowTitle(self.tr("Open Project")) - self.setMinimumWidth(self.mainConf.pxInt(650)) - self.setMinimumHeight(self.mainConf.pxInt(400)) + self.setMinimumWidth(CONFIG.pxInt(650)) + self.setMinimumHeight(CONFIG.pxInt(400)) self.nwIcon = QLabel() self.nwIcon.setPixmap(self.mainGui.mainTheme.getPixmap("novelwriter", (nPx, nPx))) @@ -120,8 +119,8 @@ class GuiProjectLoad(QDialog): self.projectForm.setColumnStretch(0, 0) self.projectForm.setColumnStretch(1, 1) self.projectForm.setColumnStretch(2, 0) - self.projectForm.setVerticalSpacing(self.mainConf.pxInt(4)) - self.projectForm.setHorizontalSpacing(self.mainConf.pxInt(8)) + self.projectForm.setVerticalSpacing(CONFIG.pxInt(4)) + self.projectForm.setHorizontalSpacing(CONFIG.pxInt(8)) self.innerBox.addLayout(self.projectForm) @@ -228,7 +227,7 @@ class GuiProjectLoad(QDialog): ).format(projName) ) if msgYes: - self.mainConf.recentProjects.remove( + CONFIG.recentProjects.remove( selList[0].data(self.C_NAME, Qt.UserRole) ) self._populateList() @@ -257,14 +256,14 @@ class GuiProjectLoad(QDialog): colWidths[self.C_NAME] = self.listBox.columnWidth(self.C_NAME) colWidths[self.C_COUNT] = self.listBox.columnWidth(self.C_COUNT) colWidths[self.C_TIME] = self.listBox.columnWidth(self.C_TIME) - self.mainConf.setProjLoadColWidths(colWidths) + CONFIG.setProjLoadColWidths(colWidths) return def _populateList(self): """Populate the list box with recent project data. """ self.listBox.clear() - dataList = self.mainConf.recentProjects.listEntries() + dataList = CONFIG.recentProjects.listEntries() sortList = sorted(dataList, key=lambda x: x[3], reverse=True) nwxIcon = self.mainGui.mainTheme.getIcon("proj_nwx") for path, title, words, time in sortList: @@ -283,7 +282,7 @@ class GuiProjectLoad(QDialog): if self.listBox.topLevelItemCount() > 0: self.listBox.topLevelItem(0).setSelected(True) - projColWidth = self.mainConf.projLoadColWidths + projColWidth = CONFIG.projLoadColWidths if len(projColWidth) == 3: self.listBox.setColumnWidth(self.C_NAME, projColWidth[self.C_NAME]) self.listBox.setColumnWidth(self.C_COUNT, projColWidth[self.C_COUNT]) diff --git a/novelwriter/dialogs/projsettings.py b/novelwriter/dialogs/projsettings.py index 11fc0e00..0bc0229f 100644 --- a/novelwriter/dialogs/projsettings.py +++ b/novelwriter/dialogs/projsettings.py @@ -24,7 +24,6 @@ along with this program. If not, see . """ import logging -import novelwriter from PyQt5.QtGui import QIcon, QPixmap, QColor from PyQt5.QtCore import Qt, QLocale, pyqtSlot @@ -33,6 +32,7 @@ from PyQt5.QtWidgets import ( QPushButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget ) +from novelwriter import CONFIG from novelwriter.enum import nwAlert from novelwriter.common import simplified from novelwriter.extensions.switch import NSwitch @@ -55,22 +55,21 @@ class GuiProjectSettings(NPagedDialog): logger.debug("Initialising GuiProjectSettings ...") self.setObjectName("GuiProjectSettings") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.theProject = mainGui.theProject self.theProject.countStatus() self.setWindowTitle(self.tr("Project Settings")) - wW = self.mainConf.pxInt(570) - wH = self.mainConf.pxInt(375) + wW = CONFIG.pxInt(570) + wH = CONFIG.pxInt(375) pOptions = self.theProject.options self.setMinimumWidth(wW) self.setMinimumHeight(wH) self.resize( - self.mainConf.pxInt(pOptions.getInt("GuiProjectSettings", "winWidth", wW)), - self.mainConf.pxInt(pOptions.getInt("GuiProjectSettings", "winHeight", wH)) + CONFIG.pxInt(pOptions.getInt("GuiProjectSettings", "winWidth", wW)), + CONFIG.pxInt(pOptions.getInt("GuiProjectSettings", "winHeight", wH)) ) self.tabMain = GuiProjectEditMain(self) @@ -170,11 +169,11 @@ class GuiProjectSettings(NPagedDialog): def _saveGuiSettings(self): """Save GUI settings. """ - winWidth = self.mainConf.rpxInt(self.width()) - winHeight = self.mainConf.rpxInt(self.height()) - replaceColW = self.mainConf.rpxInt(self.tabReplace.listBox.columnWidth(0)) - statusColW = self.mainConf.rpxInt(self.tabStatus.listBox.columnWidth(0)) - importColW = self.mainConf.rpxInt(self.tabImport.listBox.columnWidth(0)) + winWidth = CONFIG.rpxInt(self.width()) + winHeight = CONFIG.rpxInt(self.height()) + replaceColW = CONFIG.rpxInt(self.tabReplace.listBox.columnWidth(0)) + statusColW = CONFIG.rpxInt(self.tabStatus.listBox.columnWidth(0)) + importColW = CONFIG.rpxInt(self.tabImport.listBox.columnWidth(0)) pOptions = self.theProject.options pOptions.setValue("GuiProjectSettings", "winWidth", winWidth) @@ -193,7 +192,6 @@ class GuiProjectEditMain(QWidget): def __init__(self, projGui): super().__init__(parent=projGui) - self.mainConf = novelwriter.CONFIG self.mainGui = projGui.mainGui self.theProject = projGui.theProject @@ -204,7 +202,7 @@ class GuiProjectEditMain(QWidget): self.mainForm.addGroupLabel(self.tr("Project Settings")) - xW = self.mainConf.pxInt(250) + xW = CONFIG.pxInt(250) self.editName = QLineEdit() self.editName.setMaxLength(200) @@ -282,7 +280,6 @@ class GuiProjectEditStatus(QWidget): def __init__(self, projGui, isStatus): super().__init__(parent=projGui) - self.mainConf = novelwriter.CONFIG self.mainGui = projGui.mainGui self.theProject = projGui.theProject self.mainTheme = projGui.mainGui.mainTheme @@ -296,7 +293,7 @@ class GuiProjectEditStatus(QWidget): pageLabel = self.tr("Note File Importance Levels") colSetting = "importColW" - wCol0 = self.mainConf.pxInt( + wCol0 = CONFIG.pxInt( self.theProject.options.getInt("GuiProjectSettings", colSetting, 130) ) @@ -571,13 +568,12 @@ class GuiProjectEditReplace(QWidget): def __init__(self, projGui): super().__init__(parent=projGui) - self.mainConf = novelwriter.CONFIG self.mainGui = projGui.mainGui self.mainTheme = projGui.mainGui.mainTheme self.theProject = projGui.theProject self.arChanged = False - wCol0 = self.mainConf.pxInt( + wCol0 = CONFIG.pxInt( self.theProject.options.getInt("GuiProjectSettings", "replaceColW", 130) ) pageLabel = self.tr("Text Replace List for Preview and Export") diff --git a/novelwriter/dialogs/quotes.py b/novelwriter/dialogs/quotes.py index ffd169da..256888ce 100644 --- a/novelwriter/dialogs/quotes.py +++ b/novelwriter/dialogs/quotes.py @@ -24,7 +24,6 @@ along with this program. If not, see . """ import logging -import novelwriter from PyQt5.QtGui import QFontMetrics from PyQt5.QtCore import Qt, QSize @@ -33,6 +32,7 @@ from PyQt5.QtWidgets import ( QListWidget, QListWidgetItem, QFrame ) +from novelwriter import CONFIG from novelwriter.constants import trConst, nwQuotes logger = logging.getLogger(__name__) @@ -45,8 +45,6 @@ class GuiQuoteSelect(QDialog): def __init__(self, parent=None, currentQuote='"'): super().__init__(parent=parent) - self.mainConf = novelwriter.CONFIG - self.outerBox = QVBoxLayout() self.innerBox = QHBoxLayout() self.labelBox = QVBoxLayout() @@ -82,8 +80,8 @@ class GuiQuoteSelect(QDialog): if sKey == currentQuote: self.listBox.setCurrentItem(qtItem) - self.listBox.setMinimumWidth(minSize + self.mainConf.pxInt(40)) - self.listBox.setMinimumHeight(self.mainConf.pxInt(150)) + self.listBox.setMinimumWidth(minSize + CONFIG.pxInt(40)) + self.listBox.setMinimumHeight(CONFIG.pxInt(150)) # Buttons self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) diff --git a/novelwriter/dialogs/updates.py b/novelwriter/dialogs/updates.py index 685f8698..8eaa353e 100644 --- a/novelwriter/dialogs/updates.py +++ b/novelwriter/dialogs/updates.py @@ -25,7 +25,6 @@ along with this program. If not, see . import json import logging -import novelwriter from datetime import datetime from urllib.request import Request, urlopen @@ -36,7 +35,9 @@ from PyQt5.QtWidgets import ( qApp, QDialog, QHBoxLayout, QVBoxLayout, QDialogButtonBox, QLabel ) +from novelwriter import CONFIG, __version__, __date__ from novelwriter.common import logException +from novelwriter.constants import nwConst logger = logging.getLogger(__name__) @@ -49,15 +50,14 @@ class GuiUpdates(QDialog): logger.debug("Initialising GuiUpdates ...") self.setObjectName("GuiUpdates") - self.mainConf = novelwriter.CONFIG - self.mainGui = mainGui + self.mainGui = mainGui self.setWindowTitle(self.tr("Check for Updates")) - nPx = self.mainConf.pxInt(96) - sPx = self.mainConf.pxInt(16) - tPx = self.mainConf.pxInt(8) - mPx = self.mainConf.pxInt(4) + nPx = CONFIG.pxInt(96) + sPx = CONFIG.pxInt(16) + tPx = CONFIG.pxInt(8) + mPx = CONFIG.pxInt(4) # Left Box self.nwIcon = QLabel() @@ -72,8 +72,8 @@ class GuiUpdates(QDialog): self.currentValue = QLabel(self.tr( "novelWriter {0} released on {1}" ).format( - "v%s" % novelwriter.__version__, - datetime.strptime(novelwriter.__date__, "%Y-%m-%d").strftime("%x")) + "v%s" % __version__, + datetime.strptime(__date__, "%Y-%m-%d").strftime("%x")) ) self.latestLabel = QLabel(self.tr("Latest Release")) @@ -152,7 +152,7 @@ class GuiUpdates(QDialog): self.latestLink.setText(self.tr( "Download: {0}" ).format( - f'{novelwriter.__url__}' + f'{nwConst.URL_WEB}' )) qApp.restoreOverrideCursor() diff --git a/novelwriter/dialogs/wordlist.py b/novelwriter/dialogs/wordlist.py index ca667ed2..73886bab 100644 --- a/novelwriter/dialogs/wordlist.py +++ b/novelwriter/dialogs/wordlist.py @@ -24,7 +24,6 @@ along with this program. If not, see . """ import logging -import novelwriter from pathlib import Path @@ -34,6 +33,7 @@ from PyQt5.QtWidgets import ( QAbstractItemView, QPushButton, QLineEdit, QLabel ) +from novelwriter import CONFIG from novelwriter.enum import nwAlert from novelwriter.error import logException from novelwriter.constants import nwFiles @@ -49,23 +49,22 @@ class GuiWordList(QDialog): logger.debug("Initialising GuiWordList ...") self.setObjectName("GuiWordList") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.theProject = mainGui.theProject self.setWindowTitle(self.tr("Project Word List")) - mS = self.mainConf.pxInt(250) - wW = self.mainConf.pxInt(320) - wH = self.mainConf.pxInt(340) + mS = CONFIG.pxInt(250) + wW = CONFIG.pxInt(320) + wH = CONFIG.pxInt(340) pOptions = self.theProject.options self.setMinimumWidth(mS) self.setMinimumHeight(mS) self.resize( - self.mainConf.pxInt(pOptions.getInt("GuiWordList", "winWidth", wW)), - self.mainConf.pxInt(pOptions.getInt("GuiWordList", "winHeight", wH)) + CONFIG.pxInt(pOptions.getInt("GuiWordList", "winWidth", wW)), + CONFIG.pxInt(pOptions.getInt("GuiWordList", "winHeight", wH)) ) # Main Widgets @@ -99,10 +98,10 @@ class GuiWordList(QDialog): self.outerBox = QVBoxLayout() self.outerBox.addWidget(self.headLabel) - self.outerBox.addSpacing(self.mainConf.pxInt(8)) + self.outerBox.addSpacing(CONFIG.pxInt(8)) self.outerBox.addWidget(self.listBox, 1) self.outerBox.addLayout(self.editBox, 0) - self.outerBox.addSpacing(self.mainConf.pxInt(12)) + self.outerBox.addSpacing(CONFIG.pxInt(12)) self.outerBox.addWidget(self.buttonBox, 0) self.setLayout(self.outerBox) @@ -210,8 +209,8 @@ class GuiWordList(QDialog): def _saveGuiSettings(self): """Save GUI settings. """ - winWidth = self.mainConf.rpxInt(self.width()) - winHeight = self.mainConf.rpxInt(self.height()) + winWidth = CONFIG.rpxInt(self.width()) + winHeight = CONFIG.rpxInt(self.height()) pOptions = self.theProject.options pOptions.setValue("GuiWordList", "winWidth", winWidth) diff --git a/novelwriter/error.py b/novelwriter/error.py index 50e7ddc0..74f45318 100644 --- a/novelwriter/error.py +++ b/novelwriter/error.py @@ -111,18 +111,17 @@ class NWErrorMessage(QDialog): error traceback. """ from traceback import format_tb - from novelwriter import __issuesurl__, __version__ + from novelwriter import __version__ + from novelwriter.constants import nwConst from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QSysInfo - self.msgHead.setText(( + self.msgHead.setText( "

An unhandled error has been encountered.

" "

Please report this error by submitting an issue report on " "GitHub, providing a description and including the error " "message and traceback shown below.

" - "

URL: {issueUrl}

" - ).format( - issueUrl=__issuesurl__, - )) + f"

URL: {nwConst.URL_REPORT}

" + ) try: kernelVersion = QSysInfo.kernelVersion() diff --git a/novelwriter/extensions/configlayout.py b/novelwriter/extensions/configlayout.py index 129400e2..f50ac2cf 100644 --- a/novelwriter/extensions/configlayout.py +++ b/novelwriter/extensions/configlayout.py @@ -23,8 +23,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import novelwriter - from PyQt5.QtGui import QColor, QPalette from PyQt5.QtCore import Qt from PyQt5.QtWidgets import ( @@ -32,6 +30,8 @@ from PyQt5.QtWidgets import ( QWidget ) +from novelwriter import CONFIG + class NConfigLayout(QGridLayout): @@ -44,7 +44,7 @@ class NConfigLayout(QGridLayout): self._itemMap = {} - wSp = novelwriter.CONFIG.pxInt(8) + wSp = CONFIG.pxInt(8) self.setHorizontalSpacing(wSp) self.setVerticalSpacing(wSp) self.setColumnStretch(0, 1) @@ -94,7 +94,7 @@ class NConfigLayout(QGridLayout): qLabel = None raise ValueError("theLabel must be a QLabel") - hM = novelwriter.CONFIG.pxInt(4) + hM = CONFIG.pxInt(4) qLabel.setContentsMargins(0, hM, 0, hM) self.addWidget(qLabel, self._nextRow, 0, 1, 2, Qt.AlignLeft) @@ -128,7 +128,7 @@ class NConfigLayout(QGridLayout): qWidget = None raise ValueError("theWidget must be a QWidget") - wSp = novelwriter.CONFIG.pxInt(8) + wSp = CONFIG.pxInt(8) qLabel.setIndent(wSp) if helpText is not None: qHelp = NHelpLabel(str(helpText), self._helpCol, self._fontScale) diff --git a/novelwriter/extensions/pageddialog.py b/novelwriter/extensions/pageddialog.py index ec22767b..28bd817c 100644 --- a/novelwriter/extensions/pageddialog.py +++ b/novelwriter/extensions/pageddialog.py @@ -23,14 +23,14 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import novelwriter - from PyQt5.QtCore import QRect, QPoint from PyQt5.QtWidgets import ( QDialog, QHBoxLayout, QStyle, QStyleOptionTab, QStylePainter, QTabBar, QTabWidget, QVBoxLayout ) +from novelwriter import CONFIG + class NPagedDialog(QDialog): @@ -92,7 +92,7 @@ class NVerticalTabBar(QTabBar): def __init__(self, parent=None): super().__init__(parent=parent) - self._mW = novelwriter.CONFIG.pxInt(150) + self._mW = CONFIG.pxInt(150) return def tabSizeHint(self, index): diff --git a/novelwriter/extensions/switch.py b/novelwriter/extensions/switch.py index ab1efa9a..529db854 100644 --- a/novelwriter/extensions/switch.py +++ b/novelwriter/extensions/switch.py @@ -23,12 +23,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import novelwriter - from PyQt5.QtGui import QPainter from PyQt5.QtCore import Qt, QRectF, QPropertyAnimation, pyqtProperty from PyQt5.QtWidgets import QSizePolicy, QAbstractButton +from novelwriter import CONFIG from novelwriter.constants import nwUnicode @@ -38,18 +37,18 @@ class NSwitch(QAbstractButton): super().__init__(parent=parent) if width is None: - self._xW = novelwriter.CONFIG.pxInt(40) + self._xW = CONFIG.pxInt(40) else: self._xW = width if height is None: - self._xH = novelwriter.CONFIG.pxInt(20) + self._xH = CONFIG.pxInt(20) else: self._xH = height self._xR = int(self._xH*0.5) self._xT = int(self._xH*0.6) - self._rB = int(novelwriter.CONFIG.guiScale*2) + self._rB = int(CONFIG.guiScale*2) self._rH = self._xH - 2*self._rB self._rR = self._xR - self._rB diff --git a/novelwriter/extensions/switchbox.py b/novelwriter/extensions/switchbox.py index d036ccb6..f1895ca9 100644 --- a/novelwriter/extensions/switchbox.py +++ b/novelwriter/extensions/switchbox.py @@ -23,8 +23,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import novelwriter - from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtWidgets import QGridLayout, QLabel, QScrollArea, QSizePolicy, QWidget @@ -38,8 +36,6 @@ class NSwitchBox(QScrollArea): def __init__(self, parent, baseSize): super().__init__(parent=parent) - self.mainConf = novelwriter.CONFIG - self._index = 0 self._hSwitch = baseSize self._wSwitch = 2*self._hSwitch diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 90a671ce..c7681759 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -31,7 +31,6 @@ along with this program. If not, see . import bisect import logging -import novelwriter from enum import Enum from time import time @@ -50,6 +49,7 @@ from PyQt5.QtWidgets import ( QFrame ) +from novelwriter import CONFIG from novelwriter.enum import nwAlert, nwDocAction, nwDocInsert, nwDocMode, nwItemClass from novelwriter.common import minmax, transferCase from novelwriter.constants import nwConst, nwFiles, nwKeyWords, nwUnicode @@ -81,7 +81,6 @@ class GuiDocEditor(QTextEdit): logger.debug("Initialising GuiDocEditor ...") # Class Variables - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.theProject = mainGui.theProject @@ -140,7 +139,7 @@ class GuiDocEditor(QTextEdit): self.customContextMenuRequested.connect(self._openContextMenu) # Editor Settings - self.setMinimumWidth(self.mainConf.pxInt(300)) + self.setMinimumWidth(CONFIG.pxInt(300)) self.setAcceptRichText(False) self.setAutoFillBackground(True) self.setFrameStyle(QFrame.NoFrame) @@ -169,7 +168,7 @@ class GuiDocEditor(QTextEdit): self.wCounterDoc.setAutoDelete(False) self.wCounterDoc.signals.countsReady.connect(self._updateDocCounts) - self.wcInterval = self.mainConf.wordCountTimer + self.wcInterval = CONFIG.wordCountTimer # Set Up Selection Word Counter self.wcTimerSel = QTimer() @@ -252,26 +251,26 @@ class GuiDocEditor(QTextEdit): # Some Constants self._nonWord = ( "\"'" - f"{self.mainConf.fmtSQuoteOpen}{self.mainConf.fmtSQuoteClose}" - f"{self.mainConf.fmtDQuoteOpen}{self.mainConf.fmtDQuoteClose}" + f"{CONFIG.fmtSQuoteOpen}{CONFIG.fmtSQuoteClose}" + f"{CONFIG.fmtDQuoteOpen}{CONFIG.fmtDQuoteClose}" ) # Typography - if self.mainConf.fmtPadThin: + if CONFIG.fmtPadThin: self._typPadChar = nwUnicode.U_THNBSP else: self._typPadChar = nwUnicode.U_NBSP - self._typSQuoteO = self.mainConf.fmtSQuoteOpen - self._typSQuoteC = self.mainConf.fmtSQuoteClose - self._typDQuoteO = self.mainConf.fmtDQuoteOpen - self._typDQuoteC = self.mainConf.fmtDQuoteClose - self._typRepDQuote = self.mainConf.doReplaceDQuote - self._typRepSQuote = self.mainConf.doReplaceSQuote - self._typRepDash = self.mainConf.doReplaceDash - self._typRepDots = self.mainConf.doReplaceDots - self._typPadBefore = self.mainConf.fmtPadBefore - self._typPadAfter = self.mainConf.fmtPadAfter + self._typSQuoteO = CONFIG.fmtSQuoteOpen + self._typSQuoteC = CONFIG.fmtSQuoteClose + self._typDQuoteO = CONFIG.fmtDQuoteOpen + self._typDQuoteC = CONFIG.fmtDQuoteClose + self._typRepDQuote = CONFIG.doReplaceDQuote + self._typRepSQuote = CONFIG.doReplaceSQuote + self._typRepDash = CONFIG.doReplaceDash + self._typRepDots = CONFIG.doReplaceDots + self._typPadBefore = CONFIG.fmtPadBefore + self._typPadAfter = CONFIG.fmtPadAfter # Reload spell check and dictionaries self.setDictionaries() @@ -279,23 +278,23 @@ class GuiDocEditor(QTextEdit): # Set font theFont = QFont() qDoc = self.document() - if self.mainConf.textFont is None: + if CONFIG.textFont is None: # If none is defined, set a default font theFont = QFont() - if self.mainConf.osWindows and "Arial" in self.mainTheme.guiFontDB.families(): + if CONFIG.osWindows and "Arial" in self.mainTheme.guiFontDB.families(): theFont.setFamily("Arial") theFont.setPointSize(12) - elif self.mainConf.osDarwin and "Courier" in self.mainTheme.guiFontDB.families(): + elif CONFIG.osDarwin and "Courier" in self.mainTheme.guiFontDB.families(): theFont.setFamily("Courier") theFont.setPointSize(12) else: theFont = qDoc.defaultFont() - self.mainConf.textFont = theFont.family() - self.mainConf.textSize = theFont.pointSize() + CONFIG.textFont = theFont.family() + CONFIG.textSize = theFont.pointSize() - theFont.setFamily(self.mainConf.textFont) - theFont.setPointSize(self.mainConf.textSize) + theFont.setFamily(CONFIG.textFont) + theFont.setPointSize(CONFIG.textSize) self.setFont(theFont) # Set default text margins @@ -303,37 +302,37 @@ class GuiDocEditor(QTextEdit): # allocated to the document itself. See issue #1112. cW = self.cursorWidth() qDoc.setDocumentMargin(cW) - self._vpMargin = max(self.mainConf.getTextMargin() - cW, 0) + self._vpMargin = max(CONFIG.getTextMargin() - cW, 0) self.setViewportMargins(self._vpMargin, self._vpMargin, self._vpMargin, self._vpMargin) # Also set the document text options for the document text flow theOpt = QTextOption() - if self.mainConf.doJustify: + if CONFIG.doJustify: theOpt.setAlignment(Qt.AlignJustify) - if self.mainConf.showTabsNSpaces: + if CONFIG.showTabsNSpaces: theOpt.setFlags(theOpt.flags() | QTextOption.ShowTabsAndSpaces) - if self.mainConf.showLineEndings: + if CONFIG.showLineEndings: theOpt.setFlags(theOpt.flags() | QTextOption.ShowLineAndParagraphSeparators) qDoc.setDefaultTextOption(theOpt) # Scroll bars - if self.mainConf.hideVScroll: + if CONFIG.hideVScroll: self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) - if self.mainConf.hideHScroll: + if CONFIG.hideHScroll: self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) # Refresh the tab stops - self.setTabStopDistance(self.mainConf.getTabWidth()) + self.setTabStopDistance(CONFIG.getTabWidth()) # Configure word count timer - self.wcInterval = self.mainConf.wordCountTimer + self.wcInterval = CONFIG.wordCountTimer self.wcTimerDoc.setInterval(int(self.wcInterval*1000)) # If we have a document open, we should reload it in case the @@ -420,10 +419,10 @@ class GuiDocEditor(QTextEdit): elif isinstance(tLine, int): self.setCursorLine(tLine) - if self.mainConf.scrollPastEnd > 0: + if CONFIG.scrollPastEnd > 0: fSize = QFontMetrics(self.font()).lineSpacing() docFrame = self.document().rootFrame().frameFormat() - docFrame.setBottomMargin(round(self.mainConf.scrollPastEnd * fSize)) + docFrame.setBottomMargin(round(CONFIG.scrollPastEnd * fSize)) self.document().rootFrame().setFrameFormat(docFrame) self.docFooter.updateLineCount() @@ -571,8 +570,8 @@ class GuiDocEditor(QTextEdit): sH = hBar.height() if hBar.isVisible() else 0 tM = self._vpMargin - if self.mainConf.textWidth > 0 or self.mainGui.isFocusMode: - tW = self.mainConf.getTextWidth(self.mainGui.isFocusMode) + if CONFIG.textWidth > 0 or self.mainGui.isFocusMode: + tW = CONFIG.getTextWidth(self.mainGui.isFocusMode) tM = max((wW - sW - tW)//2, self._vpMargin) tB = self.frameWidth() @@ -674,7 +673,7 @@ class GuiDocEditor(QTextEdit): # when it is enabled. By default, it's 30% of viewport. vPos = self.verticalScrollBar().value() cPos = self.cursorRect().topLeft().y() - mPos = int(self.mainConf.autoScrollPos*0.01 * self.viewport().height()) + mPos = int(CONFIG.autoScrollPos*0.01 * self.viewport().height()) if cPos > mPos: # Only scroll if the cursor is past the auto-scroll limit self.verticalScrollBar().setValue(max(0, vPos + cPos - mPos)) @@ -715,7 +714,7 @@ class GuiDocEditor(QTextEdit): dictionary changed signal. """ if self.theProject.data.spellLang is None: - theLang = self.mainConf.spellLanguage + theLang = CONFIG.spellLanguage else: theLang = self.theProject.data.spellLang @@ -738,7 +737,7 @@ class GuiDocEditor(QTextEdit): if theMode is None: theMode = not self._spellCheck - if not self.mainConf.hasEnchant: + if not CONFIG.hasEnchant: if theMode: self.mainGui.makeAlert(self.tr( "Spell checking requires the package PyEnchant. " @@ -1038,7 +1037,7 @@ class GuiDocEditor(QTextEdit): self.docAction(nwDocAction.SEL_ALL) return - if self.mainConf.autoScroll: + if CONFIG.autoScroll: cOld = self.cursorRect().center().y() super().keyPressEvent(keyEvent) @@ -1049,7 +1048,7 @@ class GuiDocEditor(QTextEdit): if okMod and okKey: cNew = self.cursorRect().center().y() cMov = cNew - cOld - mPos = self.mainConf.autoScrollPos*0.01 * self.viewport().height() + mPos = CONFIG.autoScrollPos*0.01 * self.viewport().height() if abs(cMov) > 0 and cOld > mPos: # Move the scroll bar vBar = self.verticalScrollBar() @@ -2090,7 +2089,7 @@ class GuiDocEditor(QTextEdit): """Check if document size crosses the big document limit set in config. If so, we will set the big document flag to True. """ - bigLim = round(self.mainConf.bigDocLimit*1000) + bigLim = round(CONFIG.bigDocLimit*1000) newState = theSize > bigLim if newState != self._bigDoc: @@ -2114,7 +2113,7 @@ class GuiDocEditor(QTextEdit): on user settings and document action. """ theCursor = self.textCursor() - if self.mainConf.autoSelect and not theCursor.hasSelection(): + if CONFIG.autoSelect and not theCursor.hasSelection(): theCursor.select(QTextCursor.WordUnderCursor) posS = theCursor.selectionStart() posE = theCursor.selectionEnd() @@ -2175,7 +2174,7 @@ class GuiDocEditor(QTextEdit): """Enable/disable the auto-replace feature temporarily. """ if theState: - self._doReplace = self.mainConf.doReplace + self._doReplace = CONFIG.doReplace else: self._doReplace = False return @@ -2245,21 +2244,20 @@ class GuiDocEditSearch(QFrame): logger.debug("Initialising GuiDocEditSearch ...") - self.mainConf = novelwriter.CONFIG self.docEditor = docEditor self.mainGui = docEditor.mainGui self.theProject = docEditor.theProject self.mainTheme = docEditor.mainTheme self.repVisible = False - self.isCaseSense = self.mainConf.searchCase - self.isWholeWord = self.mainConf.searchWord - self.isRegEx = self.mainConf.searchRegEx - self.doLoop = self.mainConf.searchLoop - self.doNextFile = self.mainConf.searchNextFile - self.doMatchCap = self.mainConf.searchMatchCap + self.isCaseSense = CONFIG.searchCase + self.isWholeWord = CONFIG.searchWord + self.isRegEx = CONFIG.searchRegEx + self.doLoop = CONFIG.searchLoop + self.doNextFile = CONFIG.searchNextFile + self.doMatchCap = CONFIG.searchMatchCap - mPx = self.mainConf.pxInt(6) + mPx = CONFIG.pxInt(6) tPx = int(0.8*self.mainTheme.fontPixelSize) self.boxFont = self.mainTheme.guiFont self.boxFont.setPointSizeF(0.9*self.mainTheme.fontPointSize) @@ -2291,7 +2289,7 @@ class GuiDocEditSearch(QFrame): self.searchLabel = QLabel(self.tr("Search")) self.searchLabel.setFont(self.boxFont) - self.searchLabel.setIndent(self.mainConf.pxInt(6)) + self.searchLabel.setIndent(CONFIG.pxInt(6)) self.resultLabel = QLabel("?/?") self.resultLabel.setFont(self.boxFont) @@ -2376,10 +2374,10 @@ class GuiDocEditSearch(QFrame): self.mainBox.setColumnStretch(3, 0) self.mainBox.setColumnStretch(4, 0) self.mainBox.setColumnStretch(5, 0) - self.mainBox.setSpacing(self.mainConf.pxInt(2)) + self.mainBox.setSpacing(CONFIG.pxInt(2)) self.mainBox.setContentsMargins(mPx, mPx, mPx, mPx) - boxWidth = self.mainConf.pxInt(200) + boxWidth = CONFIG.pxInt(200) self.searchBox.setFixedWidth(boxWidth) self.replaceBox.setFixedWidth(boxWidth) self.replaceBox.setVisible(False) @@ -2438,12 +2436,12 @@ 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.searchNextFile = self.doNextFile - self.mainConf.searchMatchCap = self.doMatchCap + CONFIG.searchCase = self.isCaseSense + CONFIG.searchWord = self.isWholeWord + CONFIG.searchRegEx = self.isRegEx + CONFIG.searchLoop = self.doLoop + CONFIG.searchNextFile = self.doNextFile + CONFIG.searchMatchCap = self.doMatchCap self.showReplace.setChecked(False) self.setVisible(False) @@ -2517,7 +2515,7 @@ class GuiDocEditSearch(QFrame): # Using the Unicode-capable QRegularExpression class was # only added in Qt 5.13. Otherwise, 5.3 and up supports # only the QRegExp class. - if self.mainConf.verQtValue >= 0x050d00: + if CONFIG.verQtValue >= 0x050d00: rxOpt = QRegularExpression.UseUnicodePropertiesOption if not self.isCaseSense: rxOpt |= QRegularExpression.CaseInsensitiveOption @@ -2661,7 +2659,6 @@ class GuiDocEditHeader(QWidget): logger.debug("Initialising GuiDocEditHeader ...") - self.mainConf = novelwriter.CONFIG self.docEditor = docEditor self.mainGui = docEditor.mainGui self.theProject = docEditor.theProject @@ -2670,7 +2667,7 @@ class GuiDocEditHeader(QWidget): self._docHandle = None fPx = int(0.9*self.mainTheme.fontPixelSize) - hSp = self.mainConf.pxInt(6) + hSp = CONFIG.pxInt(6) # Main Widget Settings self.setAutoFillBackground(True) @@ -2738,7 +2735,7 @@ class GuiDocEditHeader(QWidget): # Fix Margins and Size # This is needed for high DPI systems. See issue #499. - cM = self.mainConf.pxInt(8) + cM = CONFIG.pxInt(8) self.setContentsMargins(0, 0, 0, 0) self.outerBox.setContentsMargins(cM, cM, cM, cM) self.setMinimumHeight(fPx + 2*cM) @@ -2802,7 +2799,7 @@ class GuiDocEditHeader(QWidget): self.minmaxButton.setVisible(False) return True - if self.mainConf.showFullPath: + if CONFIG.showFullPath: tTitle = [] tTree = self.theProject.tree.getItemPath(tHandle) for aHandle in reversed(tTree): @@ -2897,7 +2894,6 @@ class GuiDocEditFooter(QWidget): logger.debug("Initialising GuiDocEditFooter ...") - self.mainConf = novelwriter.CONFIG self.docEditor = docEditor self.mainGui = docEditor.mainGui self.theProject = docEditor.theProject @@ -2910,8 +2906,8 @@ class GuiDocEditFooter(QWidget): self.sPx = int(round(0.9*self.mainTheme.baseIconSize)) fPx = int(0.9*self.mainTheme.fontPixelSize) - bSp = self.mainConf.pxInt(4) - hSp = self.mainConf.pxInt(6) + bSp = CONFIG.pxInt(4) + hSp = CONFIG.pxInt(6) lblFont = self.font() lblFont.setPointSizeF(0.9*self.mainTheme.fontPointSize) @@ -2980,7 +2976,7 @@ class GuiDocEditFooter(QWidget): # Fix Margins and Size # This is needed for high DPI systems. See issue #499. - cM = self.mainConf.pxInt(8) + cM = CONFIG.pxInt(8) self.setContentsMargins(0, 0, 0, 0) self.outerBox.setContentsMargins(cM, cM, cM, cM) self.setMinimumHeight(fPx + 2*cM) diff --git a/novelwriter/gui/dochighlight.py b/novelwriter/gui/dochighlight.py index 3b527a64..a4d86c98 100644 --- a/novelwriter/gui/dochighlight.py +++ b/novelwriter/gui/dochighlight.py @@ -24,7 +24,6 @@ along with this program. If not, see . """ import logging -import novelwriter from time import time @@ -33,6 +32,7 @@ from PyQt5.QtGui import ( QColor, QTextCharFormat, QFont, QSyntaxHighlighter, QBrush ) +from novelwriter import CONFIG from novelwriter.common import checkInt from novelwriter.constants import nwRegEx, nwUnicode @@ -50,7 +50,6 @@ class GuiDocHighlighter(QSyntaxHighlighter): super().__init__(theDoc) logger.debug("Initialising GuiDocHighlighter ...") - self.mainConf = novelwriter.CONFIG self.theDoc = theDoc self.spEnchant = spEnchant self.mainGui = mainGui @@ -103,7 +102,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): self.colBreak.setAlpha(64) self.colEmph = None - if self.mainConf.highlightEmph: + if CONFIG.highlightEmph: self.colEmph = QColor(*self.mainTheme.colEmph) self.hStyles = { @@ -135,7 +134,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): self.hRules = [] # Multiple or Trailing Spaces - if self.mainConf.showMultiSpaces: + if CONFIG.showMultiSpaces: self.hRules.append(( r"[ ]{2,}|[ ]*$", { 0: self.hStyles["mspaces"], @@ -150,11 +149,11 @@ class GuiDocHighlighter(QSyntaxHighlighter): )) # Quoted Strings - if self.mainConf.highlightQuotes: - fmtDblO = self.mainConf.fmtDQuoteOpen - fmtDblC = self.mainConf.fmtDQuoteClose - fmtSngO = self.mainConf.fmtSQuoteOpen - fmtSngC = self.mainConf.fmtSQuoteClose + if CONFIG.highlightQuotes: + fmtDblO = CONFIG.fmtDQuoteOpen + fmtDblC = CONFIG.fmtDQuoteClose + fmtSngO = CONFIG.fmtSQuoteOpen + fmtSngC = CONFIG.fmtSQuoteClose # Straight Quotes if not (fmtDblO == fmtDblC == "\""): @@ -165,7 +164,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): )) # Double Quotes - dblEnd = "|$" if self.mainConf.allowOpenDQuote else "" + dblEnd = "|$" if CONFIG.allowOpenDQuote else "" self.hRules.append(( f"(\\B{fmtDblO})(.*?)({fmtDblC}\\B{dblEnd})", { 0: self.hStyles["dialogue2"], @@ -173,7 +172,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): )) # Single Quotes - sngEnd = "|$" if self.mainConf.allowOpenSQuote else "" + sngEnd = "|$" if CONFIG.allowOpenSQuote else "" self.hRules.append(( f"(\\B{fmtSngO})(.*?)({fmtSngC}\\B{sngEnd})", { 0: self.hStyles["dialogue3"], @@ -432,7 +431,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): theFormat.setBackground(QBrush(fmtCol, Qt.SolidPattern)) if fmtSize is not None: - theFormat.setFontPointSize(int(round(fmtSize*self.mainConf.textSize))) + theFormat.setFontPointSize(int(round(fmtSize*CONFIG.textSize))) return theFormat diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index 517b88f4..7cb8be4d 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -28,7 +28,6 @@ along with this program. If not, see . """ import logging -import novelwriter from enum import Enum @@ -41,6 +40,7 @@ from PyQt5.QtWidgets import ( QAction, QMenu, QFrame ) +from novelwriter import CONFIG from novelwriter.enum import nwItemType, nwDocAction, nwDocMode from novelwriter.error import logException from novelwriter.constants import nwUnicode @@ -59,7 +59,6 @@ class GuiDocViewer(QTextBrowser): logger.debug("Initialising GuiDocViewer ...") # Class Variables - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.theProject = mainGui.theProject @@ -68,7 +67,7 @@ class GuiDocViewer(QTextBrowser): self._docHandle = None # Settings - self.setMinimumWidth(self.mainConf.pxInt(300)) + self.setMinimumWidth(CONFIG.pxInt(300)) self.setAutoFillBackground(True) self.setOpenExternalLinks(False) self.setFocusPolicy(Qt.StrongFocus) @@ -116,11 +115,11 @@ class GuiDocViewer(QTextBrowser): # Set Font theFont = QFont() - if self.mainConf.textFont is None: + if CONFIG.textFont is None: # If none is defined, set the default back to config - self.mainConf.textFont = self.document().defaultFont().family() - theFont.setFamily(self.mainConf.textFont) - theFont.setPointSize(self.mainConf.textSize) + CONFIG.textFont = self.document().defaultFont().family() + theFont.setFamily(CONFIG.textFont) + theFont.setPointSize(CONFIG.textSize) self.setFont(theFont) # Set the widget colours to match syntax theme @@ -141,23 +140,23 @@ class GuiDocViewer(QTextBrowser): # Set default text margins self.document().setDocumentMargin(0) theOpt = QTextOption() - if self.mainConf.doJustify: + if CONFIG.doJustify: theOpt.setAlignment(Qt.AlignJustify) self.document().setDefaultTextOption(theOpt) # Scroll bars - if self.mainConf.hideVScroll: + if CONFIG.hideVScroll: self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) - if self.mainConf.hideHScroll: + if CONFIG.hideHScroll: self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) # Refresh the tab stops - self.setTabStopDistance(self.mainConf.getTabWidth()) + self.setTabStopDistance(CONFIG.getTabWidth()) # If we have a document open, we should reload it in case the font changed if self._docHandle is not None: @@ -177,7 +176,7 @@ class GuiDocViewer(QTextBrowser): sPos = self.verticalScrollBar().value() aDoc = ToHtml(self.theProject) - aDoc.setPreview(self.mainConf.viewComments, self.mainConf.viewSynopsis) + aDoc.setPreview(CONFIG.viewComments, CONFIG.viewSynopsis) aDoc.setLinkHeaders(True) # Be extra careful here to prevent crashes when first opening a @@ -196,7 +195,7 @@ class GuiDocViewer(QTextBrowser): return False # Refresh the tab stops - self.setTabStopDistance(self.mainConf.getTabWidth()) + self.setTabStopDistance(CONFIG.getTabWidth()) # Must be before setHtml if updateHistory: @@ -297,7 +296,7 @@ class GuiDocViewer(QTextBrowser): """ wW = self.width() wH = self.height() - cM = self.mainConf.getTextMargin() + cM = CONFIG.getTextMargin() vBar = self.verticalScrollBar() sW = vBar.width() if vBar.isVisible() else 0 @@ -306,8 +305,8 @@ class GuiDocViewer(QTextBrowser): sH = hBar.height() if hBar.isVisible() else 0 tM = cM - if self.mainConf.textWidth > 0: - tW = self.mainConf.getTextWidth() + if CONFIG.textWidth > 0: + tW = CONFIG.getTextWidth() tM = max((wW - sW - tW)//2, cM) tB = self.frameWidth() @@ -685,7 +684,6 @@ class GuiDocViewHeader(QWidget): logger.debug("Initialising GuiDocViewHeader ...") - self.mainConf = novelwriter.CONFIG self.docViewer = docViewer self.mainGui = docViewer.mainGui self.theProject = docViewer.theProject @@ -695,7 +693,7 @@ class GuiDocViewHeader(QWidget): self._docHandle = None fPx = int(0.9*self.mainTheme.fontPixelSize) - hSp = self.mainConf.pxInt(6) + hSp = CONFIG.pxInt(6) # Main Widget Settings self.setAutoFillBackground(True) @@ -763,7 +761,7 @@ class GuiDocViewHeader(QWidget): # Fix Margins and Size # This is needed for high DPI systems. See issue #499. - cM = self.mainConf.pxInt(8) + cM = CONFIG.pxInt(8) self.setContentsMargins(0, 0, 0, 0) self.outerBox.setContentsMargins(cM, cM, cM, cM) self.setMinimumHeight(fPx + 2*cM) @@ -828,7 +826,7 @@ class GuiDocViewHeader(QWidget): self.refreshButton.setVisible(False) return True - if self.mainConf.showFullPath: + if CONFIG.showFullPath: tTitle = [] tTree = self.theProject.tree.getItemPath(tHandle) for aHandle in reversed(tTree): @@ -903,7 +901,6 @@ class GuiDocViewFooter(QWidget): logger.debug("Initialising GuiDocViewFooter ...") - self.mainConf = novelwriter.CONFIG self.docViewer = docViewer self.mainGui = docViewer.mainGui self.mainTheme = docViewer.mainTheme @@ -913,8 +910,8 @@ class GuiDocViewFooter(QWidget): self._docHandle = None fPx = int(0.9*self.mainTheme.fontPixelSize) - bSp = self.mainConf.pxInt(2) - hSp = self.mainConf.pxInt(8) + bSp = CONFIG.pxInt(2) + hSp = CONFIG.pxInt(8) # Main Widget Settings self.setContentsMargins(0, 0, 0, 0) @@ -942,7 +939,7 @@ class GuiDocViewFooter(QWidget): # Show Comments self.showComments = QToolButton(self) self.showComments.setCheckable(True) - self.showComments.setChecked(self.mainConf.viewComments) + self.showComments.setChecked(CONFIG.viewComments) self.showComments.setToolButtonStyle(Qt.ToolButtonIconOnly) self.showComments.setIconSize(QSize(fPx, fPx)) self.showComments.setFixedSize(QSize(fPx, fPx)) @@ -952,7 +949,7 @@ class GuiDocViewFooter(QWidget): # Show Synopsis self.showSynopsis = QToolButton(self) self.showSynopsis.setCheckable(True) - self.showSynopsis.setChecked(self.mainConf.viewSynopsis) + self.showSynopsis.setChecked(CONFIG.viewSynopsis) self.showSynopsis.setToolButtonStyle(Qt.ToolButtonIconOnly) self.showSynopsis.setIconSize(QSize(fPx, fPx)) self.showSynopsis.setFixedSize(QSize(fPx, fPx)) @@ -1021,7 +1018,7 @@ class GuiDocViewFooter(QWidget): # Fix Margins and Size # This is needed for high DPI systems. See issue #499. - cM = self.mainConf.pxInt(8) + cM = CONFIG.pxInt(8) self.setContentsMargins(0, 0, 0, 0) self.outerBox.setContentsMargins(cM, cM, cM, cM) self.setMinimumHeight(fPx + 2*cM) @@ -1120,7 +1117,7 @@ class GuiDocViewFooter(QWidget): def _doToggleComments(self, theState): """Toggle the view comment button and reload the document. """ - self.mainConf.viewComments = theState + CONFIG.viewComments = theState self.docViewer.reloadText() return @@ -1128,7 +1125,7 @@ class GuiDocViewFooter(QWidget): def _doToggleSynopsis(self, theState): """Toggle the view synopsis button and reload the document. """ - self.mainConf.viewSynopsis = theState + CONFIG.viewSynopsis = theState self.docViewer.reloadText() return @@ -1146,7 +1143,6 @@ class GuiDocViewDetails(QScrollArea): super().__init__(parent=mainGui) logger.debug("Initialising GuiDocViewDetails ...") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.theProject = mainGui.theProject self.mainTheme = mainGui.mainTheme @@ -1172,7 +1168,7 @@ class GuiDocViewDetails(QScrollArea): self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setWidgetResizable(True) - self.setMinimumHeight(self.mainConf.pxInt(50)) + self.setMinimumHeight(CONFIG.pxInt(50)) self.setFrameStyle(QFrame.NoFrame) logger.debug("GuiDocViewDetails initialisation complete") diff --git a/novelwriter/gui/itemdetails.py b/novelwriter/gui/itemdetails.py index f36a78d3..e89ed7e2 100644 --- a/novelwriter/gui/itemdetails.py +++ b/novelwriter/gui/itemdetails.py @@ -24,12 +24,12 @@ along with this program. If not, see . """ import logging -import novelwriter from PyQt5.QtCore import Qt, pyqtSlot from PyQt5.QtGui import QFont, QPixmap from PyQt5.QtWidgets import QWidget, QGridLayout, QLabel +from novelwriter import CONFIG from novelwriter.constants import trConst, nwLabels logger = logging.getLogger(__name__) @@ -41,7 +41,6 @@ class GuiItemDetails(QWidget): super().__init__(parent=mainGui) logger.debug("Initialising GuiItemDetails ...") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.theProject = mainGui.theProject self.mainTheme = mainGui.mainTheme @@ -50,9 +49,9 @@ class GuiItemDetails(QWidget): self._itemHandle = None # Sizes - hSp = self.mainConf.pxInt(6) - vSp = self.mainConf.pxInt(1) - mPx = self.mainConf.pxInt(6) + hSp = CONFIG.pxInt(6) + vSp = CONFIG.pxInt(1) + mPx = CONFIG.pxInt(6) fPt = self.mainTheme.fontPointSize fntLabel = QFont() diff --git a/novelwriter/gui/mainmenu.py b/novelwriter/gui/mainmenu.py index c06e6bce..93dbc184 100644 --- a/novelwriter/gui/mainmenu.py +++ b/novelwriter/gui/mainmenu.py @@ -24,7 +24,6 @@ along with this program. If not, see . """ import logging -import novelwriter from pathlib import Path from urllib.parse import urljoin @@ -34,8 +33,9 @@ from PyQt5.QtCore import QUrl from PyQt5.QtGui import QDesktopServices from PyQt5.QtWidgets import QMenuBar, QAction +from novelwriter import CONFIG from novelwriter.enum import nwDocAction, nwDocInsert, nwWidget -from novelwriter.constants import trConst, nwKeyWords, nwLabels, nwUnicode +from novelwriter.constants import nwConst, trConst, nwKeyWords, nwLabels, nwUnicode logger = logging.getLogger(__name__) @@ -50,7 +50,6 @@ class GuiMainMenu(QMenuBar): super().__init__(parent=mainGui) logger.debug("Initialising GuiMainMenu ...") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.theProject = mainGui.theProject @@ -105,9 +104,9 @@ class GuiMainMenu(QMenuBar): def _openUserManualFile(self): """Open the documentation in PDF format. """ - if isinstance(self.mainConf.pdfDocs, Path): + if isinstance(CONFIG.pdfDocs, Path): QDesktopServices.openUrl( - QUrl(urljoin("file:", pathname2url(str(self.mainConf.pdfDocs)))) + QUrl(urljoin("file:", pathname2url(str(CONFIG.pdfDocs)))) ) return @@ -310,7 +309,7 @@ class GuiMainMenu(QMenuBar): # View > TreeView self.aFocusTree = QAction(self.tr("Go to Project Tree"), self) - if self.mainConf.osWindows: + if CONFIG.osWindows: self.aFocusTree.setShortcut("Ctrl+Alt+1") else: self.aFocusTree.setShortcut("Alt+1") @@ -319,7 +318,7 @@ class GuiMainMenu(QMenuBar): # View > Document Pane 1 self.aFocusEditor = QAction(self.tr("Go to Document Editor"), self) - if self.mainConf.osWindows: + if CONFIG.osWindows: self.aFocusEditor.setShortcut("Ctrl+Alt+2") else: self.aFocusEditor.setShortcut("Alt+2") @@ -328,7 +327,7 @@ class GuiMainMenu(QMenuBar): # View > Document Pane 2 self.aFocusView = QAction(self.tr("Go to Document Viewer"), self) - if self.mainConf.osWindows: + if CONFIG.osWindows: self.aFocusView.setShortcut("Ctrl+Alt+3") else: self.aFocusView.setShortcut("Alt+3") @@ -337,7 +336,7 @@ class GuiMainMenu(QMenuBar): # View > Outline self.aFocusOutline = QAction(self.tr("Go to Outline"), self) - if self.mainConf.osWindows: + if CONFIG.osWindows: self.aFocusOutline.setShortcut("Ctrl+Alt+4") else: self.aFocusOutline.setShortcut("Alt+4") @@ -754,7 +753,7 @@ class GuiMainMenu(QMenuBar): # Search > Replace self.aReplace = QAction(self.tr("Replace"), self) - if self.mainConf.osDarwin: + if CONFIG.osDarwin: self.aReplace.setShortcut("Ctrl+=") else: self.aReplace.setShortcut("Ctrl+H") @@ -763,7 +762,7 @@ class GuiMainMenu(QMenuBar): # Search > Find Next self.aFindNext = QAction(self.tr("Find Next"), self) - if self.mainConf.osDarwin: + if CONFIG.osDarwin: self.aFindNext.setShortcuts(["Ctrl+G", "F3"]) else: self.aFindNext.setShortcuts(["F3", "Ctrl+G"]) @@ -772,7 +771,7 @@ class GuiMainMenu(QMenuBar): # Search > Find Prev self.aFindPrev = QAction(self.tr("Find Previous"), self) - if self.mainConf.osDarwin: + if CONFIG.osDarwin: self.aFindPrev.setShortcuts(["Ctrl+Shift+G", "Shift+F3"]) else: self.aFindPrev.setShortcuts(["Shift+F3", "Ctrl+Shift+G"]) @@ -877,18 +876,13 @@ class GuiMainMenu(QMenuBar): self.helpMenu.addSeparator() # Help > User Manual (Online) - if novelwriter.__version__[-2] == "f": - docUrl = f"{novelwriter.__docurl__}/en/stable/" - else: - docUrl = f"{novelwriter.__docurl__}/en/latest/" - self.aHelpDocs = QAction(self.tr("User Manual (Online)"), self) self.aHelpDocs.setShortcut("F1") - self.aHelpDocs.triggered.connect(lambda: self._openWebsite(docUrl)) + self.aHelpDocs.triggered.connect(lambda: self._openWebsite(nwConst.URL_DOCS)) self.helpMenu.addAction(self.aHelpDocs) # Help > User Manual (PDF) - if isinstance(self.mainConf.pdfDocs, Path): + if isinstance(CONFIG.pdfDocs, Path): self.aPdfDocs = QAction(self.tr("User Manual (PDF)"), self) self.aPdfDocs.setShortcut("Shift+F1") self.aPdfDocs.triggered.connect(self._openUserManualFile) @@ -899,17 +893,17 @@ class GuiMainMenu(QMenuBar): # Document > Report an Issue self.aIssue = QAction(self.tr("Report an Issue (GitHub)"), self) - self.aIssue.triggered.connect(lambda: self._openWebsite(novelwriter.__issuesurl__)) + self.aIssue.triggered.connect(lambda: self._openWebsite(nwConst.URL_REPORT)) self.helpMenu.addAction(self.aIssue) # Document > Ask a Question self.aQuestion = QAction(self.tr("Ask a Question (GitHub)"), self) - self.aQuestion.triggered.connect(lambda: self._openWebsite(novelwriter.__helpurl__)) + self.aQuestion.triggered.connect(lambda: self._openWebsite(nwConst.URL_HELP)) self.helpMenu.addAction(self.aQuestion) # Document > Main Website self.aWebsite = QAction(self.tr("The novelWriter Website"), self) - self.aWebsite.triggered.connect(lambda: self._openWebsite(novelwriter.__url__)) + self.aWebsite.triggered.connect(lambda: self._openWebsite(nwConst.URL_WEB)) self.helpMenu.addAction(self.aWebsite) # Help > Separator diff --git a/novelwriter/gui/noveltree.py b/novelwriter/gui/noveltree.py index 920dccf2..d8fe310d 100644 --- a/novelwriter/gui/noveltree.py +++ b/novelwriter/gui/noveltree.py @@ -26,7 +26,6 @@ along with this program. If not, see . """ import logging -import novelwriter from enum import Enum from time import time @@ -39,6 +38,7 @@ from PyQt5.QtWidgets import ( QTreeWidgetItem, QVBoxLayout, QWidget ) +from novelwriter import CONFIG from novelwriter.enum import nwDocMode, nwItemClass, nwOutline from novelwriter.common import minmax from novelwriter.constants import nwHeaders, nwKeyWords, nwLabels, trConst @@ -198,14 +198,13 @@ class GuiNovelToolBar(QWidget): logger.debug("Initialising GuiNovelToolBar ...") - self.mainConf = novelwriter.CONFIG self.novelView = novelView self.mainGui = novelView.mainGui self.theProject = novelView.mainGui.theProject self.mainTheme = novelView.mainGui.mainTheme iPx = self.mainTheme.baseIconSize - mPx = self.mainConf.pxInt(2) + mPx = CONFIG.pxInt(2) self.setContentsMargins(0, 0, 0, 0) self.setAutoFillBackground(True) @@ -216,7 +215,7 @@ class GuiNovelToolBar(QWidget): self.novelPrefix = self.tr("Outline of {0}") self.novelValue = NovelSelector(self, self.theProject, self.mainGui) self.novelValue.setFont(selFont) - self.novelValue.setMinimumWidth(self.mainConf.pxInt(150)) + self.novelValue.setMinimumWidth(CONFIG.pxInt(150)) self.novelValue.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.novelValue.novelSelectionChanged.connect(self.setCurrentRoot) @@ -290,7 +289,7 @@ class GuiNovelToolBar(QWidget): buttonStyle = ( "QToolButton {{padding: {0}px; border: none; background: transparent;}} " "QToolButton:hover {{border: none; background: rgba({1},{2},{3},0.2);}}" - ).format(self.mainConf.pxInt(2), fadeCol.red(), fadeCol.green(), fadeCol.blue()) + ).format(CONFIG.pxInt(2), fadeCol.red(), fadeCol.green(), fadeCol.blue()) self.tbNovel.setStyleSheet(buttonStyle) self.tbRefresh.setStyleSheet(buttonStyle) @@ -398,7 +397,6 @@ class GuiNovelTree(QTreeWidget): logger.debug("Initialising GuiNovelTree ...") - self.mainConf = novelwriter.CONFIG self.novelView = novelView self.mainGui = novelView.mainGui self.mainTheme = novelView.mainGui.mainTheme @@ -420,7 +418,7 @@ class GuiNovelTree(QTreeWidget): # ========= iPx = self.mainTheme.baseIconSize - cMg = self.mainConf.pxInt(6) + cMg = CONFIG.pxInt(6) self.setIconSize(QSize(iPx, iPx)) self.setFrameStyle(QFrame.NoFrame) @@ -470,12 +468,12 @@ class GuiNovelTree(QTreeWidget): """Set or update tree widget settings. """ # Scroll bars - if self.mainConf.hideVScroll: + if CONFIG.hideVScroll: self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) - if self.mainConf.hideHScroll: + if CONFIG.hideHScroll: self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) diff --git a/novelwriter/gui/outline.py b/novelwriter/gui/outline.py index 1d90ab89..fd288a11 100644 --- a/novelwriter/gui/outline.py +++ b/novelwriter/gui/outline.py @@ -28,7 +28,6 @@ along with this program. If not, see . """ import logging -import novelwriter from time import time from enum import Enum @@ -42,6 +41,7 @@ from PyQt5.QtWidgets import ( QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget ) +from novelwriter import CONFIG from novelwriter.enum import ( nwDocMode, nwItemClass, nwItemLayout, nwItemType, nwOutline ) @@ -61,7 +61,6 @@ class GuiOutlineView(QWidget): def __init__(self, mainGui): super().__init__(parent=mainGui) - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.theProject = mainGui.theProject @@ -75,7 +74,7 @@ class GuiOutlineView(QWidget): self.splitOutline.addWidget(self.outlineTree) self.splitOutline.addWidget(self.outlineData) self.splitOutline.setOpaqueResize(False) - self.splitOutline.setSizes(self.mainConf.outlinePanePos) + self.splitOutline.setSizes(CONFIG.outlinePanePos) # Assemble self.outerBox = QVBoxLayout() @@ -215,13 +214,12 @@ class GuiOutlineToolBar(QToolBar): logger.debug("Initialising GuiOutlineToolBar ...") - self.mainConf = novelwriter.CONFIG self.mainGui = theOutline.mainGui self.theProject = theOutline.mainGui.theProject self.mainTheme = theOutline.mainGui.mainTheme - iPx = self.mainConf.pxInt(22) - mPx = self.mainConf.pxInt(12) + iPx = CONFIG.pxInt(22) + mPx = CONFIG.pxInt(12) self.setMovable(False) self.setIconSize(QSize(iPx, iPx)) @@ -235,7 +233,7 @@ class GuiOutlineToolBar(QToolBar): self.novelLabel.setContentsMargins(0, 0, mPx, 0) self.novelValue = NovelSelector(self, self.theProject, self.mainGui) - self.novelValue.setMinimumWidth(self.mainConf.pxInt(200)) + self.novelValue.setMinimumWidth(CONFIG.pxInt(200)) self.novelValue.novelSelectionChanged.connect(self._novelValueChanged) # Actions @@ -373,7 +371,6 @@ class GuiOutlineTree(QTreeWidget): logger.debug("Initialising GuiOutlineTree ...") - self.mainConf = novelwriter.CONFIG self.outlineView = outlineView self.mainGui = outlineView.mainGui self.theProject = outlineView.mainGui.theProject @@ -446,12 +443,12 @@ class GuiOutlineTree(QTreeWidget): """Set or update outline settings. """ # Scroll bars - if self.mainConf.hideVScroll: + if CONFIG.hideVScroll: self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) - if self.mainConf.hideHScroll: + if CONFIG.hideHScroll: self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) @@ -610,7 +607,7 @@ class GuiOutlineTree(QTreeWidget): tmpWidth = pOptions.getValue("GuiOutline", "columnWidth", {}) for hName in tmpWidth: try: - self._colWidth[nwOutline[hName]] = self.mainConf.pxInt(tmpWidth[hName]) + self._colWidth[nwOutline[hName]] = CONFIG.pxInt(tmpWidth[hName]) except Exception: logger.warning("Ignored unknown outline column '%s'", str(hName)) @@ -640,7 +637,7 @@ class GuiOutlineTree(QTreeWidget): colHidden = {} for hItem in nwOutline: - colWidth[hItem.name] = self.mainConf.rpxInt(self._colWidth[hItem]) + colWidth[hItem.name] = CONFIG.rpxInt(self._colWidth[hItem]) colHidden[hItem.name] = self._colHidden[hItem] for iCol in range(self.columnCount()): @@ -648,7 +645,7 @@ class GuiOutlineTree(QTreeWidget): treeOrder.append(hName) iLog = self.treeHead.logicalIndex(iCol) - logWidth = self.mainConf.rpxInt(self.columnWidth(iLog)) + logWidth = CONFIG.rpxInt(self.columnWidth(iLog)) logHidden = self.isColumnHidden(iLog) colHidden[hName] = logHidden @@ -801,7 +798,6 @@ class GuiOutlineDetails(QScrollArea): logger.debug("Initialising GuiOutlineDetails ...") - self.mainConf = novelwriter.CONFIG self.theOutline = theOutline self.mainGui = theOutline.mainGui self.theProject = theOutline.mainGui.theProject @@ -811,8 +807,8 @@ class GuiOutlineDetails(QScrollArea): minTitle = 30*self.mainTheme.textNWidth maxTitle = 40*self.mainTheme.textNWidth wCount = self.mainTheme.getTextWidth("999,999") - hSpace = int(self.mainConf.pxInt(10)) - vSpace = int(self.mainConf.pxInt(4)) + hSpace = int(CONFIG.pxInt(10)) + vSpace = int(CONFIG.pxInt(4)) # Details Area self.titleLabel = QLabel("%s" % self.tr("Title")) @@ -994,12 +990,12 @@ class GuiOutlineDetails(QScrollArea): """Set or update outline settings. """ # Scroll bars - if self.mainConf.hideVScroll: + if CONFIG.hideVScroll: self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) - if self.mainConf.hideHScroll: + if CONFIG.hideHScroll: self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) diff --git a/novelwriter/gui/projtree.py b/novelwriter/gui/projtree.py index a21c7a9d..e5bce3a6 100644 --- a/novelwriter/gui/projtree.py +++ b/novelwriter/gui/projtree.py @@ -26,7 +26,6 @@ along with this program. If not, see . """ import logging -import novelwriter from enum import Enum from time import time @@ -38,10 +37,11 @@ from PyQt5.QtWidgets import ( QMenu, QShortcut, QSizePolicy, QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget ) -from novelwriter.core.item import NWItem +from novelwriter import CONFIG from novelwriter.enum import nwDocMode, nwItemType, nwItemClass, nwItemLayout, nwAlert, nwWidget from novelwriter.constants import nwHeaders, nwUnicode, trConst, nwLabels +from novelwriter.core.item import NWItem from novelwriter.core.coretools import DocMerger, DocSplitter from novelwriter.dialogs.docmerge import GuiDocMerge from novelwriter.dialogs.docsplit import GuiDocSplit @@ -217,7 +217,6 @@ class GuiProjectToolBar(QWidget): logger.debug("Initialising GuiProjectToolBar ...") - self.mainConf = novelwriter.CONFIG self.projView = projView self.projTree = projView.projTree self.mainGui = projView.mainGui @@ -225,7 +224,7 @@ class GuiProjectToolBar(QWidget): self.mainTheme = projView.mainGui.mainTheme iPx = self.mainTheme.baseIconSize - mPx = self.mainConf.pxInt(2) + mPx = CONFIG.pxInt(2) self.setContentsMargins(0, 0, 0, 0) self.setAutoFillBackground(True) @@ -348,7 +347,7 @@ class GuiProjectToolBar(QWidget): buttonStyle = ( "QToolButton {{padding: {0}px; border: none; background: transparent;}} " "QToolButton:hover {{border: none; background: rgba({1},{2},{3},0.2);}}" - ).format(self.mainConf.pxInt(2), fadeCol.red(), fadeCol.green(), fadeCol.blue()) + ).format(CONFIG.pxInt(2), fadeCol.red(), fadeCol.green(), fadeCol.blue()) self.tbQuick.setStyleSheet(buttonStyle) self.tbMoveU.setStyleSheet(buttonStyle) @@ -458,7 +457,6 @@ class GuiProjectTree(QTreeWidget): logger.debug("Initialising GuiProjectTree ...") - self.mainConf = novelwriter.CONFIG self.projView = projView self.mainGui = projView.mainGui self.mainTheme = projView.mainGui.mainTheme @@ -478,7 +476,7 @@ class GuiProjectTree(QTreeWidget): # Tree Settings iPx = self.mainTheme.baseIconSize - cMg = self.mainConf.pxInt(6) + cMg = CONFIG.pxInt(6) self.setIconSize(QSize(iPx, iPx)) self.setFrameStyle(QFrame.NoFrame) @@ -532,12 +530,12 @@ class GuiProjectTree(QTreeWidget): """Set or update tree widget settings. """ # Scroll bars - if self.mainConf.hideVScroll: + if CONFIG.hideVScroll: self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) - if self.mainConf.hideHScroll: + if CONFIG.hideHScroll: self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) @@ -987,7 +985,7 @@ class GuiProjectTree(QTreeWidget): trItem.setIcon(self.C_ACTIVE, self.mainTheme.getIcon(iconName)) - if self.mainConf.emphLabels and nwItem.isDocumentLayout(): + if CONFIG.emphLabels and nwItem.isDocumentLayout(): trFont = trItem.font(self.C_NAME) trFont.setBold(hLevel == "H1" or hLevel == "H2") trFont.setUnderline(hLevel == "H1") diff --git a/novelwriter/gui/sidebar.py b/novelwriter/gui/sidebar.py index 79ea27af..12d26d93 100644 --- a/novelwriter/gui/sidebar.py +++ b/novelwriter/gui/sidebar.py @@ -24,13 +24,13 @@ along with this program. If not, see . """ import logging -import novelwriter from PyQt5.QtCore import Qt, QSize, pyqtSignal from PyQt5.QtWidgets import ( QToolBar, QWidget, QSizePolicy, QAction, QMenu, QToolButton ) +from novelwriter import CONFIG from novelwriter.enum import nwView logger = logging.getLogger(__name__) @@ -45,13 +45,12 @@ class GuiSideBar(QToolBar): logger.debug("Initialising GuiSideBar ...") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme # Style - iPx = self.mainConf.pxInt(22) - mPx = self.mainConf.pxInt(60) + iPx = CONFIG.pxInt(22) + mPx = CONFIG.pxInt(60) lblFont = self.mainTheme.guiFont lblFont.setPointSizeF(0.65*self.mainTheme.fontPointSize) diff --git a/novelwriter/gui/statusbar.py b/novelwriter/gui/statusbar.py index b811f80b..5d90dcd3 100644 --- a/novelwriter/gui/statusbar.py +++ b/novelwriter/gui/statusbar.py @@ -25,7 +25,6 @@ along with this program. If not, see . """ import logging -import novelwriter from time import time @@ -33,6 +32,7 @@ from PyQt5.QtCore import pyqtSlot, QLocale from PyQt5.QtGui import QColor from PyQt5.QtWidgets import qApp, QStatusBar, QLabel +from novelwriter import CONFIG from novelwriter.common import formatTime from novelwriter.gui.components import StatusLED @@ -46,7 +46,6 @@ class GuiMainStatus(QStatusBar): logger.debug("Initialising GuiMainStatus ...") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.refTime = None @@ -61,7 +60,7 @@ class GuiMainStatus(QStatusBar): # Permanent Widgets # ================= - xM = self.mainConf.pxInt(8) + xM = CONFIG.pxInt(8) # The Spell Checker Language self.langIcon = QLabel("") @@ -174,7 +173,7 @@ class GuiMainStatus(QStatusBar): def setUserIdle(self, userIdle): """Change the idle status icon. """ - if not self.mainConf.stopWhenIdle: + if not CONFIG.stopWhenIdle: userIdle = False if self.userIdle != userIdle: @@ -191,7 +190,7 @@ class GuiMainStatus(QStatusBar): """Update the current project statistics. """ self.statsText.setText(self.tr("Words: {0} ({1})").format(f"{pWC:n}", f"{sWC:+n}")) - if self.mainConf.incNotesWCount: + if CONFIG.incNotesWCount: self.statsText.setToolTip(self.tr("Project word count (session change)")) else: self.statsText.setToolTip(self.tr("Novel word count (session change)")) @@ -203,7 +202,7 @@ class GuiMainStatus(QStatusBar): if self.refTime is None: self.timeText.setText("00:00:00") else: - if self.mainConf.stopWhenIdle: + if CONFIG.stopWhenIdle: sessTime = round(time() - self.refTime - idleTime) else: sessTime = round(time() - self.refTime) diff --git a/novelwriter/gui/theme.py b/novelwriter/gui/theme.py index bfb6c3de..0d61423a 100644 --- a/novelwriter/gui/theme.py +++ b/novelwriter/gui/theme.py @@ -25,7 +25,6 @@ along with this program. If not, see . """ import logging -import novelwriter from math import ceil @@ -35,6 +34,7 @@ from PyQt5.QtGui import ( QPalette, QColor, QIcon, QFont, QFontMetrics, QFontDatabase, QPixmap ) +from novelwriter import CONFIG from novelwriter.enum import nwItemLayout, nwItemType from novelwriter.error import logException from novelwriter.common import NWConfigParser, minmax @@ -52,7 +52,6 @@ class GuiTheme: def __init__(self): - self.mainConf = novelwriter.CONFIG self.iconCache = GuiIcons(self) # Loaded Theme Settings @@ -118,10 +117,10 @@ class GuiTheme: self._availThemes = {} self._availSyntax = {} - self._listConf(self._availSyntax, self.mainConf.assetPath("syntax")) - self._listConf(self._availThemes, self.mainConf.assetPath("themes")) - self._listConf(self._availSyntax, self.mainConf.dataPath("syntax")) - self._listConf(self._availThemes, self.mainConf.dataPath("themes")) + self._listConf(self._availSyntax, CONFIG.assetPath("syntax")) + self._listConf(self._availThemes, CONFIG.assetPath("themes")) + self._listConf(self._availSyntax, CONFIG.dataPath("syntax")) + self._listConf(self._availThemes, CONFIG.dataPath("themes")) self.loadTheme() self.loadSyntax() @@ -136,7 +135,7 @@ class GuiTheme: # Extract Other Info self.guiDPI = qApp.primaryScreen().logicalDotsPerInchX() self.guiScale = qApp.primaryScreen().logicalDotsPerInchX()/96.0 - self.mainConf.guiScale = self.guiScale + CONFIG.guiScale = self.guiScale logger.debug("GUI DPI: %.1f", self.guiDPI) logger.debug("GUI Scale: %.2f", self.guiScale) @@ -184,11 +183,11 @@ class GuiTheme: def loadTheme(self): """Load the currently specified GUI theme. """ - guiTheme = self.mainConf.guiTheme + guiTheme = CONFIG.guiTheme if guiTheme not in self._availThemes: logger.error("Could not find GUI theme '%s'", guiTheme) guiTheme = "default" - self.mainConf.guiTheme = guiTheme + CONFIG.guiTheme = guiTheme themeFile = self._availThemes.get(guiTheme, None) if themeFile is None: @@ -270,11 +269,11 @@ class GuiTheme: def loadSyntax(self): """Load the currently specified syntax highlighter theme. """ - guiSyntax = self.mainConf.guiSyntax + guiSyntax = CONFIG.guiSyntax if guiSyntax not in self._availSyntax: logger.error("Could not find syntax theme '%s'", guiSyntax) guiSyntax = "default_light" - self.mainConf.guiSyntax = guiSyntax + CONFIG.guiSyntax = guiSyntax syntaxFile = self._availSyntax.get(guiSyntax, None) if syntaxFile is None: @@ -367,18 +366,18 @@ class GuiTheme: """Update the GUI's font style from settings. """ theFont = QFont() - if self.mainConf.guiFont not in self.guiFontDB.families(): - if self.mainConf.osWindows and "Arial" in self.guiFontDB.families(): + if CONFIG.guiFont not in self.guiFontDB.families(): + if CONFIG.osWindows and "Arial" in self.guiFontDB.families(): # On Windows we default to Arial if possible theFont.setFamily("Arial") theFont.setPointSize(10) else: theFont = self.guiFontDB.systemFont(QFontDatabase.GeneralFont) - self.mainConf.guiFont = theFont.family() - self.mainConf.guiFontSize = theFont.pointSize() + CONFIG.guiFont = theFont.family() + CONFIG.guiFontSize = theFont.pointSize() else: - theFont.setFamily(self.mainConf.guiFont) - theFont.setPointSize(self.mainConf.guiFontSize) + theFont.setFamily(CONFIG.guiFont) + theFont.setPointSize(CONFIG.guiFontSize) qApp.setFont(theFont) @@ -473,7 +472,6 @@ class GuiIcons: def __init__(self, mainTheme): - self.mainConf = novelwriter.CONFIG self.mainTheme = mainTheme # Storage @@ -483,7 +481,7 @@ class GuiIcons: self._confName = "icons.conf" # Icon Theme Path - self._iconPath = self.mainConf.assetPath("icons") + self._iconPath = CONFIG.assetPath("icons") # Icon Theme Meta self.themeName = "" @@ -508,7 +506,7 @@ class GuiIcons: self._themeMap = {} themePath = self._iconPath / iconTheme if not themePath.is_dir(): - themePath = self.mainConf.dataPath("icons") / iconTheme + themePath = CONFIG.dataPath("icons") / iconTheme if not themePath.is_dir(): logger.warning("No icons loaded for '%s'", iconTheme) return False @@ -581,7 +579,7 @@ class GuiIcons: if decoKey in self._themeMap: imgPath = self._themeMap[decoKey] elif decoKey in self.IMAGE_MAP: - imgPath = self.mainConf.assetPath("images") / self.IMAGE_MAP[decoKey] + imgPath = CONFIG.assetPath("images") / self.IMAGE_MAP[decoKey] else: logger.error("Decoration with name '%s' does not exist", decoKey) return QPixmap() diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index 700b7ba7..684b61d6 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -24,7 +24,6 @@ along with this program. If not, see . """ import logging -import novelwriter from enum import Enum from time import time @@ -38,6 +37,7 @@ from PyQt5.QtWidgets import ( QMessageBox, QDialog, QStackedWidget ) +from novelwriter import CONFIG, __hexversion__ from novelwriter.gui.theme import GuiTheme from novelwriter.gui.sidebar import GuiSideBar from novelwriter.gui.outline import GuiOutlineView @@ -79,19 +79,18 @@ class GuiMain(QMainWindow): logger.debug("Initialising GUI ...") self.setObjectName("GuiMain") - self.mainConf = novelwriter.CONFIG self.threadPool = QThreadPool() # System Info # =========== - logger.info("OS: %s", self.mainConf.osType) - logger.info("Kernel: %s", self.mainConf.kernelVer) - logger.info("Host: %s", self.mainConf.hostName) - logger.info("Qt5: %s (0x%06x)", self.mainConf.verQtString, self.mainConf.verQtValue) - logger.info("PyQt5: %s (0x%06x)", self.mainConf.verPyQtString, self.mainConf.verPyQtValue) - logger.info("Python: %s (0x%08x)", self.mainConf.verPyString, self.mainConf.verPyHexVal) - logger.info("GUI Language: %s", self.mainConf.guiLocale) + logger.info("OS: %s", CONFIG.osType) + logger.info("Kernel: %s", CONFIG.kernelVer) + logger.info("Host: %s", CONFIG.hostName) + logger.info("Qt5: %s (0x%06x)", CONFIG.verQtString, CONFIG.verQtValue) + logger.info("PyQt5: %s (0x%06x)", CONFIG.verPyQtString, CONFIG.verPyQtValue) + logger.info("Python: %s (0x%08x)", CONFIG.verPyString, CONFIG.verPyHexVal) + logger.info("GUI Language: %s", CONFIG.guiLocale) # Core Classes # ============ @@ -105,10 +104,10 @@ class GuiMain(QMainWindow): self.idleTime = 0.0 # Prepare Main Window - self.resize(*self.mainConf.mainWinSize) + self.resize(*CONFIG.mainWinSize) self._updateWindowTitle() - nwIcon = self.mainConf.assetPath("icons") / "novelwriter.svg" + nwIcon = CONFIG.assetPath("icons") / "novelwriter.svg" self.nwIcon = QIcon(str(nwIcon)) if nwIcon.is_file() else QIcon() self.setWindowIcon(self.nwIcon) qApp.setWindowIcon(self.nwIcon) @@ -117,8 +116,8 @@ class GuiMain(QMainWindow): # ============= # Sizes - mPx = self.mainConf.pxInt(4) - hWd = self.mainConf.pxInt(4) + mPx = CONFIG.pxInt(4) + hWd = CONFIG.pxInt(4) # Main GUI Elements self.mainStatus = GuiMainStatus(self) @@ -153,7 +152,7 @@ class GuiMain(QMainWindow): self.splitView.addWidget(self.viewMeta) self.splitView.setHandleWidth(hWd) self.splitView.setOpaqueResize(False) - self.splitView.setSizes(self.mainConf.viewPanePos) + self.splitView.setSizes(CONFIG.viewPanePos) # Splitter : Document Editor / Document Viewer self.splitDocs = QSplitter(Qt.Horizontal) @@ -169,7 +168,7 @@ class GuiMain(QMainWindow): self.splitMain.addWidget(self.splitDocs) self.splitMain.setOpaqueResize(False) self.splitMain.setHandleWidth(hWd) - self.splitMain.setSizes(self.mainConf.mainPanePos) + self.splitMain.setSizes(CONFIG.mainPanePos) # Main Stack : Editor / Outline self.mainStack = QStackedWidget() @@ -299,12 +298,12 @@ class GuiMain(QMainWindow): # Handle Windows Mode self.showNormal() - if self.mainConf.isFullScreen: + if CONFIG.isFullScreen: self.toggleFullScreenMode() logger.debug("GUI initialisation complete") - if novelwriter.__hexversion__[-2] == "a" and logger.getEffectiveLevel() > logging.DEBUG: + if __hexversion__[-2] == "a" and logger.getEffectiveLevel() > logging.DEBUG: self.makeAlert(self.tr( "You are running an untested development version of novelWriter. " "Please be careful when working on a live project " @@ -339,8 +338,8 @@ class GuiMain(QMainWindow): def initMain(self): """Initialise elements that depend on user settings. """ - self.asProjTimer.setInterval(int(self.mainConf.autoSaveProj*1000)) - self.asDocTimer.setInterval(int(self.mainConf.autoSaveDoc*1000)) + self.asProjTimer.setInterval(int(CONFIG.autoSaveProj*1000)) + self.asDocTimer.setInterval(int(CONFIG.autoSaveDoc*1000)) return True def postLaunchTasks(self, cmdOpen): @@ -355,8 +354,8 @@ class GuiMain(QMainWindow): self.showProjectLoadDialog() # Determine whether release notes need to be shown or not - if hexToInt(self.mainConf.lastNotes) < hexToInt(novelwriter.__hexversion__): - self.mainConf.lastNotes = novelwriter.__hexversion__ + if hexToInt(CONFIG.lastNotes) < hexToInt(__hexversion__): + CONFIG.lastNotes = __hexversion__ self.showAboutNWDialog(showNotes=True) return @@ -427,9 +426,9 @@ class GuiMain(QMainWindow): saveOK = self.saveProject() doBackup = False - if self.theProject.data.doBackup and self.mainConf.backupOnClose: + if self.theProject.data.doBackup and CONFIG.backupOnClose: doBackup = True - if self.mainConf.askBeforeBackup: + if CONFIG.askBeforeBackup: msgYes = self.askQuestion( self.tr("Backup Project"), self.tr("Backup the current project?") @@ -713,7 +712,7 @@ class GuiMain(QMainWindow): vPos[0] = int(bPos[1]/2) vPos[1] = bPos[1] - vPos[0] self.splitDocs.setSizes(vPos) - self.viewMeta.setVisible(self.mainConf.showRefPanel) + self.viewMeta.setVisible(CONFIG.showRefPanel) if sTitle: self.docViewer.navigateTo(f"#{sTitle}") @@ -728,7 +727,7 @@ class GuiMain(QMainWindow): logger.error("No project open") return False - lastPath = self.mainConf.lastPath() + lastPath = CONFIG.lastPath() extFilter = [ self.tr("Text files ({0})").format("*.txt"), self.tr("Markdown files ({0})").format("*.md"), @@ -748,7 +747,7 @@ class GuiMain(QMainWindow): try: with open(loadFile, mode="rt", encoding="utf-8") as inFile: theText = inFile.read() - self.mainConf.setLastPath(loadFile) + CONFIG.setLastPath(loadFile) except Exception as exc: self.makeAlert(self.tr( "Could not read file. The file must be an existing text file." @@ -1185,8 +1184,8 @@ class GuiMain(QMainWindow): the user know if this is the case. The Config module caches errors since it is initialised before the GUI itself. """ - if self.mainConf.hasError: - self.makeAlert(self.mainConf.errorText(), nwAlert.ERROR) + if CONFIG.hasError: + self.makeAlert(CONFIG.errorText(), nwAlert.ERROR) return True return False @@ -1211,19 +1210,19 @@ class GuiMain(QMainWindow): logger.info("Exiting novelWriter") if not self.isFocusMode: - self.mainConf.setMainPanePos(self.splitMain.sizes()) - self.mainConf.setOutlinePanePos(self.outlineView.splitSizes()) + CONFIG.setMainPanePos(self.splitMain.sizes()) + CONFIG.setOutlinePanePos(self.outlineView.splitSizes()) if self.viewMeta.isVisible(): - self.mainConf.setViewPanePos(self.splitView.sizes()) + CONFIG.setViewPanePos(self.splitView.sizes()) - self.mainConf.showRefPanel = self.viewMeta.isVisible() - if not self.mainConf.isFullScreen: - self.mainConf.setMainWinSize(self.width(), self.height()) + CONFIG.showRefPanel = self.viewMeta.isVisible() + if not CONFIG.isFullScreen: + CONFIG.setMainWinSize(self.width(), self.height()) if self.hasProject: self.closeProject(True) - self.mainConf.saveConfig() + CONFIG.saveConfig() self.reportConfErr() qApp.quit() @@ -1292,7 +1291,7 @@ class GuiMain(QMainWindow): self.mainMenu.setVisible(isVisible) self.viewsBar.setVisible(isVisible) - hideDocFooter = self.isFocusMode and self.mainConf.hideFocusFooter + hideDocFooter = self.isFocusMode and CONFIG.hideFocusFooter self.docEditor.docFooter.setVisible(not hideDocFooter) self.docEditor.docHeader.updateFocusMode() @@ -1318,7 +1317,7 @@ class GuiMain(QMainWindow): else: logger.debug("Deactivated full screen mode") - self.mainConf.isFullScreen = winState + CONFIG.isFullScreen = winState return @@ -1413,7 +1412,7 @@ class GuiMain(QMainWindow): # Help self.addAction(self.mainMenu.aHelpDocs) - if isinstance(self.mainConf.pdfDocs, Path): + if isinstance(CONFIG.pdfDocs, Path): self.addAction(self.mainMenu.aPdfDocs) return True @@ -1421,7 +1420,7 @@ class GuiMain(QMainWindow): def _updateWindowTitle(self, projName=None): """Set the window title and add the project's name. """ - winTitle = self.mainConf.appName + winTitle = CONFIG.appName if projName is not None: winTitle += " - %s" % projName self.setWindowTitle(winTitle) @@ -1572,7 +1571,7 @@ class GuiMain(QMainWindow): return currTime = time() - editIdle = currTime - self.docEditor.lastActive() > self.mainConf.userIdleTime + editIdle = currTime - self.docEditor.lastActive() > CONFIG.userIdleTime userIdle = qApp.applicationState() != Qt.ApplicationActive if editIdle or userIdle: @@ -1594,7 +1593,7 @@ class GuiMain(QMainWindow): self.mainStatus.setProjectStats(0, 0) self.theProject.updateWordCounts() - if self.mainConf.incNotesWCount: + if CONFIG.incNotesWCount: iTotal = sum(self.theProject.data.initCounts) cTotal = sum(self.theProject.data.currCounts) self.mainStatus.setProjectStats(cTotal, cTotal - iTotal) diff --git a/novelwriter/tools/build.py b/novelwriter/tools/build.py index 27e99eb8..9fe56440 100644 --- a/novelwriter/tools/build.py +++ b/novelwriter/tools/build.py @@ -25,7 +25,6 @@ along with this program. If not, see . import json import logging -import novelwriter from time import time from pathlib import Path @@ -43,6 +42,7 @@ from PyQt5.QtWidgets import ( ) from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog +from novelwriter import CONFIG from novelwriter.enum import nwAlert, nwItemType, nwItemLayout, nwItemClass from novelwriter.error import formatException, logException from novelwriter.common import fuzzyTime, makeFileNameSafe @@ -73,7 +73,6 @@ class GuiBuildNovel(QDialog): logger.debug("Initialising GuiBuildNovel ...") self.setObjectName("GuiBuildNovel") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.theProject = mainGui.theProject @@ -84,13 +83,13 @@ class GuiBuildNovel(QDialog): self.buildTime = 0 # The timestamp of the last build self.setWindowTitle(self.tr("Build Novel Project")) - self.setMinimumWidth(self.mainConf.pxInt(700)) - self.setMinimumHeight(self.mainConf.pxInt(600)) + self.setMinimumWidth(CONFIG.pxInt(700)) + self.setMinimumHeight(CONFIG.pxInt(600)) pOptions = self.theProject.options self.resize( - self.mainConf.pxInt(pOptions.getInt("GuiBuildNovel", "winWidth", 900)), - self.mainConf.pxInt(pOptions.getInt("GuiBuildNovel", "winHeight", 800)) + CONFIG.pxInt(pOptions.getInt("GuiBuildNovel", "winWidth", 900)), + CONFIG.pxInt(pOptions.getInt("GuiBuildNovel", "winHeight", 800)) ) self.docView = GuiBuildNovelDocView(self, self.theProject) @@ -121,7 +120,7 @@ class GuiBuildNovel(QDialog): "be centred automatically and only appear between sections of " "the same type." ).format("* * *") - xFmt = self.mainConf.pxInt(100) + xFmt = CONFIG.pxInt(100) self.fmtTitle = QLineEdit() self.fmtTitle.setMaxLength(200) @@ -165,7 +164,7 @@ class GuiBuildNovel(QDialog): self.buildLang = QComboBox() self.buildLang.setMinimumWidth(xFmt) - theLangs = self.mainConf.listLanguages(self.mainConf.LANG_PROJ) + theLangs = CONFIG.listLanguages(CONFIG.LANG_PROJ) self.buildLang.addItem("[%s]" % self.tr("Not Set"), "None") for langID, langName in theLangs: self.buildLang.addItem(langName, langID) @@ -237,7 +236,7 @@ class GuiBuildNovel(QDialog): self.textFont.setReadOnly(True) self.textFont.setMinimumWidth(xFmt) self.textFont.setText( - pOptions.getString("GuiBuildNovel", "textFont", self.mainConf.textFont) + pOptions.getString("GuiBuildNovel", "textFont", CONFIG.textFont) ) self.fontButton = QPushButton("...") self.fontButton.setMaximumWidth(int(2.5*self.mainTheme.getTextWidth("..."))) @@ -249,7 +248,7 @@ class GuiBuildNovel(QDialog): self.textSize.setMaximum(72) self.textSize.setSingleStep(1) self.textSize.setValue( - pOptions.getInt("GuiBuildNovel", "textSize", self.mainConf.textSize) + pOptions.getInt("GuiBuildNovel", "textSize", CONFIG.textSize) ) self.lineHeight = QDoubleSpinBox(self) @@ -518,13 +517,13 @@ class GuiBuildNovel(QDialog): self.buttonBox.addWidget(self.btnSave) self.buttonBox.addWidget(self.btnPrint) self.buttonBox.addWidget(self.btnClose) - self.buttonBox.setSpacing(self.mainConf.pxInt(4)) + self.buttonBox.setSpacing(CONFIG.pxInt(4)) # Assemble GUI # ============ # Splitter Position - boxWidth = self.mainConf.pxInt(350) + boxWidth = CONFIG.pxInt(350) boxWidth = pOptions.getInt("GuiBuildNovel", "boxWidth", boxWidth) docWidth = max(self.width() - boxWidth, 100) docWidth = pOptions.getInt("GuiBuildNovel", "docWidth", docWidth) @@ -547,22 +546,22 @@ class GuiBuildNovel(QDialog): # Tool Box Scroll Area self.toolsArea = QScrollArea() - self.toolsArea.setMinimumWidth(self.mainConf.pxInt(250)) + self.toolsArea.setMinimumWidth(CONFIG.pxInt(250)) self.toolsArea.setWidgetResizable(True) self.toolsArea.setWidget(self.toolsWidget) - if self.mainConf.hideVScroll: + if CONFIG.hideVScroll: self.toolsArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.toolsArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) - if self.mainConf.hideHScroll: + if CONFIG.hideHScroll: self.toolsArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) else: self.toolsArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) # Tools and Buttons Layout - tSp = self.mainConf.pxInt(8) + tSp = CONFIG.pxInt(8) self.innerBox = QVBoxLayout() self.innerBox.addWidget(self.toolsArea) self.innerBox.addSpacing(tSp) @@ -891,14 +890,14 @@ class GuiBuildNovel(QDialog): cleanName = makeFileNameSafe(self.theProject.data.name) fileName = "%s.%s" % (cleanName, fileExt) - savePath = self.mainConf.lastPath() / fileName + savePath = CONFIG.lastPath() / fileName savePath, _ = QFileDialog.getSaveFileName( self, self.tr("Save Document As"), str(savePath) ) if not savePath: return False - self.mainConf.setLastPath(savePath) + CONFIG.setLastPath(savePath) # Build and Write # =============== @@ -1173,8 +1172,8 @@ class GuiBuildNovel(QDialog): buildLang = self.buildLang.currentData() hideScene = self.hideScene.isChecked() hideSection = self.hideSection.isChecked() - winWidth = self.mainConf.rpxInt(self.width()) - winHeight = self.mainConf.rpxInt(self.height()) + winWidth = CONFIG.rpxInt(self.width()) + winHeight = CONFIG.rpxInt(self.height()) justifyText = self.justifyText.isChecked() noStyling = self.noStyling.isChecked() textFont = self.textFont.text() @@ -1192,8 +1191,8 @@ class GuiBuildNovel(QDialog): rootFilter = self._generateRootFilter() mainSplit = self.mainSplit.sizes() - boxWidth = self.mainConf.rpxInt(mainSplit[0]) - docWidth = self.mainConf.rpxInt(mainSplit[1]) + boxWidth = CONFIG.rpxInt(mainSplit[0]) + docWidth = CONFIG.rpxInt(mainSplit[1]) self.theProject.setProjectLang(buildLang) @@ -1243,7 +1242,6 @@ class GuiBuildNovelDocView(QTextBrowser): logger.debug("Initialising GuiBuildNovelDocView ...") - self.mainConf = novelwriter.CONFIG self.theProject = theProject self.mainGui = mainGui self.mainTheme = mainGui.mainTheme @@ -1252,7 +1250,7 @@ class GuiBuildNovelDocView(QTextBrowser): self.setMinimumWidth(40*self.mainGui.mainTheme.textNWidth) self.setOpenExternalLinks(False) - self.document().setDocumentMargin(self.mainConf.getTextMargin()) + self.document().setDocumentMargin(CONFIG.getTextMargin()) self.setPlaceholderText(self.tr( "This area will show the content of the document to be " "exported or printed. Press the \"Build Preview\" button " @@ -1260,15 +1258,15 @@ class GuiBuildNovelDocView(QTextBrowser): )) theFont = QFont() - if self.mainConf.textFont is None: + if CONFIG.textFont is None: # If none is defined, set the default back to config - self.mainConf.textFont = self.document().defaultFont().family() - theFont.setFamily(self.mainConf.textFont) - theFont.setPointSize(self.mainConf.textSize) + CONFIG.textFont = self.document().defaultFont().family() + theFont.setFamily(CONFIG.textFont) + theFont.setPointSize(CONFIG.textSize) self.setFont(theFont) # Set the tab stops - self.setTabStopDistance(self.mainConf.getTabWidth()) + self.setTabStopDistance(CONFIG.getTabWidth()) docPalette = self.palette() docPalette.setColor(QPalette.Base, QColor(255, 255, 255)) diff --git a/novelwriter/tools/lipsum.py b/novelwriter/tools/lipsum.py index 1047dd60..3a6f1f42 100644 --- a/novelwriter/tools/lipsum.py +++ b/novelwriter/tools/lipsum.py @@ -25,7 +25,6 @@ along with this program. If not, see . import random import logging -import novelwriter from PyQt5.QtCore import Qt from PyQt5.QtWidgets import ( @@ -33,6 +32,7 @@ from PyQt5.QtWidgets import ( QSpinBox ) +from novelwriter import CONFIG from novelwriter.common import readTextFile from novelwriter.extensions.switch import NSwitch @@ -47,18 +47,17 @@ class GuiLipsum(QDialog): logger.debug("Initialising GuiLipsum ...") self.setObjectName("GuiLipsum") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.setWindowTitle(self.tr("Insert Placeholder Text")) self.innerBox = QHBoxLayout() - self.innerBox.setSpacing(self.mainConf.pxInt(16)) + self.innerBox.setSpacing(CONFIG.pxInt(16)) # Icon - nPx = self.mainConf.pxInt(64) - vSp = self.mainConf.pxInt(4) + nPx = CONFIG.pxInt(64) + vSp = CONFIG.pxInt(4) self.docIcon = QLabel() self.docIcon.setPixmap(self.mainTheme.getPixmap("proj_document", (nPx, nPx))) @@ -105,7 +104,7 @@ class GuiLipsum(QDialog): self.outerBox = QVBoxLayout() self.outerBox.addLayout(self.innerBox) self.outerBox.addWidget(self.buttonBox) - self.outerBox.setSpacing(self.mainConf.pxInt(16)) + self.outerBox.setSpacing(CONFIG.pxInt(16)) self.setLayout(self.outerBox) logger.debug("GuiLipsum initialisation complete") @@ -119,7 +118,7 @@ class GuiLipsum(QDialog): def _doInsert(self): """Load the text and insert it in the open document. """ - lipsumFile = self.mainConf.assetPath("text") / "lipsum.txt" + lipsumFile = CONFIG.assetPath("text") / "lipsum.txt" lipsumText = readTextFile(lipsumFile).splitlines() if self.randSwitch.isChecked(): diff --git a/novelwriter/tools/manusbuild.py b/novelwriter/tools/manusbuild.py index f3a60162..6f1fc7f8 100644 --- a/novelwriter/tools/manusbuild.py +++ b/novelwriter/tools/manusbuild.py @@ -24,13 +24,13 @@ along with this program. If not, see . """ import logging -import novelwriter from PyQt5.QtWidgets import ( QDialog, QGridLayout, QPushButton, QSplitter, QTextBrowser, QVBoxLayout, QWidget, qApp ) +from novelwriter import CONFIG from novelwriter.tools.manussettings import GuiBuildSettings logger = logging.getLogger(__name__) @@ -41,22 +41,21 @@ class GuiBuildManuscript(QDialog): def __init__(self, mainGui): super().__init__(parent=mainGui) - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.theProject = mainGui.theProject self.setWindowTitle(self.tr("Build Manuscript")) - self.setMinimumWidth(self.mainConf.pxInt(600)) - self.setMinimumHeight(self.mainConf.pxInt(500)) + self.setMinimumWidth(CONFIG.pxInt(600)) + self.setMinimumHeight(CONFIG.pxInt(500)) - wWin = self.mainConf.pxInt(900) - hWin = self.mainConf.pxInt(600) + wWin = CONFIG.pxInt(900) + hWin = CONFIG.pxInt(600) pOptions = self.theProject.options self.resize( - self.mainConf.pxInt(pOptions.getInt("GuiBuildManuscript", "winWidth", wWin)), - self.mainConf.pxInt(pOptions.getInt("GuiBuildManuscript", "winHeight", hWin)) + CONFIG.pxInt(pOptions.getInt("GuiBuildManuscript", "winWidth", wWin)), + CONFIG.pxInt(pOptions.getInt("GuiBuildManuscript", "winHeight", hWin)) ) # Controls @@ -80,8 +79,8 @@ class GuiBuildManuscript(QDialog): self.mainSplit.addWidget(self.optsWidget) self.mainSplit.addWidget(self.manPreview) self.mainSplit.setSizes([ - self.mainConf.pxInt(pOptions.getInt("GuiBuildManuscript", "optsWidth", wWin//3)), - self.mainConf.pxInt(pOptions.getInt("GuiBuildManuscript", "viewWidth", 2*wWin//3)), + CONFIG.pxInt(pOptions.getInt("GuiBuildManuscript", "optsWidth", wWin//3)), + CONFIG.pxInt(pOptions.getInt("GuiBuildManuscript", "viewWidth", 2*wWin//3)), ]) self.outerBox = QVBoxLayout() @@ -134,8 +133,8 @@ class GuiBuildManuscript(QDialog): """ logger.debug("Saving GuiBuildManuscript settings") - winWidth = self.mainConf.rpxInt(self.width()) - winHeight = self.mainConf.rpxInt(self.height()) + winWidth = CONFIG.rpxInt(self.width()) + winHeight = CONFIG.rpxInt(self.height()) mainSplit = self.mainSplit.sizes() optsWidth = mainSplit[0] @@ -158,7 +157,6 @@ class GuiManuscriptPreview(QTextBrowser): def __init__(self, mainGui): super().__init__(parent=mainGui) - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.theProject = mainGui.theProject diff --git a/novelwriter/tools/manussettings.py b/novelwriter/tools/manussettings.py index 2ef9c3fc..7ae2f770 100644 --- a/novelwriter/tools/manussettings.py +++ b/novelwriter/tools/manussettings.py @@ -25,7 +25,6 @@ along with this program. If not, see . from __future__ import annotations import logging -import novelwriter from typing import TYPE_CHECKING @@ -37,6 +36,7 @@ from PyQt5.QtWidgets import ( QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget ) +from novelwriter import CONFIG from novelwriter.core.buildsettings import BuildSettings, FilterMode from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.switchbox import NSwitchBox @@ -64,7 +64,6 @@ class GuiBuildSettings(QDialog): logger.debug("Initialising GuiBuildSettings ...") self.setObjectName("GuiBuildSettings") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.theProject = mainGui.theProject @@ -73,17 +72,17 @@ class GuiBuildSettings(QDialog): self._build.unpack(buildData) self.setWindowTitle(self.tr("Manuscript Build Settings")) - self.setMinimumWidth(self.mainConf.pxInt(700)) - self.setMinimumHeight(self.mainConf.pxInt(400)) + self.setMinimumWidth(CONFIG.pxInt(700)) + self.setMinimumHeight(CONFIG.pxInt(400)) - mPx = self.mainConf.pxInt(150) - wWin = self.mainConf.pxInt(900) - hWin = self.mainConf.pxInt(600) + mPx = CONFIG.pxInt(150) + wWin = CONFIG.pxInt(900) + hWin = CONFIG.pxInt(600) pOptions = self.theProject.options self.resize( - self.mainConf.pxInt(pOptions.getInt("GuiBuildSettings", "winWidth", wWin)), - self.mainConf.pxInt(pOptions.getInt("GuiBuildSettings", "winHeight", hWin)) + CONFIG.pxInt(pOptions.getInt("GuiBuildSettings", "winWidth", wWin)), + CONFIG.pxInt(pOptions.getInt("GuiBuildSettings", "winHeight", hWin)) ) # Options SideBar @@ -204,8 +203,8 @@ class GuiBuildSettings(QDialog): """ logger.debug("Saving GuiBuildSettings settings") - winWidth = self.mainConf.rpxInt(self.width()) - winHeight = self.mainConf.rpxInt(self.height()) + winWidth = CONFIG.rpxInt(self.width()) + winHeight = CONFIG.rpxInt(self.height()) treeWidth, filterWidth = self.optTabSelect.mainSplitSizes() @@ -239,7 +238,6 @@ class GuiBuildFilterTab(QWidget): def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings): super().__init__(parent=buildMain) - self.mainConf = novelwriter.CONFIG self.mainGui = buildMain.mainGui self.mainTheme = buildMain.mainGui.mainTheme self.theProject = buildMain.mainGui.theProject @@ -259,7 +257,7 @@ class GuiBuildFilterTab(QWidget): # Tree Settings iPx = self.mainTheme.baseIconSize - cMg = self.mainConf.pxInt(6) + cMg = CONFIG.pxInt(6) # Tree Widget self.optTree = QTreeWidget(self) @@ -312,8 +310,8 @@ class GuiBuildFilterTab(QWidget): # ======== pOptions = self.theProject.options - wTree = self.mainConf.pxInt(pOptions.getInt("GuiBuildSettings", "treeWidth", 0)) - fTree = self.mainConf.pxInt(pOptions.getInt("GuiBuildSettings", "filterWidth", 0)) + wTree = CONFIG.pxInt(pOptions.getInt("GuiBuildSettings", "treeWidth", 0)) + fTree = CONFIG.pxInt(pOptions.getInt("GuiBuildSettings", "filterWidth", 0)) self.selectionBox = QVBoxLayout() self.selectionBox.addLayout(self.modeBox) @@ -511,7 +509,6 @@ class GuiBuildHeadingsTab(QWidget): def __init__(self, buildMain: GuiBuildSettings, build: BuildSettings): super().__init__(parent=buildMain) - self.mainConf = novelwriter.CONFIG self.mainGui = buildMain.mainGui self.mainTheme = buildMain.mainGui.mainTheme self.theProject = buildMain.mainGui.theProject @@ -519,8 +516,8 @@ class GuiBuildHeadingsTab(QWidget): self._build = build iPx = self.mainTheme.baseIconSize - vSp = self.mainConf.pxInt(12) - bSp = self.mainConf.pxInt(6) + vSp = CONFIG.pxInt(12) + bSp = CONFIG.pxInt(6) # Format Boxes # ============ diff --git a/novelwriter/tools/projwizard.py b/novelwriter/tools/projwizard.py index da6a0578..fdf5ea3a 100644 --- a/novelwriter/tools/projwizard.py +++ b/novelwriter/tools/projwizard.py @@ -25,7 +25,6 @@ along with this program. If not, see . import os import logging -import novelwriter from PyQt5.QtCore import Qt from PyQt5.QtWidgets import ( @@ -33,6 +32,7 @@ from PyQt5.QtWidgets import ( QPushButton, QRadioButton, QSpinBox, QVBoxLayout, QWizard, QWizardPage ) +from novelwriter import CONFIG from novelwriter.common import makeFileNameSafe from novelwriter.extensions.switch import NSwitch @@ -53,12 +53,11 @@ class GuiProjectWizard(QWizard): logger.debug("Initialising GuiProjectWizard ...") self.setObjectName("GuiProjectWizard") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.sideImage = self.mainTheme.loadDecoration( - "wiz-back", None, self.mainConf.pxInt(370) + "wiz-back", None, CONFIG.pxInt(370) ) self.setWizardStyle(QWizard.ModernStyle) self.setPixmap(QWizard.WatermarkPixmap, self.sideImage) @@ -89,7 +88,6 @@ class ProjWizardIntroPage(QWizardPage): def __init__(self, theWizard): super().__init__() - self.mainConf = novelwriter.CONFIG self.theWizard = theWizard self.mainTheme = theWizard.mainTheme @@ -109,9 +107,9 @@ class ProjWizardIntroPage(QWizardPage): lblFont.setPointSizeF(0.6*self.mainTheme.fontPointSize) self.imgCredit.setFont(lblFont) - xW = self.mainConf.pxInt(300) - vS = self.mainConf.pxInt(12) - fS = self.mainConf.pxInt(4) + xW = CONFIG.pxInt(300) + vS = CONFIG.pxInt(12) + fS = CONFIG.pxInt(4) # The Page Form self.projName = QLineEdit() @@ -158,7 +156,6 @@ class ProjWizardFolderPage(QWizardPage): def __init__(self, theWizard): super().__init__() - self.mainConf = novelwriter.CONFIG self.theWizard = theWizard self.mainTheme = theWizard.mainTheme @@ -169,9 +166,9 @@ class ProjWizardFolderPage(QWizardPage): )) self.theText.setWordWrap(True) - xW = self.mainConf.pxInt(300) - vS = self.mainConf.pxInt(12) - fS = self.mainConf.pxInt(8) + xW = CONFIG.pxInt(300) + vS = CONFIG.pxInt(12) + fS = CONFIG.pxInt(8) self.projPath = QLineEdit("") self.projPath.setFixedWidth(xW) @@ -234,7 +231,7 @@ class ProjWizardFolderPage(QWizardPage): def _doBrowse(self): """Select a project folder. """ - lastPath = self.mainConf.lastPath() + lastPath = CONFIG.lastPath() projDir = QFileDialog.getExistingDirectory( self, self.tr("Select Project Folder"), str(lastPath), options=QFileDialog.ShowDirsOnly ) @@ -256,7 +253,6 @@ class ProjWizardPopulatePage(QWizardPage): def __init__(self, theWizard): super().__init__() - self.mainConf = novelwriter.CONFIG self.theWizard = theWizard self.setTitle(self.tr("Populate Project")) @@ -267,8 +263,8 @@ class ProjWizardPopulatePage(QWizardPage): )) self.theText.setWordWrap(True) - vS = self.mainConf.pxInt(12) - fS = self.mainConf.pxInt(4) + vS = CONFIG.pxInt(12) + fS = CONFIG.pxInt(4) self.popMinimal = QRadioButton(self.tr("Fill the project with a minimal set of items")) self.popSample = QRadioButton(self.tr("Fill the project with example files")) @@ -312,7 +308,6 @@ class ProjWizardCustomPage(QWizardPage): def __init__(self, theWizard): super().__init__() - self.mainConf = novelwriter.CONFIG self.theWizard = theWizard self.setTitle(self.tr("Custom Project Options")) @@ -323,9 +318,9 @@ class ProjWizardCustomPage(QWizardPage): )) self.theText.setWordWrap(True) - cM = self.mainConf.pxInt(12) - mH = self.mainConf.pxInt(26) - fS = self.mainConf.pxInt(4) + cM = CONFIG.pxInt(12) + mH = CONFIG.pxInt(26) + fS = CONFIG.pxInt(4) # Root Folders self.addPlot = NSwitch() @@ -413,7 +408,6 @@ class ProjWizardFinalPage(QWizardPage): def __init__(self, theWizard): super().__init__() - self.mainConf = novelwriter.CONFIG self.theWizard = theWizard self.setTitle(self.tr("Summary")) @@ -422,7 +416,7 @@ class ProjWizardFinalPage(QWizardPage): # Assemble self.outerBox = QVBoxLayout() - self.outerBox.setSpacing(self.mainConf.pxInt(12)) + self.outerBox.setSpacing(CONFIG.pxInt(12)) self.outerBox.addWidget(self.theText) self.outerBox.addStretch(1) self.setLayout(self.outerBox) @@ -470,7 +464,7 @@ class ProjWizardFinalPage(QWizardPage): self.tr("You have selected the following:"), "
 • ".join(sumList), self.tr("Press '{0}' to create the new project.").format( - self.tr("Done") if self.mainConf.osDarwin else self.tr("Finish") + self.tr("Done") if CONFIG.osDarwin else self.tr("Finish") ) ) ) diff --git a/novelwriter/tools/writingstats.py b/novelwriter/tools/writingstats.py index cb2edcf8..8f4ba724 100644 --- a/novelwriter/tools/writingstats.py +++ b/novelwriter/tools/writingstats.py @@ -25,7 +25,6 @@ along with this program. If not, see . import json import logging -import novelwriter from pathlib import Path from datetime import datetime @@ -37,6 +36,7 @@ from PyQt5.QtWidgets import ( QLabel, QGroupBox, QMenu, QAction, QFileDialog, QSpinBox, QHBoxLayout ) +from novelwriter import CONFIG from novelwriter.enum import nwAlert from novelwriter.error import formatException from novelwriter.common import formatTime, checkInt, checkIntTuple, minmax @@ -63,7 +63,6 @@ class GuiWritingStats(QDialog): logger.debug("Initialising GuiWritingStats ...") self.setObjectName("GuiWritingStats") - self.mainConf = novelwriter.CONFIG self.mainGui = mainGui self.mainTheme = mainGui.mainTheme self.theProject = mainGui.theProject @@ -76,24 +75,24 @@ class GuiWritingStats(QDialog): pOptions = self.theProject.options self.setWindowTitle(self.tr("Writing Statistics")) - self.setMinimumWidth(self.mainConf.pxInt(420)) - self.setMinimumHeight(self.mainConf.pxInt(400)) + self.setMinimumWidth(CONFIG.pxInt(420)) + self.setMinimumHeight(CONFIG.pxInt(400)) self.resize( - self.mainConf.pxInt(pOptions.getInt("GuiWritingStats", "winWidth", 550)), - self.mainConf.pxInt(pOptions.getInt("GuiWritingStats", "winHeight", 500)) + CONFIG.pxInt(pOptions.getInt("GuiWritingStats", "winWidth", 550)), + CONFIG.pxInt(pOptions.getInt("GuiWritingStats", "winHeight", 500)) ) # List Box - wCol0 = self.mainConf.pxInt( + wCol0 = CONFIG.pxInt( pOptions.getInt("GuiWritingStats", "widthCol0", 180) ) - wCol1 = self.mainConf.pxInt( + wCol1 = CONFIG.pxInt( pOptions.getInt("GuiWritingStats", "widthCol1", 80) ) - wCol2 = self.mainConf.pxInt( + wCol2 = CONFIG.pxInt( pOptions.getInt("GuiWritingStats", "widthCol2", 80) ) - wCol3 = self.mainConf.pxInt( + wCol3 = CONFIG.pxInt( pOptions.getInt("GuiWritingStats", "widthCol3", 80) ) @@ -127,7 +126,7 @@ class GuiWritingStats(QDialog): # Word Bar self.barHeight = int(round(0.5*self.mainTheme.fontPixelSize)) - self.barWidth = self.mainConf.pxInt(200) + self.barWidth = CONFIG.pxInt(200) self.barImage = QPixmap(self.barHeight, self.barHeight) self.barImage.fill(self.palette().highlight().color()) @@ -309,12 +308,12 @@ class GuiWritingStats(QDialog): """ self.logData = [] - winWidth = self.mainConf.rpxInt(self.width()) - winHeight = self.mainConf.rpxInt(self.height()) - widthCol0 = self.mainConf.rpxInt(self.listBox.columnWidth(0)) - widthCol1 = self.mainConf.rpxInt(self.listBox.columnWidth(1)) - widthCol2 = self.mainConf.rpxInt(self.listBox.columnWidth(2)) - widthCol3 = self.mainConf.rpxInt(self.listBox.columnWidth(3)) + winWidth = CONFIG.rpxInt(self.width()) + winHeight = CONFIG.rpxInt(self.height()) + widthCol0 = CONFIG.rpxInt(self.listBox.columnWidth(0)) + widthCol1 = CONFIG.rpxInt(self.listBox.columnWidth(1)) + widthCol2 = CONFIG.rpxInt(self.listBox.columnWidth(2)) + widthCol3 = CONFIG.rpxInt(self.listBox.columnWidth(3)) sortCol = self.listBox.sortColumn() sortOrder = self.listBox.header().sortIndicatorOrder() incNovel = self.incNovel.isChecked() @@ -362,14 +361,14 @@ class GuiWritingStats(QDialog): return False # Generate the file name - savePath = self.mainConf.lastPath() / f"sessionStats.{fileExt}" + savePath = CONFIG.lastPath() / f"sessionStats.{fileExt}" savePath, _ = QFileDialog.getSaveFileName( self, self.tr("Save Data As"), str(savePath), "%s (*.%s)" % (textFmt, fileExt) ) if not savePath: return False - self.mainConf.setLastPath(savePath) + CONFIG.setLastPath(savePath) # Do the actual writing wSuccess = False diff --git a/tests/conftest.py b/tests/conftest.py index dd2004d6..9435eee6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -28,19 +28,60 @@ from pathlib import Path from mock import MockGuiMain from tools import cleanProject +from PyQt5.QtWidgets import QMessageBox + sys.path.insert(1, str(Path(__file__).parent.parent.absolute())) -import novelwriter # noqa: E402 +from novelwriter import CONFIG, main # noqa: E402 -from PyQt5.QtWidgets import QMessageBox # noqa: E402 - -from novelwriter.config import Config # noqa: E402 +_TST_ROOT = Path(__file__).parent +_TMP_ROOT = _TST_ROOT / "temp" +_TMP_CONF = _TMP_ROOT / "conf" -@pytest.fixture(autouse=True) -def initQt(qtbot): - """Ensures that the qt main thread is always available in all tests. +## +# Helper Functions +## + +def resetConfigVars(): + """Reset the CONFIG object and set various values for testing to + prevent interfering with local OS. """ + CONFIG.setLastPath(_TMP_ROOT) + CONFIG.setBackupPath(_TMP_ROOT) + CONFIG._homePath = _TMP_ROOT + CONFIG.guiLocale = "en_GB" + return + + +## +# Auto Fixtures +## + +@pytest.fixture(scope="session", autouse=True) +def sessionFixture(): + """A session wide fixture to set up the test environment. + """ + if _TMP_ROOT.exists(): + shutil.rmtree(_TMP_ROOT) + _TMP_ROOT.mkdir() + _TMP_CONF.mkdir() + return + + +@pytest.fixture(scope="function", autouse=True) +def functionFixture(qtbot): + """Ensures that the main Qt thread is always available, and reset + the config object for each function and redirect its storage paths. + """ + if _TMP_CONF.exists(): + shutil.rmtree(_TMP_CONF) + _TMP_CONF.mkdir() + + CONFIG.__init__() + CONFIG.initConfig(confPath=_TMP_CONF, dataPath=_TMP_CONF) + resetConfigVars() + return @@ -49,26 +90,17 @@ def initQt(qtbot): ## @pytest.fixture(scope="session") -def tmpPath(): - """A temporary folder for the test session. Path version. - """ - theTemp = Path(__file__).parent / "temp" - if theTemp.exists(): - shutil.rmtree(theTemp) - theTemp.mkdir(exist_ok=True) - return theTemp - - -@pytest.fixture(scope="session") -def tstPaths(tmpPath): +def tstPaths(): """Returns an object that can provide the various paths needed for running tests. """ class _Store: - testDir = Path(__file__).parent - filesDir = testDir / "files" - refDir = testDir / "reference" - outDir = tmpPath / "results" + testDir = _TST_ROOT + filesDir = _TST_ROOT / "files" + refDir = _TST_ROOT / "reference" + outDir = _TMP_ROOT / "results" + tmpDir = _TMP_ROOT + cnfDir = _TMP_CONF store = _Store() store.outDir.mkdir(exist_ok=True) @@ -77,10 +109,10 @@ def tstPaths(tmpPath): @pytest.fixture(scope="function") -def fncPath(tmpPath): - """A temporary folder for a single test function. Path version. +def fncPath(): + """A temporary folder for a single test function. """ - fncPath = tmpPath / "function" + fncPath = _TMP_ROOT / "function" if fncPath.is_dir(): shutil.rmtree(fncPath) fncPath.mkdir(exist_ok=True) @@ -103,46 +135,17 @@ def projPath(fncPath): # novelWriter Objects ## -@pytest.fixture(scope="function") -def tmpConf(tmpPath): - """Create a temporary novelWriter configuration object. - """ - confFile = tmpPath / "novelwriter.conf" - if confFile.is_file(): - confFile.unlink() - theConf = Config() - theConf.initConfig(tmpPath, tmpPath) - theConf.setLastPath(tmpPath) - theConf.guiLocale = "en_GB" - return theConf - @pytest.fixture(scope="function") -def fncConf(fncPath): - """Create a temporary novelWriter configuration object. - """ - confFile = fncPath / "novelwriter.conf" - if confFile.is_file(): - confFile.unlink() - theConf = Config() - theConf.initConfig(fncPath, fncPath) - theConf.setLastPath(fncPath) - theConf.guiLocale = "en_GB" - return theConf - - -@pytest.fixture(scope="function") -def mockGUI(monkeypatch, tmpConf): +def mockGUI(): """Create a mock instance of novelWriter's main GUI class. """ - monkeypatch.setattr("novelwriter.CONFIG", tmpConf) theGui = MockGuiMain() - theGui.mainConf = tmpConf return theGui @pytest.fixture(scope="function") -def nwGUI(qtbot, monkeypatch, fncPath, fncConf): +def nwGUI(qtbot, monkeypatch, functionFixture): """Create an instance of the novelWriter GUI. """ monkeypatch.setattr(QMessageBox, "warning", lambda *a: QMessageBox.Ok) @@ -150,14 +153,13 @@ def nwGUI(qtbot, monkeypatch, fncPath, fncConf): monkeypatch.setattr(QMessageBox, "information", lambda *a: QMessageBox.Ok) monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes) - monkeypatch.setattr("novelwriter.CONFIG", fncConf) - nwGUI = novelwriter.main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"]) + nwGUI = main(["--testmode", f"--config={_TMP_CONF}", f"--data={_TMP_CONF}"]) qtbot.addWidget(nwGUI) + resetConfigVars() + nwGUI.show() qtbot.wait(20) - nwGUI.mainConf.setLastPath(fncPath) - yield nwGUI qtbot.wait(20) @@ -198,13 +200,12 @@ def mockRnd(monkeypatch): ## @pytest.fixture(scope="function") -def nwLipsum(tmpPath): +def nwLipsum(): """A medium sized novelWriter example project with a lot of Lorem Ipsum text. """ - tstDir = Path(__file__).parent - srcDir = tstDir / "lipsum" - dstDir = tmpPath / "lipsum" + srcDir = _TST_ROOT / "lipsum" + dstDir = _TMP_ROOT / "lipsum" if dstDir.exists(): shutil.rmtree(dstDir) @@ -220,13 +221,12 @@ def nwLipsum(tmpPath): @pytest.fixture(scope="function") -def prjLipsum(tmpPath): +def prjLipsum(): """A medium sized novelWriter example project with a lot of Lorem Ipsum text. """ - tstDir = Path(__file__).parent - srcDir = tstDir / "lipsum" - dstDir = tmpPath / "lipsum" + srcDir = _TST_ROOT / "lipsum" + dstDir = _TMP_ROOT / "lipsum" if dstDir.exists(): shutil.rmtree(dstDir) diff --git a/tests/mock.py b/tests/mock.py index 96a4c5f8..57381b0a 100644 --- a/tests/mock.py +++ b/tests/mock.py @@ -31,7 +31,6 @@ class MockGuiMain(QObject): def __init__(self): super().__init__() - self.mainConf = None self.hasProject = True self.theProject = None self.mainStatus = MockStatusBar() diff --git a/tests/test_base/test_base_config.py b/tests/test_base/test_base_config.py index 17d9ddf9..0d986906 100644 --- a/tests/test_base/test_base_config.py +++ b/tests/test_base/test_base_config.py @@ -28,6 +28,7 @@ from pathlib import Path from mock import causeOSError, MockApp from tools import cmpFiles, writeFile +from novelwriter import CONFIG from novelwriter.config import Config, RecentProjects from novelwriter.constants import nwFiles @@ -196,197 +197,206 @@ def testBaseConfig_Localisation(fncPath, tstPaths): @pytest.mark.base -def testBaseConfig_Methods(tmpConf, tmpPath): +def testBaseConfig_Methods(fncPath): """Check class methods. """ + tstConf = Config() + tstConf.initConfig(confPath=fncPath, dataPath=fncPath) + # Data Path - assert tmpConf.dataPath() == tmpPath - assert tmpConf.dataPath("stuff") == tmpPath / "stuff" + assert tstConf.dataPath() == fncPath + assert tstConf.dataPath("stuff") == fncPath / "stuff" # Assets Path - appPath = tmpConf._appPath - assert tmpConf.assetPath() == appPath / "assets" - assert tmpConf.assetPath("stuff") == appPath / "assets" / "stuff" + appPath = tstConf._appPath + assert tstConf.assetPath() == appPath / "assets" + assert tstConf.assetPath("stuff") == appPath / "assets" / "stuff" # Last Path - assert tmpConf.lastPath() == tmpPath + assert tstConf.lastPath() == Path.home().absolute() - tmpStuff = tmpPath / "stuff" + tmpStuff = fncPath / "stuff" tmpStuff.mkdir() - tmpConf.setLastPath(tmpStuff) - assert tmpConf.lastPath() == tmpStuff + tstConf.setLastPath(tmpStuff) + assert tstConf.lastPath() == tmpStuff fileStuff = tmpStuff / "more_stuff.txt" fileStuff.write_text("Stuff") - tmpConf.setLastPath(fileStuff) - assert tmpConf.lastPath() == tmpStuff + tstConf.setLastPath(fileStuff) + assert tstConf.lastPath() == tmpStuff fileStuff.unlink() tmpStuff.rmdir() - assert tmpConf.lastPath() == Path.home().absolute() + assert tstConf.lastPath() == Path.home().absolute() # Recent Projects - assert isinstance(tmpConf.recentProjects, RecentProjects) + assert isinstance(tstConf.recentProjects, RecentProjects) # END Test testBaseConfig_Methods @pytest.mark.base -def testBaseConfig_SettersGetters(tmpConf): +def testBaseConfig_SettersGetters(fncPath): """Set various sizes and positions """ + tstConf = Config() + tstConf.initConfig(confPath=fncPath, dataPath=fncPath) + # GUI Scaling # =========== - tmpConf.guiScale = 1.0 - assert tmpConf.pxInt(10) == 10 - assert tmpConf.pxInt(13) == 13 - assert tmpConf.rpxInt(10) == 10 - assert tmpConf.rpxInt(13) == 13 + tstConf.guiScale = 1.0 + assert tstConf.pxInt(10) == 10 + assert tstConf.pxInt(13) == 13 + assert tstConf.rpxInt(10) == 10 + assert tstConf.rpxInt(13) == 13 - tmpConf.guiScale = 2.0 - assert tmpConf.pxInt(10) == 20 - assert tmpConf.pxInt(13) == 26 - assert tmpConf.rpxInt(10) == 5 - assert tmpConf.rpxInt(13) == 6 + tstConf.guiScale = 2.0 + assert tstConf.pxInt(10) == 20 + assert tstConf.pxInt(13) == 26 + assert tstConf.rpxInt(10) == 5 + assert tstConf.rpxInt(13) == 6 # Setter + Getter Combos # ====================== # Window Size - tmpConf.guiScale = 1.0 - tmpConf.setMainWinSize(1205, 655) - assert tmpConf.mainWinSize == [1200, 650] + tstConf.guiScale = 1.0 + tstConf.setMainWinSize(1205, 655) + assert tstConf.mainWinSize == [1200, 650] - tmpConf.guiScale = 2.0 - tmpConf.setMainWinSize(70, 70) - assert tmpConf.mainWinSize == [70, 70] - assert tmpConf._mainWinSize == [35, 35] + tstConf.guiScale = 2.0 + tstConf.setMainWinSize(70, 70) + assert tstConf.mainWinSize == [70, 70] + assert tstConf._mainWinSize == [35, 35] - tmpConf.guiScale = 1.0 - tmpConf.setMainWinSize(70, 70) - assert tmpConf.mainWinSize == [70, 70] - assert tmpConf._mainWinSize == [70, 70] + tstConf.guiScale = 1.0 + tstConf.setMainWinSize(70, 70) + assert tstConf.mainWinSize == [70, 70] + assert tstConf._mainWinSize == [70, 70] - tmpConf.setMainWinSize(1200, 650) + tstConf.setMainWinSize(1200, 650) # Preferences Size - tmpConf.guiScale = 2.0 - tmpConf.setPreferencesWinSize(70, 70) - assert tmpConf.preferencesWinSize == [70, 70] - assert tmpConf._prefsWinSize == [35, 35] + tstConf.guiScale = 2.0 + tstConf.setPreferencesWinSize(70, 70) + assert tstConf.preferencesWinSize == [70, 70] + assert tstConf._prefsWinSize == [35, 35] - tmpConf.guiScale = 1.0 - tmpConf.setPreferencesWinSize(70, 70) - assert tmpConf.preferencesWinSize == [70, 70] - assert tmpConf._prefsWinSize == [70, 70] + tstConf.guiScale = 1.0 + tstConf.setPreferencesWinSize(70, 70) + assert tstConf.preferencesWinSize == [70, 70] + assert tstConf._prefsWinSize == [70, 70] - tmpConf.setPreferencesWinSize(700, 615) + tstConf.setPreferencesWinSize(700, 615) # Project Settings Tree Columns - tmpConf.guiScale = 2.0 - tmpConf.setProjLoadColWidths([10, 20, 30]) - assert tmpConf.projLoadColWidths == [10, 20, 30] - assert tmpConf._projLoadCols == [5, 10, 15] + tstConf.guiScale = 2.0 + tstConf.setProjLoadColWidths([10, 20, 30]) + assert tstConf.projLoadColWidths == [10, 20, 30] + assert tstConf._projLoadCols == [5, 10, 15] - tmpConf.guiScale = 1.0 - tmpConf.setProjLoadColWidths([10, 20, 30]) - assert tmpConf.projLoadColWidths == [10, 20, 30] - assert tmpConf._projLoadCols == [10, 20, 30] + tstConf.guiScale = 1.0 + tstConf.setProjLoadColWidths([10, 20, 30]) + assert tstConf.projLoadColWidths == [10, 20, 30] + assert tstConf._projLoadCols == [10, 20, 30] - tmpConf.setProjLoadColWidths([200, 60, 140]) + tstConf.setProjLoadColWidths([200, 60, 140]) # Main Pane Splitter - tmpConf.guiScale = 2.0 - tmpConf.setMainPanePos([200, 700]) - assert tmpConf.mainPanePos == [200, 700] - assert tmpConf._mainPanePos == [100, 350] + tstConf.guiScale = 2.0 + tstConf.setMainPanePos([200, 700]) + assert tstConf.mainPanePos == [200, 700] + assert tstConf._mainPanePos == [100, 350] - tmpConf.guiScale = 1.0 - tmpConf.setMainPanePos([200, 700]) - assert tmpConf.mainPanePos == [200, 700] - assert tmpConf._mainPanePos == [200, 700] + tstConf.guiScale = 1.0 + tstConf.setMainPanePos([200, 700]) + assert tstConf.mainPanePos == [200, 700] + assert tstConf._mainPanePos == [200, 700] - tmpConf.setMainPanePos([300, 800]) + tstConf.setMainPanePos([300, 800]) # View Pane Splitter - tmpConf.guiScale = 2.0 - tmpConf.setViewPanePos([400, 250]) - assert tmpConf.viewPanePos == [400, 250] - assert tmpConf._viewPanePos == [200, 125] + tstConf.guiScale = 2.0 + tstConf.setViewPanePos([400, 250]) + assert tstConf.viewPanePos == [400, 250] + assert tstConf._viewPanePos == [200, 125] - tmpConf.guiScale = 1.0 - tmpConf.setViewPanePos([400, 250]) - assert tmpConf.viewPanePos == [400, 250] - assert tmpConf._viewPanePos == [400, 250] + tstConf.guiScale = 1.0 + tstConf.setViewPanePos([400, 250]) + assert tstConf.viewPanePos == [400, 250] + assert tstConf._viewPanePos == [400, 250] - tmpConf.setViewPanePos([500, 150]) + tstConf.setViewPanePos([500, 150]) # Outline Pane Splitter - tmpConf.guiScale = 2.0 - tmpConf.setOutlinePanePos([400, 250]) - assert tmpConf.outlinePanePos == [400, 250] - assert tmpConf._outlnPanePos == [200, 125] + tstConf.guiScale = 2.0 + tstConf.setOutlinePanePos([400, 250]) + assert tstConf.outlinePanePos == [400, 250] + assert tstConf._outlnPanePos == [200, 125] - tmpConf.guiScale = 1.0 - tmpConf.setOutlinePanePos([400, 250]) - assert tmpConf.outlinePanePos == [400, 250] - assert tmpConf._outlnPanePos == [400, 250] + tstConf.guiScale = 1.0 + tstConf.setOutlinePanePos([400, 250]) + assert tstConf.outlinePanePos == [400, 250] + assert tstConf._outlnPanePos == [400, 250] - tmpConf.setOutlinePanePos([500, 150]) + tstConf.setOutlinePanePos([500, 150]) # Getters Only # ============ - tmpConf.guiScale = 1.0 - assert tmpConf.getTextWidth(False) == 700 - assert tmpConf.getTextWidth(True) == 800 - assert tmpConf.getTextMargin() == 40 - assert tmpConf.getTabWidth() == 40 + tstConf.guiScale = 1.0 + assert tstConf.getTextWidth(False) == 700 + assert tstConf.getTextWidth(True) == 800 + assert tstConf.getTextMargin() == 40 + assert tstConf.getTabWidth() == 40 - tmpConf.guiScale = 2.0 - assert tmpConf.getTextWidth(False) == 1400 - assert tmpConf.getTextWidth(True) == 1600 - assert tmpConf.getTextMargin() == 80 - assert tmpConf.getTabWidth() == 80 + tstConf.guiScale = 2.0 + assert tstConf.getTextWidth(False) == 1400 + assert tstConf.getTextWidth(True) == 1600 + assert tstConf.getTextMargin() == 80 + assert tstConf.getTabWidth() == 80 # END Test testBaseConfig_SettersGetters @pytest.mark.base -def testBaseConfig_Internal(monkeypatch, tmpConf): +def testBaseConfig_Internal(monkeypatch, fncPath): """Check internal functions. """ + tstConf = Config() + tstConf.initConfig(confPath=fncPath, dataPath=fncPath) + # Function _packList - assert tmpConf._packList(["A", 1, 2.0, None, False]) == "A, 1, 2.0, None, False" + assert tstConf._packList(["A", 1, 2.0, None, False]) == "A, 1, 2.0, None, False" # Function _checkNone - assert tmpConf._checkNone(None) is None - assert tmpConf._checkNone("None") is None - assert tmpConf._checkNone("none") is None - assert tmpConf._checkNone("NONE") is None - assert tmpConf._checkNone("NoNe") is None - assert tmpConf._checkNone(123456) == 123456 + assert tstConf._checkNone(None) is None + assert tstConf._checkNone("None") is None + assert tstConf._checkNone("none") is None + assert tstConf._checkNone("NONE") is None + assert tstConf._checkNone("NoNe") is None + assert tstConf._checkNone(123456) == 123456 # Function _checkOptionalPackages # (Assumes enchant package exists and is importable) - tmpConf._checkOptionalPackages() - assert tmpConf.hasEnchant is True + tstConf._checkOptionalPackages() + assert tstConf.hasEnchant is True with monkeypatch.context() as mp: mp.setitem(sys.modules, "enchant", None) - tmpConf._checkOptionalPackages() - assert tmpConf.hasEnchant is False + tstConf._checkOptionalPackages() + assert tstConf.hasEnchant is False # END Test testBaseConfig_Internal @pytest.mark.base -def testBaseConfig_RecentCache(monkeypatch, fncConf, fncPath): +def testBaseConfig_RecentCache(monkeypatch, tstPaths): """Test recent cache file. """ - cacheFile = fncPath / nwFiles.RECENT_FILE - recent = RecentProjects(fncConf) + cacheFile = tstPaths.cnfDir / nwFiles.RECENT_FILE + recent = RecentProjects(CONFIG) # Load when there is no file should pass, but load nothing assert not cacheFile.exists() @@ -394,8 +404,8 @@ def testBaseConfig_RecentCache(monkeypatch, fncConf, fncPath): assert recent.listEntries() == [] # Add a couple of values - pathOne = fncPath / "projPathOne" / nwFiles.PROJ_FILE - pathTwo = fncPath / "projPathTwo" / nwFiles.PROJ_FILE + pathOne = tstPaths.cnfDir / "projPathOne" / nwFiles.PROJ_FILE + pathTwo = tstPaths.cnfDir / "projPathTwo" / nwFiles.PROJ_FILE recent.update(pathOne, "Proj One", 100, 1600002000) recent.update(pathTwo, "Proj Two", 200, 1600005600) diff --git a/tests/test_base/test_base_init.py b/tests/test_base/test_base_init.py index 3c5b6780..71056fb7 100644 --- a/tests/test_base/test_base_init.py +++ b/tests/test_base/test_base_init.py @@ -22,46 +22,47 @@ along with this program. If not, see . import sys import pytest import logging -import novelwriter from mock import MockGuiMain +from novelwriter import CONFIG, main, logger + @pytest.mark.base -def testBaseInit_Launch(caplog, monkeypatch, tmpPath): +def testBaseInit_Launch(caplog, monkeypatch, fncPath): """Check launching the main GUI. """ monkeypatch.setattr("novelwriter.guimain.GuiMain", MockGuiMain) # TestMode Launch - nwGUI = novelwriter.main(["--testmode", f"--config={tmpPath}", f"--data={tmpPath}"]) + nwGUI = main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"]) assert isinstance(nwGUI, MockGuiMain) # Darwin Launch caplog.clear() - osDarwin = novelwriter.CONFIG.osDarwin - novelwriter.CONFIG.osDarwin = True + osDarwin = CONFIG.osDarwin + CONFIG.osDarwin = True with monkeypatch.context() as mp: mp.setitem(sys.modules, "Foundation", None) - nwGUI = novelwriter.main(["--testmode", f"--config={tmpPath}", f"--data={tmpPath}"]) + nwGUI = main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"]) assert isinstance(nwGUI, MockGuiMain) assert "Failed" in caplog.text - novelwriter.CONFIG.osDarwin = osDarwin + CONFIG.osDarwin = osDarwin # Windows Launch caplog.clear() - osWindows = novelwriter.CONFIG.osWindows - novelwriter.CONFIG.osWindows = True + osWindows = CONFIG.osWindows + CONFIG.osWindows = True with monkeypatch.context() as mp: mp.setitem(sys.modules, "ctypes", None) - nwGUI = novelwriter.main(["--testmode", f"--config={tmpPath}", f"--data={tmpPath}"]) + nwGUI = main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"]) assert isinstance(nwGUI, MockGuiMain) if not sys.platform.startswith("darwin"): # For some reason, the test doesn't work on macOS assert "Failed" in caplog.text - novelwriter.CONFIG.osWindows = osWindows + CONFIG.osWindows = osWindows # Normal Launch monkeypatch.setattr("PyQt5.QtWidgets.QApplication.__init__", lambda *a: None) @@ -71,72 +72,72 @@ def testBaseInit_Launch(caplog, monkeypatch, tmpPath): monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setOrganizationDomain", lambda *a: None) monkeypatch.setattr("PyQt5.QtWidgets.QApplication.exec_", lambda *a: 0) with pytest.raises(SystemExit) as ex: - novelwriter.main([f"--config={tmpPath}", f"--data={tmpPath}"]) + main([f"--config={fncPath}", f"--data={fncPath}"]) assert ex.value.code == 0 # END Test testBaseInit_Launch @pytest.mark.base -def testBaseInit_Options(monkeypatch, tmpPath): +def testBaseInit_Options(monkeypatch, fncPath): """Test command line options for logging level. """ monkeypatch.setattr("novelwriter.guimain.GuiMain", MockGuiMain) monkeypatch.setattr(sys, "argv", [ - "novelWriter.py", "--testmode", f"--config={tmpPath}", f"--data={tmpPath}" + "novelWriter.py", "--testmode", f"--config={fncPath}", f"--data={fncPath}" ]) # Defaults w/None Args - nwGUI = novelwriter.main() - assert novelwriter.logger.getEffectiveLevel() == logging.WARNING + nwGUI = main() + assert logger.getEffectiveLevel() == logging.WARNING assert nwGUI.closeMain() == "closeMain" # Defaults - nwGUI = novelwriter.main( - ["--testmode", f"--config={tmpPath}", f"--data={tmpPath}", "--style=Fusion"] + nwGUI = main( + ["--testmode", f"--config={fncPath}", f"--data={fncPath}", "--style=Fusion"] ) - assert novelwriter.logger.getEffectiveLevel() == logging.WARNING + assert logger.getEffectiveLevel() == logging.WARNING assert nwGUI.closeMain() == "closeMain" # Log Levels - nwGUI = novelwriter.main( - ["--testmode", "--info", f"--config={tmpPath}", f"--data={tmpPath}"] + nwGUI = main( + ["--testmode", "--info", f"--config={fncPath}", f"--data={fncPath}"] ) - assert novelwriter.logger.getEffectiveLevel() == logging.INFO + assert logger.getEffectiveLevel() == logging.INFO assert nwGUI.closeMain() == "closeMain" - nwGUI = novelwriter.main( - ["--testmode", "--debug", f"--config={tmpPath}", f"--data={tmpPath}"] + nwGUI = main( + ["--testmode", "--debug", f"--config={fncPath}", f"--data={fncPath}"] ) - assert novelwriter.logger.getEffectiveLevel() == logging.DEBUG + assert logger.getEffectiveLevel() == logging.DEBUG assert nwGUI.closeMain() == "closeMain" # Help and Version with pytest.raises(SystemExit) as ex: - nwGUI = novelwriter.main( - ["--testmode", "--help", f"--config={tmpPath}", f"--data={tmpPath}"] + nwGUI = main( + ["--testmode", "--help", f"--config={fncPath}", f"--data={fncPath}"] ) assert nwGUI.closeMain() == "closeMain" assert ex.value.code == 0 with pytest.raises(SystemExit) as ex: - nwGUI = novelwriter.main( - ["--testmode", "--version", f"--config={tmpPath}", f"--data={tmpPath}"] + nwGUI = main( + ["--testmode", "--version", f"--config={fncPath}", f"--data={fncPath}"] ) assert nwGUI.closeMain() == "closeMain" assert ex.value.code == 0 # Invalid options with pytest.raises(SystemExit) as ex: - nwGUI = novelwriter.main( - ["--testmode", "--invalid", f"--config={tmpPath}", f"--data={tmpPath}"] + nwGUI = main( + ["--testmode", "--invalid", f"--config={fncPath}", f"--data={fncPath}"] ) assert nwGUI.closeMain() == "closeMain" assert ex.value.code == 2 # Project Path - nwGUI = novelwriter.main( - ["--testmode", f"--config={tmpPath}", f"--data={tmpPath}", "sample/"] + nwGUI = main( + ["--testmode", f"--config={fncPath}", f"--data={fncPath}", "sample/"] ) assert nwGUI.closeMain() == "closeMain" @@ -144,7 +145,7 @@ def testBaseInit_Options(monkeypatch, tmpPath): @pytest.mark.base -def testBaseInit_Imports(caplog, monkeypatch, tmpPath): +def testBaseInit_Imports(caplog, monkeypatch, fncPath): """Check import error handling. """ monkeypatch.setattr("novelwriter.guimain.GuiMain", MockGuiMain) @@ -159,8 +160,8 @@ def testBaseInit_Imports(caplog, monkeypatch, tmpPath): monkeypatch.setattr("novelwriter.CONFIG.verPyQtValue", 0x050000) with pytest.raises(SystemExit) as ex: - _ = novelwriter.main( - ["--testmode", f"--config={tmpPath}", f"--data={tmpPath}"] + _ = main( + ["--testmode", f"--config={fncPath}", f"--data={fncPath}"] ) assert ex.value.code & 4 == 4 # Python version not satisfied diff --git a/tests/test_core/test_core_coretools.py b/tests/test_core/test_core_coretools.py index d3789b80..585a9fae 100644 --- a/tests/test_core/test_core_coretools.py +++ b/tests/test_core/test_core_coretools.py @@ -28,6 +28,7 @@ from zipfile import ZipFile from mock import causeOSError from tools import C, buildTestProject, cmpFiles, XML_IGNORE +from novelwriter import CONFIG from novelwriter.constants import nwItemClass from novelwriter.core.project import NWProject from novelwriter.core.coretools import DocMerger, DocSplitter, ProjectBuilder @@ -371,7 +372,7 @@ def testCoreTools_NewCustomB(monkeypatch, fncPath, tstPaths, mockGUI, mockRnd): @pytest.mark.core -def testCoreTools_NewSample(monkeypatch, fncPath, tmpConf, tmpPath, mockGUI): +def testCoreTools_NewSample(monkeypatch, fncPath, tstPaths, mockGUI): """Check that we can create a new project can be created from the provided sample project via a zip file. """ @@ -391,10 +392,10 @@ def testCoreTools_NewSample(monkeypatch, fncPath, tmpConf, tmpPath, mockGUI): assert projBuild.buildProject({"popSample": True}) is False # Force the lookup path for assets to our temp folder - srcSample = tmpConf._appRoot / "sample" - dstSample = tmpPath / "sample.zip" + srcSample = CONFIG._appRoot / "sample" + dstSample = tstPaths.tmpDir / "sample.zip" monkeypatch.setattr( - "novelwriter.config.Config.assetPath", lambda *a: tmpPath / "sample.zip" + "novelwriter.config.Config.assetPath", lambda *a: tstPaths.tmpDir / "sample.zip" ) # Cannot extract when the zip does not exist diff --git a/tests/test_core/test_core_project.py b/tests/test_core/test_core_project.py index eee8e2ba..6425e4d8 100644 --- a/tests/test_core/test_core_project.py +++ b/tests/test_core/test_core_project.py @@ -29,6 +29,7 @@ from zipfile import ZipFile from mock import causeOSError from tools import C, cmpFiles, writeFile, buildTestProject, XML_IGNORE +from novelwriter import CONFIG from novelwriter.enum import nwItemClass, nwItemType, nwItemLayout from novelwriter.common import formatTimeStamp from novelwriter.constants import nwFiles @@ -704,7 +705,7 @@ def testCoreProject_OrphanedFiles(mockGUI, prjLipsum): @pytest.mark.core -def testCoreProject_Backup(monkeypatch, mockGUI, fncPath, tmpPath): +def testCoreProject_Backup(monkeypatch, mockGUI, fncPath, tstPaths): """Test the automated backup feature of the project class. The test creates a backup of the Minimal test project, and then unzips the backupd file and checks that the project XML file is identical to @@ -720,23 +721,18 @@ def testCoreProject_Backup(monkeypatch, mockGUI, fncPath, tmpPath): # Invalid Settings # ================ - # No project - mockGUI.hasProject = False - assert theProject.backupProject(doNotify=False) is False - mockGUI.hasProject = True - # Invalid path - theProject.mainConf._backupPath = None + CONFIG._backupPath = None assert theProject.backupProject(doNotify=False) is False # Missing project name - theProject.mainConf._backupPath = tmpPath + CONFIG._backupPath = tstPaths.tmpDir theProject.data.setName("") assert theProject.backupProject(doNotify=False) is False # Valid Settings # ============== - theProject.mainConf._backupPath = tmpPath + CONFIG._backupPath = tstPaths.tmpDir theProject.data.setName("Test Minimal") # Can't make folder @@ -752,7 +748,7 @@ def testCoreProject_Backup(monkeypatch, mockGUI, fncPath, tmpPath): # Test correct settings assert theProject.backupProject(doNotify=True) is True - theFiles = list((tmpPath / "Test Minimal").iterdir()) + theFiles = list((tstPaths.tmpDir / "Test Minimal").iterdir()) assert len(theFiles) == 1 theZip = theFiles[0].name @@ -760,13 +756,13 @@ def testCoreProject_Backup(monkeypatch, mockGUI, fncPath, tmpPath): assert theZip[-4:] == ".zip" # Extract the archive - with ZipFile(tmpPath / "Test Minimal" / theZip, mode="r") as inZip: - inZip.extractall(tmpPath / "extract") + with ZipFile(tstPaths.tmpDir / "Test Minimal" / theZip, mode="r") as inZip: + inZip.extractall(tstPaths.tmpDir / "extract") # Check that the main project file was restored assert cmpFiles( fncPath / "nwProject.nwx", - tmpPath / "extract" / "nwProject.nwx" + tstPaths.tmpDir / "extract" / "nwProject.nwx" ) # END Test testCoreProject_Backup diff --git a/tests/test_core/test_core_projectxml.py b/tests/test_core/test_core_projectxml.py index 74c60c74..4d099632 100644 --- a/tests/test_core/test_core_projectxml.py +++ b/tests/test_core/test_core_projectxml.py @@ -40,8 +40,8 @@ class MockProject: @pytest.fixture(scope="function", autouse=True) def mockVersion(monkeypatch): - monkeypatch.setattr("novelwriter.__version__", "2.0-rc1") - monkeypatch.setattr("novelwriter.__hexversion__", "0x020000c1") + monkeypatch.setattr("novelwriter.core.projectxml.__version__", "2.0-rc1") + monkeypatch.setattr("novelwriter.core.projectxml.__hexversion__", "0x020000c1") return diff --git a/tests/test_core/test_core_storage.py b/tests/test_core/test_core_storage.py index 1a26ebef..fe1dedc4 100644 --- a/tests/test_core/test_core_storage.py +++ b/tests/test_core/test_core_storage.py @@ -25,6 +25,7 @@ import pytest from mock import causeOSError from tools import C, buildTestProject, writeFile +from novelwriter import CONFIG from novelwriter.constants import nwFiles from novelwriter.core.project import NWProject from novelwriter.core.storage import NWStorage @@ -148,9 +149,9 @@ def testCoreStorage_LockFile(monkeypatch, fncPath): # Successful read assert storage.readLockFile() == [ - storage.mainConf.hostName, - storage.mainConf.osType, - storage.mainConf.kernelVer, + CONFIG.hostName, + CONFIG.osType, + CONFIG.kernelVer, "1000", ] @@ -299,10 +300,10 @@ def testCoreStorage_PrepareStorage(monkeypatch, fncPath): @pytest.mark.core -def testCoreStorage_ZipIt(monkeypatch, mockGUI, fncPath, tmpPath, mockRnd): +def testCoreStorage_ZipIt(monkeypatch, mockGUI, fncPath, tstPaths, mockRnd): """Test making a zip archive of a project. """ - zipFile = tmpPath / "project.zip" + zipFile = tstPaths.tmpDir / "project.zip" theProject = NWProject(mockGUI) storage = theProject.storage diff --git a/tests/test_core/test_core_tree.py b/tests/test_core/test_core_tree.py index 0a6ab099..80a6e7cc 100644 --- a/tests/test_core/test_core_tree.py +++ b/tests/test_core/test_core_tree.py @@ -437,7 +437,7 @@ def testCoreTree_Reorder(caplog, mockGUI, mockItems): @pytest.mark.core -def testCoreTree_ToCFile(monkeypatch, mockGUI, mockItems, tmpPath): +def testCoreTree_ToCFile(monkeypatch, tstPaths, mockGUI, mockItems): """Test writing the ToC.txt file. """ theProject = NWProject(mockGUI) @@ -463,20 +463,20 @@ def testCoreTree_ToCFile(monkeypatch, mockGUI, mockItems, tmpPath): theProject._storage._runtimePath = None assert theTree.writeToCFile() is False - theProject._storage._runtimePath = tmpPath + theProject._storage._runtimePath = tstPaths.tmpDir with monkeypatch.context() as mp: mp.setattr("builtins.open", causeOSError) assert theTree.writeToCFile() is False - theProject._storage._runtimePath = tmpPath - (tmpPath / "content").mkdir() + theProject._storage._runtimePath = tstPaths.tmpDir + (tstPaths.tmpDir / "content").mkdir() assert theTree.writeToCFile() is True pathA = str(Path("content") / "c000000000001.nwd") pathB = str(Path("content") / "c000000000002.nwd") pathC = str(Path("content") / "b000000000002.nwd") - assert readFile(tmpPath / nwFiles.TOC_TXT) == ( + assert readFile(tstPaths.tmpDir / nwFiles.TOC_TXT) == ( "\n" "Table of Contents\n" "=================\n" diff --git a/tests/test_dialogs/test_dlg_preferences.py b/tests/test_dialogs/test_dlg_preferences.py index ebe97b73..d42ba40f 100644 --- a/tests/test_dialogs/test_dlg_preferences.py +++ b/tests/test_dialogs/test_dlg_preferences.py @@ -30,6 +30,7 @@ from PyQt5.QtWidgets import ( QDialogButtonBox, QDialog, QAction, QFileDialog, QFontDialog ) +from novelwriter import CONFIG from novelwriter.dialogs.quotes import GuiQuoteSelect from novelwriter.dialogs.preferences import GuiPreferences @@ -37,12 +38,9 @@ KEY_DELAY = 1 @pytest.mark.gui -def testDlgPreferences_Main(qtbot, monkeypatch, nwGUI, fncPath, tstPaths): +def testDlgPreferences_Main(qtbot, monkeypatch, nwGUI, tstPaths): """Test the load project wizard. """ - theConf = nwGUI.mainConf - assert theConf._confPath == fncPath - monkeypatch.setattr(GuiPreferences, "exec_", lambda *a: None) monkeypatch.setattr(GuiPreferences, "result", lambda *a: QDialog.Accepted) monkeypatch.setattr(nwGUI.docEditor.spEnchant, "listDictionaries", lambda: [("en", "none")]) @@ -58,7 +56,6 @@ def testDlgPreferences_Main(qtbot, monkeypatch, nwGUI, fncPath, tstPaths): nwPrefs = getGuiItem("GuiPreferences") assert isinstance(nwPrefs, GuiPreferences) nwPrefs.show() - assert nwPrefs.mainConf._confPath == fncPath assert nwPrefs.updateTheme is False assert nwPrefs.updateSyntax is False @@ -215,8 +212,8 @@ def testDlgPreferences_Main(qtbot, monkeypatch, nwGUI, fncPath, tstPaths): qtbot.mouseClick(nwPrefs.buttonBox.button(QDialogButtonBox.Ok), Qt.LeftButton) nwPrefs._doClose() - assert nwGUI.mainConf.saveConfig() - projFile = fncPath / "novelwriter.conf" + assert CONFIG.saveConfig() + projFile = tstPaths.cnfDir / "novelwriter.conf" testFile = tstPaths.outDir / "guiPreferences_novelwriter.conf" compFile = tstPaths.refDir / "guiPreferences_novelwriter.conf" copyfile(projFile, testFile) diff --git a/tests/test_dialogs/test_dlg_projsettings.py b/tests/test_dialogs/test_dlg_projsettings.py index 8d933237..a2c36d2f 100644 --- a/tests/test_dialogs/test_dlg_projsettings.py +++ b/tests/test_dialogs/test_dlg_projsettings.py @@ -21,13 +21,14 @@ along with this program. If not, see . import pytest -from novelwriter.enum import nwItemType from tools import C, getGuiItem, buildTestProject from PyQt5.QtGui import QColor from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QDialog, QAction, QColorDialog +from novelwriter import CONFIG +from novelwriter.enum import nwItemType from novelwriter.dialogs.editlabel import GuiEditLabel from novelwriter.dialogs.projsettings import GuiProjectSettings @@ -91,7 +92,7 @@ def testDlgProjSettings_Main(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockR # Create new project buildTestProject(nwGUI, projPath) mockRnd.reset() - nwGUI.mainConf.backupPath = fncPath + CONFIG.setBackupPath(fncPath) # Set some values theProject = nwGUI.theProject @@ -156,7 +157,7 @@ def testDlgProjSettings_StatusImport(qtbot, monkeypatch, nwGUI, fncPath, projPat # Create new project mockRnd.reset() buildTestProject(nwGUI, projPath) - nwGUI.mainConf.backupPath = fncPath + CONFIG.setBackupPath(fncPath) # Set some values theProject = nwGUI.theProject @@ -357,7 +358,7 @@ def testDlgProjSettings_Replace(qtbot, monkeypatch, nwGUI, fncPath, projPath, mo # Create new project mockRnd.reset() buildTestProject(nwGUI, projPath) - nwGUI.mainConf.backupPath = fncPath + CONFIG.setBackupPath(fncPath) # Set some values theProject = nwGUI.theProject diff --git a/tests/test_gui/test_gui_doceditor.py b/tests/test_gui/test_gui_doceditor.py index 7497f950..cc386515 100644 --- a/tests/test_gui/test_gui_doceditor.py +++ b/tests/test_gui/test_gui_doceditor.py @@ -28,6 +28,7 @@ from PyQt5.QtCore import Qt from PyQt5.QtGui import QTextBlock, QTextCursor, QTextOption from PyQt5.QtWidgets import QAction, qApp +from novelwriter import CONFIG from novelwriter.enum import nwDocAction, nwDocInsert, nwItemLayout from novelwriter.constants import nwKeyWords, nwUnicode from novelwriter.core.index import countWords @@ -55,18 +56,18 @@ def testGuiEditor_Init(qtbot, nwGUI, projPath, ipsumText, mockRnd): assert nwGUI.docEditor._typPadChar == nwUnicode.U_NBSP # Check that editor handles settings - nwGUI.mainConf.textFont = None - nwGUI.mainConf.doJustify = True - nwGUI.mainConf.showTabsNSpaces = True - nwGUI.mainConf.showLineEndings = True - nwGUI.mainConf.hideVScroll = True - nwGUI.mainConf.hideHScroll = True - nwGUI.mainConf.fmtPadThin = True + CONFIG.textFont = None + CONFIG.doJustify = True + CONFIG.showTabsNSpaces = True + CONFIG.showLineEndings = True + CONFIG.hideVScroll = True + CONFIG.hideHScroll = True + CONFIG.fmtPadThin = True assert nwGUI.docEditor.initEditor() qDoc = nwGUI.docEditor.document() - assert nwGUI.mainConf.textFont == qDoc.defaultFont().family() + assert CONFIG.textFont == qDoc.defaultFont().family() assert qDoc.defaultTextOption().alignment() == Qt.AlignJustify assert qDoc.defaultTextOption().flags() & QTextOption.ShowTabsAndSpaces assert qDoc.defaultTextOption().flags() & QTextOption.ShowLineAndParagraphSeparators @@ -114,7 +115,7 @@ def testGuiEditor_LoadText(qtbot, monkeypatch, caplog, nwGUI, projPath, ipsumTex assert "The document you are trying to open is too big." in caplog.text # Big doc handling - nwGUI.mainConf.bigDocLimit = 50 + CONFIG.bigDocLimit = 50 assert nwGUI.docEditor.loadText(C.hSceneDoc) is True assert nwGUI.docEditor._bigDoc is True diff --git a/tests/test_gui/test_gui_docviewer.py b/tests/test_gui/test_gui_docviewer.py index 14cf66d0..2bd7ad7a 100644 --- a/tests/test_gui/test_gui_docviewer.py +++ b/tests/test_gui/test_gui_docviewer.py @@ -21,11 +21,13 @@ along with this program. If not, see . import pytest +from mock import causeException + from PyQt5.QtCore import Qt, QUrl from PyQt5.QtGui import QTextCursor from PyQt5.QtWidgets import qApp, QAction -from mock import causeException +from novelwriter import CONFIG from novelwriter.enum import nwDocAction from novelwriter.core.tohtml import ToHtml @@ -134,10 +136,10 @@ def testGuiViewer_Main(qtbot, monkeypatch, nwGUI, nwLipsum): assert nwGUI.docViewer.docHeader.theTitle.text() == "Characters › Test Title" # Ttile without full path - nwGUI.mainConf.showFullPath = False + CONFIG.showFullPath = False nwGUI.docViewer.updateDocInfo("4c4f28287af27") assert nwGUI.docViewer.docHeader.theTitle.text() == "Test Title" - nwGUI.mainConf.showFullPath = True + CONFIG.showFullPath = True # Document footer show/hide references viewState = nwGUI.viewMeta.isVisible() diff --git a/tests/test_gui/test_gui_guimain.py b/tests/test_gui/test_gui_guimain.py index e6a5256e..f5b9ecc6 100644 --- a/tests/test_gui/test_gui_guimain.py +++ b/tests/test_gui/test_gui_guimain.py @@ -30,6 +30,7 @@ from tools import ( from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QDialog, QMessageBox, QInputDialog +from novelwriter import CONFIG from novelwriter.enum import nwItemType, nwView, nwWidget from novelwriter.constants import nwFiles from novelwriter.gui.outline import GuiOutlineView @@ -75,7 +76,7 @@ def testGuiMain_Launch(qtbot, monkeypatch, nwGUI, prjLipsum): """ monkeypatch.setattr(GuiProjectLoad, "exec_", lambda *a: None) monkeypatch.setattr(GuiProjectLoad, "result", lambda *a: QDialog.Accepted) - nwGUI.mainConf.lastNotes = "0x0" + CONFIG.lastNotes = "0x0" # Open Lipsum project nwGUI.postLaunchTasks(prjLipsum) @@ -244,10 +245,10 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd): assert nwGUI.mainMenu._toggleSpellCheck() # Change some settings - nwGUI.mainConf.hideHScroll = True - nwGUI.mainConf.hideVScroll = True - nwGUI.mainConf.autoScrollPos = 80 - nwGUI.mainConf.autoScroll = True + CONFIG.hideHScroll = True + CONFIG.hideVScroll = True + CONFIG.autoScrollPos = 80 + CONFIG.autoScroll = True # Add a Character File nwGUI.switchFocus(nwWidget.TREE) @@ -589,11 +590,11 @@ def testGuiMain_FocusFullMode(qtbot, nwGUI, projPath, mockRnd): # Full Screen Mode # ================ - assert nwGUI.mainConf.isFullScreen is False + assert CONFIG.isFullScreen is False nwGUI.toggleFullScreenMode() - assert nwGUI.mainConf.isFullScreen is True + assert CONFIG.isFullScreen is True nwGUI.toggleFullScreenMode() - assert nwGUI.mainConf.isFullScreen is False + assert CONFIG.isFullScreen is False # qtbot.stop() diff --git a/tests/test_gui/test_gui_i18n.py b/tests/test_gui/test_gui_i18n.py index b514001c..8c9cb849 100644 --- a/tests/test_gui/test_gui_i18n.py +++ b/tests/test_gui/test_gui_i18n.py @@ -20,20 +20,20 @@ along with this program. If not, see . """ import sys -import novelwriter - import pytest from PyQt5.QtWidgets import qApp, QMessageBox -LANG_DATA = novelwriter.CONFIG.listLanguages(novelwriter.CONFIG.LANG_NW) +from novelwriter import CONFIG, main + +LANG_DATA = CONFIG.listLanguages(CONFIG.LANG_NW) @pytest.mark.gui @pytest.mark.skipif(not sys.platform.startswith("linux"), reason="Linux Only") @pytest.mark.skipif(not LANG_DATA, reason="No i18n Data") @pytest.mark.parametrize("language", [a for a, b in LANG_DATA]) -def testI18n_Localisation(qtbot, monkeypatch, language, fncPath, fncConf): +def testI18n_Localisation(qtbot, monkeypatch, language, fncPath): """test loading the gui with a specific language. """ monkeypatch.setattr(QMessageBox, "warning", lambda *a: QMessageBox.Ok) @@ -42,18 +42,13 @@ def testI18n_Localisation(qtbot, monkeypatch, language, fncPath, fncConf): monkeypatch.setattr(QMessageBox, "question", lambda *a: QMessageBox.Yes) # Set the test langauge - monkeypatch.setattr("novelwriter.CONFIG", fncConf) - fncConf.guiLocale = language - fncConf.initLocalisation(qApp) + CONFIG.guiLocale = language + CONFIG.initLocalisation(qApp) - nwGUI = novelwriter.main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"]) + nwGUI = main(["--testmode", f"--config={fncPath}", f"--data={fncPath}"]) qtbot.addWidget(nwGUI) nwGUI.show() qtbot.wait(20) nwGUI.closeMain() - # Reset the app language - fncConf.guiLocale = "en_GB" - fncConf.initLocalisation(qApp) - # END Test testI18n_Localisation diff --git a/tests/test_gui/test_gui_mainmenu.py b/tests/test_gui/test_gui_mainmenu.py index 92a820a0..3c7cc565 100644 --- a/tests/test_gui/test_gui_mainmenu.py +++ b/tests/test_gui/test_gui_mainmenu.py @@ -27,6 +27,7 @@ from PyQt5.QtWidgets import QAction, QFileDialog, QMessageBox from tools import C, writeFile, buildTestProject +from novelwriter import CONFIG from novelwriter.enum import nwDocAction, nwDocInsert from novelwriter.constants import nwKeyWords, nwUnicode from novelwriter.gui.doceditor import GuiDocEditor @@ -461,19 +462,19 @@ def testGuiMenu_Insert(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockRnd): nwGUI.docEditor.clear() nwGUI.mainMenu.aInsQuoteLS.activate(QAction.Trigger) - assert nwGUI.docEditor.getText() == nwGUI.mainConf.fmtSQuoteOpen + assert nwGUI.docEditor.getText() == CONFIG.fmtSQuoteOpen nwGUI.docEditor.clear() nwGUI.mainMenu.aInsQuoteRS.activate(QAction.Trigger) - assert nwGUI.docEditor.getText() == nwGUI.mainConf.fmtSQuoteClose + assert nwGUI.docEditor.getText() == CONFIG.fmtSQuoteClose nwGUI.docEditor.clear() nwGUI.mainMenu.aInsQuoteLD.activate(QAction.Trigger) - assert nwGUI.docEditor.getText() == nwGUI.mainConf.fmtDQuoteOpen + assert nwGUI.docEditor.getText() == CONFIG.fmtDQuoteOpen nwGUI.docEditor.clear() nwGUI.mainMenu.aInsQuoteRD.activate(QAction.Trigger) - assert nwGUI.docEditor.getText() == nwGUI.mainConf.fmtDQuoteClose + assert nwGUI.docEditor.getText() == CONFIG.fmtDQuoteClose nwGUI.docEditor.clear() nwGUI.mainMenu.aInsMSApos.activate(QAction.Trigger) diff --git a/tests/test_gui/test_gui_noveltree.py b/tests/test_gui/test_gui_noveltree.py index e74e4ebb..79497f57 100644 --- a/tests/test_gui/test_gui_noveltree.py +++ b/tests/test_gui/test_gui_noveltree.py @@ -29,6 +29,7 @@ from PyQt5.QtGui import QFocusEvent from PyQt5.QtCore import Qt, QEvent from PyQt5.QtWidgets import QInputDialog, QToolTip +from novelwriter import CONFIG from novelwriter.enum import nwWidget, nwItemType from novelwriter.gui.noveltree import NovelTreeColumn from novelwriter.dialogs.editlabel import GuiEditLabel @@ -67,14 +68,14 @@ def testGuiNovelTree_TreeItems(qtbot, monkeypatch, nwGUI, projPath, mockRnd): # Show/Hide Scrollbars # ==================== - nwGUI.mainConf.hideVScroll = True - nwGUI.mainConf.hideHScroll = True + CONFIG.hideVScroll = True + CONFIG.hideHScroll = True novelView.initSettings() assert not novelTree.verticalScrollBar().isVisible() assert not novelTree.horizontalScrollBar().isVisible() - nwGUI.mainConf.hideVScroll = False - nwGUI.mainConf.hideHScroll = False + CONFIG.hideVScroll = False + CONFIG.hideHScroll = False novelView.initSettings() assert novelTree.verticalScrollBar().isEnabled() assert novelTree.horizontalScrollBar().isEnabled() diff --git a/tests/test_gui/test_gui_outline.py b/tests/test_gui/test_gui_outline.py index 7b5bbfc6..533a5c52 100644 --- a/tests/test_gui/test_gui_outline.py +++ b/tests/test_gui/test_gui_outline.py @@ -28,6 +28,7 @@ from tools import buildTestProject, writeFile from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QWidget, QAction +from novelwriter import CONFIG from novelwriter.enum import nwItemClass, nwOutline, nwView @@ -47,16 +48,16 @@ def testGuiOutline_Main(qtbot, monkeypatch, nwGUI, projPath): outlineMenu = outlineView.outlineBar.mColumns # Toggle scrollbars - nwGUI.mainConf.hideVScroll = True - nwGUI.mainConf.hideHScroll = True + CONFIG.hideVScroll = True + CONFIG.hideHScroll = True outlineView.initSettings() assert outlineTree.verticalScrollBarPolicy() == Qt.ScrollBarAlwaysOff assert outlineTree.horizontalScrollBarPolicy() == Qt.ScrollBarAlwaysOff assert outlineData.verticalScrollBarPolicy() == Qt.ScrollBarAlwaysOff assert outlineData.horizontalScrollBarPolicy() == Qt.ScrollBarAlwaysOff - nwGUI.mainConf.hideVScroll = False - nwGUI.mainConf.hideHScroll = False + CONFIG.hideVScroll = False + CONFIG.hideHScroll = False outlineView.initSettings() assert outlineTree.verticalScrollBarPolicy() == Qt.ScrollBarAsNeeded assert outlineTree.horizontalScrollBarPolicy() == Qt.ScrollBarAsNeeded diff --git a/tests/test_gui/test_gui_projtree.py b/tests/test_gui/test_gui_projtree.py index cf1a4ab2..dbaeb09f 100644 --- a/tests/test_gui/test_gui_projtree.py +++ b/tests/test_gui/test_gui_projtree.py @@ -27,6 +27,7 @@ from tools import C, buildTestProject from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QMessageBox, QMenu, QTreeWidgetItem, QDialog +from novelwriter import CONFIG from novelwriter.enum import nwItemLayout, nwItemType, nwItemClass from novelwriter.gui.projtree import GuiProjectTree from novelwriter.dialogs.docmerge import GuiDocMerge @@ -862,14 +863,14 @@ def testGuiProjTree_Other(qtbot, monkeypatch, nwGUI, projPath, mockRnd): # ==================== # Test that the scrollbar setting works - nwGUI.mainConf.hideVScroll = True - nwGUI.mainConf.hideHScroll = True + CONFIG.hideVScroll = True + CONFIG.hideHScroll = True projView.initSettings() assert projTree.verticalScrollBarPolicy() == Qt.ScrollBarAlwaysOff assert projTree.horizontalScrollBarPolicy() == Qt.ScrollBarAlwaysOff - nwGUI.mainConf.hideVScroll = False - nwGUI.mainConf.hideHScroll = False + CONFIG.hideVScroll = False + CONFIG.hideHScroll = False projView.initSettings() assert projTree.verticalScrollBarPolicy() == Qt.ScrollBarAsNeeded assert projTree.horizontalScrollBarPolicy() == Qt.ScrollBarAsNeeded diff --git a/tests/test_gui/test_gui_statusbar.py b/tests/test_gui/test_gui_statusbar.py index f0a3ce9f..b19afa45 100644 --- a/tests/test_gui/test_gui_statusbar.py +++ b/tests/test_gui/test_gui_statusbar.py @@ -24,6 +24,7 @@ import pytest from tools import C, buildTestProject +from novelwriter import CONFIG from novelwriter.gui.statusbar import StatusLED @@ -60,13 +61,13 @@ def testGuiStatusBar_Main(qtbot, nwGUI, projPath, mockRnd): assert nwGUI.mainStatus.docIcon._theCol == nwGUI.mainStatus.docIcon._colGood # Idle Status - nwGUI.mainStatus.mainConf.stopWhenIdle = False + CONFIG.stopWhenIdle = False nwGUI.mainStatus.setUserIdle(True) nwGUI.mainStatus.updateTime() assert nwGUI.mainStatus.userIdle is False assert nwGUI.mainStatus.timeText.text() == "00:00:00" - nwGUI.mainStatus.mainConf.stopWhenIdle = True + CONFIG.stopWhenIdle = True nwGUI.mainStatus.setUserIdle(True) nwGUI.mainStatus.updateTime(5) assert nwGUI.mainStatus.userIdle is True @@ -84,10 +85,10 @@ def testGuiStatusBar_Main(qtbot, nwGUI, projPath, mockRnd): assert nwGUI.mainStatus.langText.text() == "American English" # Project Stats - nwGUI.mainStatus.mainConf.incNotesWCount = False + CONFIG.incNotesWCount = False nwGUI._updateStatusWordCount() assert nwGUI.mainStatus.statsText.text() == "Words: 9 (+9)" - nwGUI.mainStatus.mainConf.incNotesWCount = True + CONFIG.incNotesWCount = True nwGUI._updateStatusWordCount() assert nwGUI.mainStatus.statsText.text() == "Words: 11 (+11)" diff --git a/tests/test_gui/test_gui_theme.py b/tests/test_gui/test_gui_theme.py index 9899c1c1..a4aa6b2a 100644 --- a/tests/test_gui/test_gui_theme.py +++ b/tests/test_gui/test_gui_theme.py @@ -19,7 +19,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import shutil import pytest from pathlib import Path @@ -31,18 +30,17 @@ from tools import writeFile from PyQt5.QtGui import QIcon, QPalette, QPixmap from PyQt5.QtWidgets import QApplication +from novelwriter import CONFIG from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType -from novelwriter.config import Config from novelwriter.constants import nwLabels from novelwriter.gui.theme import GuiIcons, GuiTheme @pytest.mark.gui -def testGuiTheme_Main(qtbot, nwGUI, fncPath): +def testGuiTheme_Main(qtbot, nwGUI, tstPaths): """Test the theme class init. """ mainTheme: GuiTheme = nwGUI.mainTheme - mainConf: Config = nwGUI.mainConf # Methods # ======= @@ -55,35 +53,35 @@ def testGuiTheme_Main(qtbot, nwGUI, fncPath): # ========== # The defaults should be set - defaultFont = mainConf.guiFont - defaultSize = mainConf.guiFontSize + defaultFont = CONFIG.guiFont + defaultSize = CONFIG.guiFontSize # CHange them to nonsense values - mainConf.guiFont = "notafont" - mainConf.guiFontSize = 99 + CONFIG.guiFont = "notafont" + CONFIG.guiFontSize = 99 # Let the theme class set them back to default mainTheme._setGuiFont() - assert mainConf.guiFont == defaultFont - assert mainConf.guiFontSize == defaultSize + assert CONFIG.guiFont == defaultFont + assert CONFIG.guiFontSize == defaultSize # A second call should just restore the defaults again mainTheme._setGuiFont() - assert mainConf.guiFont == defaultFont - assert mainConf.guiFontSize == defaultSize + assert CONFIG.guiFont == defaultFont + assert CONFIG.guiFontSize == defaultSize # Scan for Themes # =============== assert mainTheme._listConf({}, Path("not_a_path")) is False - themeOne = fncPath / "themes" / "themeone.conf" - themeTwo = fncPath / "themes" / "themetwo.conf" + themeOne = tstPaths.cnfDir / "themes" / "themeone.conf" + themeTwo = tstPaths.cnfDir / "themes" / "themetwo.conf" writeFile(themeOne, "# Stuff") writeFile(themeTwo, "# Stuff") result = {} - assert mainTheme._listConf(result, fncPath / "themes") is True + assert mainTheme._listConf(result, tstPaths.cnfDir / "themes") is True assert result["themeone"] == themeOne assert result["themetwo"] == themeTwo @@ -123,18 +121,14 @@ def testGuiTheme_Main(qtbot, nwGUI, fncPath): @pytest.mark.gui -def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI, fncPath): +def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI): """Test the theme part of the class. """ mainTheme: GuiTheme = nwGUI.mainTheme - mainConf: Config = nwGUI.mainConf # List Themes # =========== - shutil.copy(mainConf.assetPath("themes") / "default_dark.conf", fncPath / "themes") - shutil.copy(mainConf.assetPath("themes") / "default.conf", fncPath / "themes") - # Block the reading of the files with monkeypatch.context() as mp: mp.setattr("builtins.open", causeOSError) @@ -149,14 +143,14 @@ def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI, fncPath): assert mainTheme.listThemes() == mainTheme._themeList # Check handling of broken theme settings - mainConf.guiTheme = "not_a_theme" + CONFIG.guiTheme = "not_a_theme" availThemes = mainTheme._availThemes mainTheme._availThemes = {} assert mainTheme.loadTheme() is False mainTheme._availThemes = availThemes # Check handling of unreadable file - mainConf.guiTheme = "default" + CONFIG.guiTheme = "default" with monkeypatch.context() as mp: mp.setattr("builtins.open", causeOSError) assert mainTheme.loadTheme() is False @@ -168,7 +162,7 @@ def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI, fncPath): mainTheme._guiPalette.color(QPalette.Window).setRgb(0, 0, 0, 0) # Load the default theme - mainConf.guiTheme = "default" + CONFIG.guiTheme = "default" assert mainTheme.loadTheme() is True # This should load a standard palette @@ -178,7 +172,7 @@ def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI, fncPath): # Load Default Dark Theme # ======================= - mainConf.guiTheme = "default_dark" + CONFIG.guiTheme = "default_dark" assert mainTheme.loadTheme() is True # Check a few values @@ -193,18 +187,14 @@ def testGuiTheme_Theme(qtbot, monkeypatch, nwGUI, fncPath): @pytest.mark.gui -def testGuiTheme_Syntax(qtbot, monkeypatch, nwGUI, fncPath): +def testGuiTheme_Syntax(qtbot, monkeypatch, nwGUI): """Test the syntax part of the class. """ mainTheme: GuiTheme = nwGUI.mainTheme - mainConf: Config = nwGUI.mainConf # List Themes # =========== - shutil.copy(mainConf.assetPath("syntax") / "default_dark.conf", fncPath / "syntax") - shutil.copy(mainConf.assetPath("syntax") / "default_light.conf", fncPath / "syntax") - # Block the reading of the files with monkeypatch.context() as mp: mp.setattr("builtins.open", causeOSError) @@ -221,12 +211,12 @@ def testGuiTheme_Syntax(qtbot, monkeypatch, nwGUI, fncPath): # Check handling of broken theme settings availSyntax = mainTheme._availSyntax mainTheme._availSyntax = {} - mainConf.guiSyntax = "not_a_syntax" + CONFIG.guiSyntax = "not_a_syntax" assert mainTheme.loadSyntax() is False mainTheme._availSyntax = availSyntax # Check handling of unreadable file - mainConf.guiSyntax = "default_light" + CONFIG.guiSyntax = "default_light" with monkeypatch.context() as mp: mp.setattr("builtins.open", causeOSError) assert mainTheme.loadSyntax() is False @@ -235,7 +225,7 @@ def testGuiTheme_Syntax(qtbot, monkeypatch, nwGUI, fncPath): # ========================= # Load the default syntax - mainConf.guiSyntax = "default_light" + CONFIG.guiSyntax = "default_light" assert mainTheme.loadSyntax() is True # Check some values @@ -248,7 +238,7 @@ def testGuiTheme_Syntax(qtbot, monkeypatch, nwGUI, fncPath): # ======================= # Load the default syntax - mainConf.guiSyntax = "default_dark" + CONFIG.guiSyntax = "default_dark" assert mainTheme.loadSyntax() is True # Check some values @@ -263,7 +253,7 @@ def testGuiTheme_Syntax(qtbot, monkeypatch, nwGUI, fncPath): @pytest.mark.gui -def testGuiTheme_Icons(qtbot, caplog, monkeypatch, nwGUI, fncPath): +def testGuiTheme_Icons(qtbot, caplog, monkeypatch, nwGUI, tstPaths): """Test the icon cache class. """ iconCache: GuiIcons = nwGUI.mainTheme.iconCache @@ -280,7 +270,7 @@ def testGuiTheme_Icons(qtbot, caplog, monkeypatch, nwGUI, fncPath): assert iconCache.loadTheme("typicons_dark") is False # Load a broken theme file - iconsDir = fncPath / "icons" + iconsDir = tstPaths.cnfDir / "icons" testIcons = iconsDir / "testicons" testIcons.mkdir() writeFile(testIcons / "icons.conf", ( @@ -293,7 +283,7 @@ def testGuiTheme_Icons(qtbot, caplog, monkeypatch, nwGUI, fncPath): )) iconPath = iconCache._iconPath - iconCache._iconPath = fncPath / "icons" + iconCache._iconPath = tstPaths.cnfDir / "icons" caplog.clear() assert iconCache.loadTheme("testicons") is True diff --git a/tests/test_tools/test_tools_build.py b/tests/test_tools/test_tools_build.py index e8dd5dce..5099c168 100644 --- a/tests/test_tools/test_tools_build.py +++ b/tests/test_tools/test_tools_build.py @@ -28,6 +28,7 @@ from tools import ODT_IGNORE, cmpFiles, getGuiItem from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QAction, QFileDialog +from novelwriter import CONFIG from novelwriter.tools.build import GuiBuildNovel @@ -67,7 +68,7 @@ def testToolBuild_Main(qtbot, monkeypatch, nwGUI, prjLipsum, tstPaths): assert not nwBuild._saveDocument(nwBuild.FMT_NWD) # Default Settings - nwGUI.mainConf._lastPath = prjLipsum + CONFIG._lastPath = prjLipsum qtbot.mouseClick(nwBuild.buildNovel, Qt.LeftButton) assert nwBuild._saveDocument(nwBuild.FMT_NWD) @@ -231,7 +232,7 @@ def testToolBuild_Main(qtbot, monkeypatch, nwGUI, prjLipsum, tstPaths): assert (prjLipsum / "Lorem Ipsum.odt").is_file() # Print to PDF - if not nwGUI.mainConf.osDarwin: + if not CONFIG.osDarwin: assert nwBuild._saveDocument(nwBuild.FMT_PDF) assert (prjLipsum / "Lorem Ipsum.pdf").is_file() diff --git a/tests/test_tools/test_tools_writingstats.py b/tests/test_tools/test_tools_writingstats.py index 895635fd..7cf832f6 100644 --- a/tests/test_tools/test_tools_writingstats.py +++ b/tests/test_tools/test_tools_writingstats.py @@ -33,7 +33,7 @@ from novelwriter.tools.writingstats import GuiWritingStats @pytest.mark.gui -def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, fncPath, projPath): +def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, projPath, tstPaths): """Test the full writing stats tool. """ # Create a project to work on @@ -126,13 +126,10 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, fncPath, projPath): assert sessLog.listBox.topLevelItem(7).text(sessLog.C_COUNT) == "{:n}".format(200) assert sessLog._saveData(sessLog.FMT_CSV) - qtbot.wait(100) - assert sessLog._saveData(sessLog.FMT_JSON) - qtbot.wait(100) # Check the exported files - jsonStats = fncPath / "sessionStats.json" + jsonStats = tstPaths.tmpDir / "sessionStats.json" with open(jsonStats, mode="r", encoding="utf-8") as inFile: jsonData = json.load(inFile) @@ -171,7 +168,7 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, fncPath, projPath): qtbot.mouseClick(sessLog.incNovel, Qt.LeftButton) assert sessLog._saveData(sessLog.FMT_JSON) - jsonStats = fncPath / "sessionStats.json" + jsonStats = tstPaths.tmpDir / "sessionStats.json" with open(jsonStats, mode="r", encoding="utf-8") as inFile: jsonData = json.loads(inFile.read()) @@ -217,7 +214,7 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, fncPath, projPath): qtbot.mouseClick(sessLog.incNotes, Qt.LeftButton) assert sessLog._saveData(sessLog.FMT_JSON) - jsonStats = fncPath / "sessionStats.json" + jsonStats = tstPaths.tmpDir / "sessionStats.json" with open(jsonStats, mode="r", encoding="utf-8") as inFile: jsonData = json.load(inFile) @@ -265,7 +262,7 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, fncPath, projPath): # qtbot.stop() - jsonStats = fncPath / "sessionStats.json" + jsonStats = tstPaths.tmpDir / "sessionStats.json" with open(jsonStats, mode="r", encoding="utf-8") as inFile: jsonData = json.load(inFile) @@ -295,7 +292,7 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, fncPath, projPath): qtbot.mouseClick(sessLog.hideZeros, Qt.LeftButton) assert sessLog._saveData(sessLog.FMT_JSON) - jsonStats = fncPath / "sessionStats.json" + jsonStats = tstPaths.tmpDir / "sessionStats.json" with open(jsonStats, mode="r", encoding="utf-8") as inFile: jsonData = json.load(inFile) @@ -348,7 +345,7 @@ def testToolWritingStats_Main(qtbot, monkeypatch, nwGUI, fncPath, projPath): qtbot.mouseClick(sessLog.groupByDay, Qt.LeftButton) assert sessLog._saveData(sessLog.FMT_JSON) - jsonStats = fncPath / "sessionStats.json" + jsonStats = tstPaths.tmpDir / "sessionStats.json" with open(jsonStats, mode="r", encoding="utf-8") as inFile: jsonData = json.load(inFile)