Merge branch 'main' into release_1.0rc1

This commit is contained in:
Veronica K. B. Olsen
2020-11-01 17:08:44 +01:00
20 changed files with 166 additions and 113 deletions
+2 -2
View File
@@ -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
+7 -7
View File
@@ -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"
+30 -6
View File
@@ -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():
+1 -1
View File
@@ -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
+3 -25
View File
@@ -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:
+12 -16
View File
@@ -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
+1 -1
View File
@@ -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
)
+2 -2
View File
@@ -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:
+12 -5
View File
@@ -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:
+11 -8
View File
@@ -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:
+1 -1
View File
@@ -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. "
+21
View File
@@ -246,6 +246,27 @@ class GuiOutlineDetails(QScrollArea):
return
def clearDetails(self):
"""Clear all the data labels.
"""
self.titleLabel.setText("<b>Title</b>")
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.
+6 -5
View File
@@ -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()
+3 -3
View File
@@ -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
+4 -4
View File
@@ -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)
+1
View File
@@ -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()
+38 -16
View File
@@ -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
+3 -3
View File
@@ -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
+6 -6
View File
@@ -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()
+2 -2
View File
@@ -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):