diff --git a/nw/common.py b/nw/common.py index d5563d16..47e86ff6 100644 --- a/nw/common.py +++ b/nw/common.py @@ -165,9 +165,9 @@ def formatTimeStamp(theTime, fileSafe=False): it to a timestamp string. """ if fileSafe: - return datetime.fromtimestamp(theTime).strftime(nwConst.fStampFmt) + return datetime.fromtimestamp(theTime).strftime(nwConst.FMT_FSTAMP) else: - return datetime.fromtimestamp(theTime).strftime(nwConst.tStampFmt) + return datetime.fromtimestamp(theTime).strftime(nwConst.FMT_TSTAMP) def formatTime(tS): """Format a time in seconds in HH:MM:SS format or d-HH:MM:SS format diff --git a/nw/config.py b/nw/config.py index a82c133b..05345b45 100644 --- a/nw/config.py +++ b/nw/config.py @@ -37,7 +37,7 @@ from shutil import which from PyQt5.Qt import PYQT_VERSION_STR from PyQt5.QtCore import QT_VERSION_STR, QStandardPaths, QSysInfo -from nw.constants import nwFiles, nwUnicode +from nw.constants import nwConst, nwFiles, nwUnicode from nw.common import splitVersionNumber, formatTimeStamp logger = logging.getLogger(__name__) @@ -88,14 +88,14 @@ class Config: self.guiIcons = "typicons_colour_light" self.guiDark = False # Load icons for dark backgrounds, if available self.guiLang = "en" # Hardcoded for now since the GUI is only in English - self.guiFont = "" # Defaults to system defualt font + self.guiFont = "" # Defaults to system default font self.guiFontSize = 11 self.guiScale = 1.0 # Set automatically by Theme class ## Sizes - self.winGeometry = [1100, 650] - self.treeColWidth = [120, 30, 50] - self.projColWidth = [140, 55, 140] + self.winGeometry = [1200, 650] + self.treeColWidth = [200, 50, 30] + self.projColWidth = [200, 60, 140] self.mainPanePos = [300, 800] self.docPanePos = [400, 400] self.viewPanePos = [500, 150] @@ -284,7 +284,7 @@ class Config: logger.verbose("App path: %s" % self.appPath) logger.verbose("Last path: %s" % self.lastPath) - # If config folder does not exist, make it. + # If config folder does not exist, create it. # This assumes that the os config folder itself exists. if not os.path.isdir(self.confPath): try: @@ -327,7 +327,7 @@ class Config: self._checkOptionalPackages() if self.spellTool is None: - self.spellTool = "internal" + self.spellTool = nwConst.SP_INTERNAL if self.spellLanguage is None: self.spellLanguage = "en" diff --git a/nw/constants/constants.py b/nw/constants/constants.py index e7549bb4..e237b662 100644 --- a/nw/constants/constants.py +++ b/nw/constants/constants.py @@ -29,13 +29,19 @@ from nw.constants.enum import nwItemClass, nwItemLayout, nwOutline class nwConst(): - tStampFmt = "%Y-%m-%d %H:%M:%S" # Default format - fStampFmt = "%Y-%m-%d %H.%M.%S" # FileName safe format - dStampFmt = "%Y-%m-%d" # Date only format + # Date and Time Formats + FMT_TSTAMP = "%Y-%m-%d %H:%M:%S" # Default format + FMT_FSTAMP = "%Y-%m-%d %H.%M.%S" # FileName safe format + FMT_DSTAMP = "%Y-%m-%d" # Date only format - maxDepth = 30 # Maximum folder depth of a project - maxDocSize = 5000000 # Maxium size of a single document - maxBuildSize = 10000000 # Maxium size of a project build + # Various Hard Limits + MAX_DEPTH = 30 # Maximum folder depth of a project + MAX_DOCSIZE = 5000000 # Maxium size of a single document + MAX_BUILDSIZE = 10000000 # Maxium size of a project build + + # Spell Check Providers + SP_INTERNAL = "internal" + SP_ENCHANT = "enchant" # END Class nwConst @@ -74,6 +80,24 @@ class nwKeyWords: ENTITY_KEY = "@entity" CUSTOM_KEY = "@custom" + # Set of Valid Keys + VALID_KEYS = { + TAG_KEY, POV_KEY, CHAR_KEY, PLOT_KEY, TIME_KEY, + WORLD_KEY, OBJECT_KEY, ENTITY_KEY, CUSTOM_KEY + } + + # Map from Keys to Item Class + KEY_CLASS = { + CHAR_KEY : nwItemClass.CHARACTER, + POV_KEY : nwItemClass.CHARACTER, + PLOT_KEY : nwItemClass.PLOT, + TIME_KEY : nwItemClass.TIMELINE, + WORLD_KEY : nwItemClass.WORLD, + OBJECT_KEY : nwItemClass.OBJECT, + ENTITY_KEY : nwItemClass.ENTITY, + CUSTOM_KEY : nwItemClass.CUSTOM, + } + # END Class nwKeyWords class nwLabels(): diff --git a/nw/core/document.py b/nw/core/document.py index 2e22e389..2597eac8 100644 --- a/nw/core/document.py +++ b/nw/core/document.py @@ -251,7 +251,7 @@ class NWDoc(): self._docMeta["layout"] = nwItemLayout[metaBits[1]] else: - logger.debug("Ignoring meta data: '%s'" % metaLine) + logger.debug("Ignoring meta data: '%s'" % metaLine.strip()) return diff --git a/nw/core/index.py b/nw/core/index.py index 29f80ea9..cb0ac376 100644 --- a/nw/core/index.py +++ b/nw/core/index.py @@ -42,28 +42,6 @@ logger = logging.getLogger(__name__) class NWIndex(): - VALID_KEYS = { - nwKeyWords.TAG_KEY, - nwKeyWords.PLOT_KEY, - nwKeyWords.POV_KEY, - nwKeyWords.CHAR_KEY, - nwKeyWords.WORLD_KEY, - nwKeyWords.TIME_KEY, - nwKeyWords.OBJECT_KEY, - nwKeyWords.ENTITY_KEY, - nwKeyWords.CUSTOM_KEY - } - TAG_CLASS = { - nwKeyWords.CHAR_KEY : nwItemClass.CHARACTER, - nwKeyWords.POV_KEY : nwItemClass.CHARACTER, - nwKeyWords.PLOT_KEY : nwItemClass.PLOT, - nwKeyWords.TIME_KEY : nwItemClass.TIMELINE, - nwKeyWords.WORLD_KEY : nwItemClass.WORLD, - nwKeyWords.OBJECT_KEY : nwItemClass.OBJECT, - nwKeyWords.ENTITY_KEY : nwItemClass.ENTITY, - nwKeyWords.CUSTOM_KEY : nwItemClass.CUSTOM, - } - def __init__(self, theProject, theParent): # Internal @@ -530,7 +508,7 @@ class NWIndex(): return [] # Check that the key is valid - isGood[0] = theBits[0] in self.VALID_KEYS + isGood[0] = theBits[0] in nwKeyWords.VALID_KEYS if not isGood[0] or nBits == 1: return isGood @@ -550,7 +528,7 @@ class NWIndex(): # If we're still here, we better check that the references exist for n in range(1, nBits): if theBits[n] in self.tagIndex: - isGood[n] = self.TAG_CLASS[theBits[0]].name == self.tagIndex[theBits[n]][2] + isGood[n] = nwKeyWords.KEY_CLASS[theBits[0]].name == self.tagIndex[theBits[n]][2] return isGood @@ -608,7 +586,7 @@ class NWIndex(): section. sTitle must be a string. """ theRefs = {} - for tKey in self.TAG_CLASS: + for tKey in nwKeyWords.KEY_CLASS: theRefs[tKey] = [] if tHandle not in self.refIndex: diff --git a/nw/core/spellcheck.py b/nw/core/spellcheck.py index 7223c616..b2f92a96 100644 --- a/nw/core/spellcheck.py +++ b/nw/core/spellcheck.py @@ -31,7 +31,7 @@ import os from difflib import get_close_matches -from nw.constants import isoLanguage +from nw.constants import nwConst, isoLanguage logger = logging.getLogger(__name__) @@ -41,11 +41,8 @@ logger = logging.getLogger(__name__) class NWSpellCheck(): - SP_INTERNAL = "internal" - SP_ENCHANT = "enchant" - theDict = None - PROJW = [] + projDict = [] def __init__(self): self.mainConf = nw.CONFIG @@ -71,9 +68,9 @@ class NWSpellCheck(): def addWord(self, newWord): """Add a word to the project dictionary. """ - if self.projectDict is not None and newWord not in self.PROJW: + if self.projectDict is not None and newWord not in self.projDict: newWord = newWord.strip() - self.PROJW.append(newWord) + self.projDict.append(newWord) try: with open(self.projectDict, mode="a+", encoding="utf-8") as outFile: outFile.write("%s\n" % newWord) @@ -110,7 +107,7 @@ class NWSpellCheck(): """Read the content of the project dictionary, and add it to the lookup lists. """ - self.PROJW = [] + self.projDict = [] if projectDict is not None: self.projectDict = projectDict if not os.path.isfile(projectDict): @@ -120,9 +117,9 @@ class NWSpellCheck(): with open(projectDict, mode="r", encoding="utf-8") as wordsFile: for theLine in wordsFile: theLine = theLine.strip() - if len(theLine) > 0 and theLine not in self.PROJW: - self.PROJW.append(theLine) - logger.debug("Project word list contains %d words" % len(self.PROJW)) + if len(theLine) > 0 and theLine not in self.projDict: + self.projDict.append(theLine) + logger.debug("Project word list contains %d words" % len(self.projDict)) except Exception as e: logger.error("Failed to load project word list") logger.error(str(e)) @@ -157,7 +154,7 @@ class NWSpellEnchant(NWSpellCheck): self.spellLanguage = None self._readProjectDictionary(projectDict) - for pWord in self.PROJW: + for pWord in self.projDict: self.theDict.add_to_session(pWord) return @@ -236,7 +233,6 @@ class NWSpellSimple(NWSpellCheck): when no other is available. This method is fairly slow compared to other implementations. """ - WORDS = [] def __init__(self): @@ -266,7 +262,7 @@ class NWSpellSimple(NWSpellCheck): self.spellLanguage = None self._readProjectDictionary(projectDict) - for pWord in self.PROJW: + for pWord in self.projDict: if pWord not in self.WORDS: self.WORDS.append(pWord) @@ -324,7 +320,7 @@ class NWSpellSimple(NWSpellCheck): if theBits[1] != ".dict": continue - spName = "%s [internal]" % self.expandLanguage(theBits[0]) + spName = "%s [%s]" % (self.expandLanguage(theBits[0]), nwConst.SP_INTERNAL) retList.append((theBits[0], spName)) return retList @@ -333,6 +329,6 @@ class NWSpellSimple(NWSpellCheck): """Return the tag and provider of the currently loaded dictionary. """ - return self.theLang, "internal" + return self.theLang, nwConst.SP_INTERNAL # END Class NWSpellSimple diff --git a/nw/core/tokenizer.py b/nw/core/tokenizer.py index c7b23208..7870493c 100644 --- a/nw/core/tokenizer.py +++ b/nw/core/tokenizer.py @@ -216,7 +216,7 @@ class Tokenizer(): self.theText = theDocument.openDocument(theHandle) docSize = len(self.theText) - if docSize > nwConst.maxDocSize: + if docSize > nwConst.MAX_DOCSIZE: errVal = "Document '%s' is too big (%.2f MB). Skipping." % ( self.theItem.itemName, docSize/1.0e6 ) diff --git a/nw/core/tree.py b/nw/core/tree.py index fc908745..2973d462 100644 --- a/nw/core/tree.py +++ b/nw/core/tree.py @@ -260,7 +260,7 @@ class NWTree(): """ tItem = self.__getitem__(tHandle) if tItem is not None: - for i in range(nwConst.maxDepth + 1): + for i in range(nwConst.MAX_DEPTH + 1): if tItem.itemParent is None: return tItem else: @@ -278,7 +278,7 @@ class NWTree(): tItem = self.__getitem__(tHandle) if tItem is not None: tTree.append(tHandle) - for i in range(nwConst.maxDepth + 1): + for i in range(nwConst.MAX_DEPTH + 1): if tItem.itemParent is None: return tTree else: diff --git a/nw/gui/build.py b/nw/gui/build.py index 4a8f8aad..bc820f16 100644 --- a/nw/gui/build.py +++ b/nw/gui/build.py @@ -422,7 +422,7 @@ class GuiBuildNovel(QDialog): self.buttonBox.addWidget(self.btnSave) self.buttonBox.addWidget(self.btnPrint) self.buttonBox.addWidget(self.btnClose) - self.buttonBox.setSpacing(4) + self.buttonBox.setSpacing(self.mainConf.pxInt(4)) # Assemble GUI # ============ @@ -464,12 +464,13 @@ class GuiBuildNovel(QDialog): self.toolsArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) # Tools and Buttons Layout + tSp = self.mainConf.pxInt(8) self.innerBox = QVBoxLayout() self.innerBox.addWidget(self.toolsArea) - self.innerBox.addSpacing(8) + self.innerBox.addSpacing(tSp) self.innerBox.addWidget(self.buildProgress) self.innerBox.addWidget(self.buildNovel) - self.innerBox.addSpacing(8) + self.innerBox.addSpacing(tSp) self.innerBox.addLayout(self.buttonBox) # Tools and Buttons Wrapper Widget @@ -482,6 +483,12 @@ class GuiBuildNovel(QDialog): self.mainSplit.addWidget(self.docView) self.mainSplit.setSizes([boxWidth, docWidth]) + self.idxSettings = self.mainSplit.indexOf(self.innerWidget) + self.idxDocument = self.mainSplit.indexOf(self.docView) + + self.mainSplit.setCollapsible(self.idxSettings, False) + self.mainSplit.setCollapsible(self.idxDocument, False) + # Outer Layout self.outerBox = QHBoxLayout() self.outerBox.addWidget(self.mainSplit) @@ -508,7 +515,7 @@ class GuiBuildNovel(QDialog): self.docView.setStyleSheet(self.htmlStyle) htmlSize = sum([len(x) for x in self.htmlText]) - if htmlSize < nwConst.maxBuildSize: + if htmlSize < nwConst.MAX_BUILDSIZE: qApp.processEvents() self.docView.setContent(self.htmlText, self.buildTime) else: @@ -649,7 +656,7 @@ class GuiBuildNovel(QDialog): else: self.docView.setStyleSheet(self.htmlStyle) - if htmlSize < nwConst.maxBuildSize: + if htmlSize < nwConst.MAX_BUILDSIZE: self.docView.setContent(self.htmlText, self.buildTime) self._enableQtSave(True) else: diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index 09792041..85a3f75d 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -50,7 +50,7 @@ from PyQt5.QtWidgets import ( QFrame ) -from nw.core import NWDoc, NWSpellCheck, NWSpellSimple, countWords +from nw.core import NWDoc, NWSpellSimple, countWords from nw.gui.dochighlight import GuiDocHighlighter from nw.common import transferCase from nw.constants import ( @@ -284,12 +284,12 @@ class GuiDocEditor(QTextEdit): return False docSize = len(theDoc) - if docSize > nwConst.maxDocSize: + if docSize > nwConst.MAX_DOCSIZE: self.theParent.makeAlert(( "The document you are trying to open is too big. " "The document size is %.2f\u202fMB. " "The maximum size allowed is %.2f\u202fMB." - ) % (docSize/1.0e6, nwConst.maxDocSize/1.0e6), nwAlert.ERROR) + ) % (docSize/1.0e6, nwConst.MAX_DOCSIZE/1.0e6), nwAlert.ERROR) self.clearEditor() return False @@ -361,12 +361,12 @@ class GuiDocEditor(QTextEdit): text. This also clears undo history. """ docSize = len(theText) - if docSize > nwConst.maxDocSize: + if docSize > nwConst.MAX_DOCSIZE: self.theParent.makeAlert(( "The text you are trying to add is too big. " "The text size is %.2f\u202fMB. " "The maximum size allowed is %.2f\u202fMB." - ) % (docSize/1.0e6, nwConst.maxDocSize/1.0e6), nwAlert.ERROR) + ) % (docSize/1.0e6, nwConst.MAX_DOCSIZE/1.0e6), nwAlert.ERROR) return False qApp.setOverrideCursor(QCursor(Qt.WaitCursor)) @@ -859,11 +859,11 @@ class GuiDocEditor(QTextEdit): """ self.lastEdit = time() self.lastFind = None - if self.qDocument.characterCount() > nwConst.maxDocSize: + if self.qDocument.characterCount() > nwConst.MAX_DOCSIZE: self.theParent.makeAlert(( "The document has grown too big and you cannot add more text to it. " "The maximum size of a single novelWriter document is %.2f\u202fMB." - ) % (nwConst.maxDocSize/1.0e6), nwAlert.ERROR) + ) % (nwConst.MAX_DOCSIZE/1.0e6), nwAlert.ERROR) self.undo() return if not self.docChanged: @@ -1004,6 +1004,9 @@ class GuiDocEditor(QTextEdit): """Decide whether to run the word counter, or not due to inactivity. """ + if self.theHandle is None: + return + if self.wCounter.isRunning(): logger.verbose("Word counter is busy") return @@ -1611,7 +1614,7 @@ class GuiDocEditor(QTextEdit): """Create the spell checking object based on the spellTool setting in config. """ - if self.mainConf.spellTool == NWSpellCheck.SP_ENCHANT: + if self.mainConf.spellTool == nwConst.SP_ENCHANT: from nw.core.spellcheck import NWSpellEnchant self.theDict = NWSpellEnchant() else: diff --git a/nw/gui/docsplit.py b/nw/gui/docsplit.py index 1a5e9491..48ea3e9e 100644 --- a/nw/gui/docsplit.py +++ b/nw/gui/docsplit.py @@ -155,7 +155,7 @@ class GuiDocSplit(QDialog): # Check that another folder can be created parTree = self.theProject.projTree.getItemPath(srcItem.itemParent) - if len(parTree) >= nwConst.maxDepth - 1: + if len(parTree) >= nwConst.MAX_DEPTH - 1: self.theParent.makeAlert(( "Cannot add new folder for the document split. " "Maximum folder depth has been reached. " diff --git a/nw/gui/outlinedetails.py b/nw/gui/outlinedetails.py index d19bf2e9..c4e54f16 100644 --- a/nw/gui/outlinedetails.py +++ b/nw/gui/outlinedetails.py @@ -246,6 +246,27 @@ class GuiOutlineDetails(QScrollArea): return + def clearDetails(self): + """Clear all the data labels. + """ + self.titleLabel.setText("Title") + self.titleValue.setText("") + self.fileValue.setText("") + self.itemValue.setText("") + self.cCValue.setText("") + self.wCValue.setText("") + self.pCValue.setText("") + self.synopValue.setText("") + self.povKeyValue.setText("") + self.chrKeyValue.setText("") + self.pltKeyValue.setText("") + self.timKeyValue.setText("") + self.wldKeyValue.setText("") + self.objKeyValue.setText("") + self.entKeyValue.setText("") + self.cstKeyValue.setText("") + return + def showItem(self, tHandle, sTitle): """Update the content of the tree with the given handle and line number pointing to a header. diff --git a/nw/gui/preferences.py b/nw/gui/preferences.py index 945e35f6..2bb22bde 100644 --- a/nw/gui/preferences.py +++ b/nw/gui/preferences.py @@ -37,7 +37,8 @@ from PyQt5.QtWidgets import ( ) from nw.gui.custom import QSwitch, QConfigLayout, PagedDialog, QuotesDialog -from nw.core import NWSpellCheck, NWSpellSimple, NWSpellEnchant +from nw.core import NWSpellSimple, NWSpellEnchant +from nw.constants import nwConst logger = logging.getLogger(__name__) @@ -703,11 +704,11 @@ class GuiConfigEditEditingTab(QWidget): ## Spell Check Provider and Language self.spellLangList = QComboBox(self) self.spellToolList = QComboBox(self) - self.spellToolList.addItem("Internal (difflib)", NWSpellCheck.SP_INTERNAL) - self.spellToolList.addItem("Spell Enchant (pyenchant)", NWSpellCheck.SP_ENCHANT) + self.spellToolList.addItem("Internal (difflib)", nwConst.SP_INTERNAL) + self.spellToolList.addItem("Spell Enchant (pyenchant)", nwConst.SP_ENCHANT) theModel = self.spellToolList.model() - idEnchant = self.spellToolList.findData(NWSpellCheck.SP_ENCHANT) + idEnchant = self.spellToolList.findData(nwConst.SP_ENCHANT) theModel.item(idEnchant).setEnabled(self.mainConf.hasEnchant) self.spellToolList.currentIndexChanged.connect(self._doUpdateSpellTool) @@ -814,7 +815,7 @@ class GuiConfigEditEditingTab(QWidget): preserve the language choice, if the language exists in the updated list. """ - if spellTool == NWSpellCheck.SP_ENCHANT: + if spellTool == nwConst.SP_ENCHANT: theDict = NWSpellEnchant() else: theDict = NWSpellSimple() diff --git a/nw/gui/projtree.py b/nw/gui/projtree.py index 89e41374..f0d0bca9 100644 --- a/nw/gui/projtree.py +++ b/nw/gui/projtree.py @@ -243,8 +243,8 @@ class GuiProjectTree(QTreeWidget): tHandle = self.theProject.newFile("New File", itemClass, pHandle) elif itemType == nwItemType.FOLDER: - if len(parTree) >= nwConst.maxDepth - 1: - # Folders cannot be deeper than maxDepth - 1, leaving room + if len(parTree) >= nwConst.MAX_DEPTH - 1: + # Folders cannot be deeper than MAX_DEPTH - 1, leaving room # for one more level of files. self.makeAlert(( "Cannot add new folder to this item. " @@ -579,7 +579,7 @@ class GuiProjectTree(QTreeWidget): pCount += int(pItem.child(i).data(self.C_COUNT, Qt.UserRole)) pHandle = pItem.data(self.C_NAME, Qt.UserRole) - if not nDepth > nwConst.maxDepth + 1 and pHandle != "": + if not nDepth > nwConst.MAX_DEPTH + 1 and pHandle != "": self.propagateCount(pHandle, pCount, nDepth+1) return diff --git a/nw/gui/writingstats.py b/nw/gui/writingstats.py index fb10f7a4..b796bbce 100644 --- a/nw/gui/writingstats.py +++ b/nw/gui/writingstats.py @@ -428,10 +428,10 @@ class GuiWritingStats(QDialog): continue dStart = datetime.strptime( - "%s %s" % (inData[0], inData[1]), nwConst.tStampFmt + "%s %s" % (inData[0], inData[1]), nwConst.FMT_TSTAMP ) dEnd = datetime.strptime( - "%s %s" % (inData[2], inData[3]), nwConst.tStampFmt + "%s %s" % (inData[2], inData[3]), nwConst.FMT_TSTAMP ) tDiff = dEnd - dStart @@ -528,9 +528,9 @@ class GuiWritingStats(QDialog): isFirst = False if groupByDay: - sStart = dStart.strftime(nwConst.dStampFmt) + sStart = dStart.strftime(nwConst.FMT_DSTAMP) else: - sStart = dStart.strftime(nwConst.tStampFmt) + sStart = dStart.strftime(nwConst.FMT_TSTAMP) self.filterData.append((dStart, sStart, sDiff, dwTotal, wcNovel, wcNotes)) listMax = min(max(listMax, dwTotal), histMax) diff --git a/nw/guimain.py b/nw/guimain.py index 9b1a8a42..1a6b5a16 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -345,6 +345,7 @@ class GuiMain(QMainWindow): self.closeDocument() self.docViewer.clearNavHistory() self.projView.closeOutline() + self.projMeta.clearDetails() self.theProject.closeProject() self.theIndex.clearIndex() self.clearGUI() diff --git a/setup.py b/setup.py index 1eae8bf7..9fc4bcf6 100755 --- a/setup.py +++ b/setup.py @@ -5,23 +5,20 @@ The main setup script for novelWeiter. It runs the standard setuptool.setup() with all options taken from the setup.cfg file. -In addtion, a few speicalised commands are available: - - * sample: Will build a sample.zip file, which is the way the sample project is - included into distributable packages. - * qthelp: Will build a QtAssistant readable version of the novelWriter - documentation. This should also be a part of distributed packages. It allows - for reading the help offline. Otherwise, the F1 button redirects to the - online documentation only. - * launcher: Will attempt to install novelWriter icons, mime type and create a - launcher for the application. - +In addtion, a few speicalised commands are available. These are +described in the help text in the main section. """ + import os import sys import shutil import subprocess +OS_NONE = 0 +OS_LINUX = 1 +OS_WIN = 2 +OS_DARWIN = 3 + # =============================================================================================== # # Qt Assistant Documentation Builder # =============================================================================================== # @@ -285,6 +282,19 @@ def xdgInstall(): # =============================================================================================== # if __name__ == "__main__": + """Parse command line options and run the commands. + """ + # Detect OS + if sys.platform.startswith("linux"): + hostOS = OS_LINUX + elif sys.platform.startswith("darwin"): + hostOS = OS_DARWIN + elif sys.platform.startswith("win32"): + hostOS = OS_WIN + elif sys.platform.startswith("cygwin"): + hostOS = OS_WIN + else: + hostOS = OS_NONE helpMsg = ( "\n" @@ -292,10 +302,17 @@ if __name__ == "__main__": "======================\n" "This tool provides some additional setup commands for novelWriter.\n" "\n" - "help Print the help message.\n" - "qthelp Build the help documentation for use with the QtAssistant.\n" + "help Print this help message.\n" + "qthelp Build the help documentation for use with the Qt Assistant.\n" + " Run before install to enable in the the installed version.\n" "sample Build the sample project as a zip file.\n" + " Run before install to enable creating sample projects.\n" + "install Installs novelWriter to the system's Python install location.\n" + " Run as root or with sudo for system-wide install, or as\n" + " user for single user install.\n" "xdg-install Install launcher and icons for freedesktop systems.\n" + " Run as root or with sudo for system-wide install, or as\n" + " user for single user install.\n" ) if "help" in sys.argv: @@ -303,6 +320,11 @@ if __name__ == "__main__": print(helpMsg) sys.exit(0) + if "launcher" in sys.argv: + sys.argv.remove("launcher") + print("The 'launcher' option has been replaced by 'xdg-install'.") + sys.exit(1) + if "qthelp" in sys.argv: sys.argv.remove("qthelp") buildQtDocs() @@ -313,11 +335,11 @@ if __name__ == "__main__": if "xdg-install" in sys.argv: sys.argv.remove("xdg-install") - if not sys.platform.startswith("win32"): - xdgInstall() - else: + if hostOS == OS_WIN: print("ERROR: xdg-install cannot be used on Windows") sys.exit(1) + else: + xdgInstall() if len(sys.argv) <= 1: # Nothing more to do diff --git a/tests/reference/novelwriter.conf b/tests/reference/novelwriter.conf index aef7459f..99b01f75 100644 --- a/tests/reference/novelwriter.conf +++ b/tests/reference/novelwriter.conf @@ -8,9 +8,9 @@ guifont = guifontsize = 11 [Sizes] -geometry = 1100, 650 -treecols = 120, 30, 50 -projcols = 140, 55, 140 +geometry = 1200, 650 +treecols = 200, 50, 30 +projcols = 200, 60, 140 mainpane = 300, 800 docpane = 400, 400 viewpane = 500, 150 diff --git a/tests/test_config.py b/tests/test_config.py index 8911a69d..f9ce767b 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -44,11 +44,11 @@ def testConfigSetWinSize(tmpConf, nwTemp, nwRef): tmpConf.guiScale = 1.0 assert tmpConf.confPath == nwTemp - assert tmpConf.setWinSize(1105, 655) + assert tmpConf.setWinSize(1205, 655) assert not tmpConf.confChanged assert tmpConf.setWinSize(70, 70) assert tmpConf.confChanged - assert tmpConf.setWinSize(1100, 650) + assert tmpConf.setWinSize(1200, 650) assert tmpConf.saveConfig() assert cmpFiles(testConf, refConf, [2]) @@ -62,13 +62,13 @@ def testConfigSetTreeColWidths(tmpConf, nwTemp, nwRef): assert tmpConf.confPath == nwTemp tmpConf.guiScale = 1.0 - assert tmpConf.setTreeColWidths([10, 20, 30]) - assert tmpConf.treeColWidth == [10, 20, 30] - assert tmpConf.setTreeColWidths([120, 30, 50]) + assert tmpConf.setTreeColWidths([10, 20, 25]) + assert tmpConf.treeColWidth == [10, 20, 25] + assert tmpConf.setTreeColWidths([200, 50, 30]) assert tmpConf.setProjColWidths([10, 20, 30]) assert tmpConf.projColWidth == [10, 20, 30] - assert tmpConf.setProjColWidths([140, 55, 140]) + assert tmpConf.setProjColWidths([200, 60, 140]) assert tmpConf.confChanged assert tmpConf.saveConfig() diff --git a/tests/test_project.py b/tests/test_project.py index 9be85a67..b8df3c0e 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -13,7 +13,7 @@ from nwtools import cmpFiles from nw.core.project import NWProject from nw.core.document import NWDoc from nw.core.spellcheck import NWSpellEnchant, NWSpellSimple -from nw.constants import nwItemClass, nwItemType, nwItemLayout, nwFiles +from nw.constants import nwConst, nwItemClass, nwItemType, nwItemLayout, nwFiles @pytest.mark.project def testProjectNewOpenSave(nwFuncTemp, nwTempProj, nwRef, nwTemp, nwDummy): @@ -405,7 +405,7 @@ def testSpellSimple(nwTemp, nwConf): aTag, aName = spChk.describeDict() assert aTag == "en" - assert aName == "internal" + assert aName == nwConst.SP_INTERNAL @pytest.mark.project def testProjectOptions(nwDummy, nwLipsum):