Merge pull request #462 from vkbo/editor_features
Various Document Editor and Related Improvements
This commit is contained in:
+4
-4
@@ -203,12 +203,12 @@ def transferCase(theSource, theTarget):
|
|||||||
if len(theTarget) < 1 or len(theSource) < 1:
|
if len(theTarget) < 1 or len(theSource) < 1:
|
||||||
return theResult
|
return theResult
|
||||||
|
|
||||||
if theSource[0] == theSource[0].upper():
|
if theSource.istitle():
|
||||||
theResult = theTarget[0].upper() + theTarget[1:]
|
theResult = theTarget.title()
|
||||||
|
|
||||||
if theSource == theSource.upper():
|
if theSource.isupper():
|
||||||
theResult = theTarget.upper()
|
theResult = theTarget.upper()
|
||||||
elif theSource == theSource.lower():
|
elif theSource.islower():
|
||||||
theResult = theTarget.lower()
|
theResult = theTarget.lower()
|
||||||
|
|
||||||
return theResult
|
return theResult
|
||||||
|
|||||||
+31
-6
@@ -87,6 +87,11 @@ class NWSpellCheck():
|
|||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def describeDict(self):
|
||||||
|
"""Dummy function.
|
||||||
|
"""
|
||||||
|
return "", ""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def expandLanguage(spTag):
|
def expandLanguage(spTag):
|
||||||
"""Translate a language tag to something more user friendly.
|
"""Translate a language tag to something more user friendly.
|
||||||
@@ -187,6 +192,21 @@ class NWSpellEnchant(NWSpellCheck):
|
|||||||
logger.error("Failed to list languages for enchant spell checking")
|
logger.error("Failed to list languages for enchant spell checking")
|
||||||
return retList
|
return retList
|
||||||
|
|
||||||
|
def describeDict(self):
|
||||||
|
"""Return the tag and provider of the currently loaded
|
||||||
|
dictionary.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
spTag = self.theDict.tag
|
||||||
|
spName = self.theDict.provider.name
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("Failed to extract information about the dictionary")
|
||||||
|
logger.error(str(e))
|
||||||
|
spTag = ""
|
||||||
|
spName = ""
|
||||||
|
|
||||||
|
return spTag, spName
|
||||||
|
|
||||||
# END Class NWSpellEnchant
|
# END Class NWSpellEnchant
|
||||||
|
|
||||||
class NWSpellEnchantDummy:
|
class NWSpellEnchantDummy:
|
||||||
@@ -221,12 +241,14 @@ class NWSpellSimple(NWSpellCheck):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
NWSpellCheck.__init__(self)
|
NWSpellCheck.__init__(self)
|
||||||
|
self.theLang = ""
|
||||||
logger.debug("Simple spell checking activated")
|
logger.debug("Simple spell checking activated")
|
||||||
return
|
return
|
||||||
|
|
||||||
def setLanguage(self, theLang, projectDict=None):
|
def setLanguage(self, theLang, projectDict=None):
|
||||||
"""Load a dictionary as a list from the app assets folder.
|
"""Load a dictionary as a list from the app assets folder.
|
||||||
"""
|
"""
|
||||||
|
self.theLang = theLang
|
||||||
self.WORDS = []
|
self.WORDS = []
|
||||||
dictFile = os.path.join(self.mainConf.dictPath, theLang+".dict")
|
dictFile = os.path.join(self.mainConf.dictPath, theLang+".dict")
|
||||||
try:
|
try:
|
||||||
@@ -269,15 +291,12 @@ class NWSpellSimple(NWSpellCheck):
|
|||||||
if len(theWord) == 0:
|
if len(theWord) == 0:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
firstUp = theWord[0] == theWord[0].upper()
|
theMatches = get_close_matches(theWord.lower(), self.WORDS, n=10, cutoff=0.75)
|
||||||
theWord = theWord.lower()
|
|
||||||
|
|
||||||
theMatches = get_close_matches(theWord, self.WORDS, n=10, cutoff=0.75)
|
|
||||||
theOptions = []
|
theOptions = []
|
||||||
for aWord in theMatches:
|
for aWord in theMatches:
|
||||||
if len(aWord) == 0:
|
if len(aWord) == 0:
|
||||||
continue
|
continue
|
||||||
if firstUp:
|
if theWord[0].isupper():
|
||||||
aWord = aWord[0].upper() + aWord[1:]
|
aWord = aWord[0].upper() + aWord[1:]
|
||||||
aWord = aWord.replace("'", self.mainConf.fmtApostrophe)
|
aWord = aWord.replace("'", self.mainConf.fmtApostrophe)
|
||||||
theOptions.append(aWord)
|
theOptions.append(aWord)
|
||||||
@@ -305,9 +324,15 @@ class NWSpellSimple(NWSpellCheck):
|
|||||||
if theBits[1] != ".dict":
|
if theBits[1] != ".dict":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
spName = "%s [Internal]" % self.expandLanguage(theBits[0])
|
spName = "%s [internal]" % self.expandLanguage(theBits[0])
|
||||||
retList.append((theBits[0], spName))
|
retList.append((theBits[0], spName))
|
||||||
|
|
||||||
return retList
|
return retList
|
||||||
|
|
||||||
|
def describeDict(self):
|
||||||
|
"""Return the tag and provider of the currently loaded
|
||||||
|
dictionary.
|
||||||
|
"""
|
||||||
|
return self.theLang, "internal"
|
||||||
|
|
||||||
# END Class NWSpellSimple
|
# END Class NWSpellSimple
|
||||||
|
|||||||
+52
-42
@@ -12,6 +12,7 @@
|
|||||||
Created: 2020-04-25 [0.4.5] GuiDocEditHeader
|
Created: 2020-04-25 [0.4.5] GuiDocEditHeader
|
||||||
Rewritten: 2020-06-15 [0.9.0] GuiDocEditSearch
|
Rewritten: 2020-06-15 [0.9.0] GuiDocEditSearch
|
||||||
Created: 2020-06-27 [0.10.0] GuiDocEditFooter
|
Created: 2020-06-27 [0.10.0] GuiDocEditFooter
|
||||||
|
Rewritten: 2020-10-07 [1.0b3] BackgroundWordCounter
|
||||||
|
|
||||||
This file is a part of novelWriter
|
This file is a part of novelWriter
|
||||||
Copyright 2018–2020, Veronica Berglyd Olsen
|
Copyright 2018–2020, Veronica Berglyd Olsen
|
||||||
@@ -36,7 +37,8 @@ import logging
|
|||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
Qt, QSize, QThread, QTimer, pyqtSlot, QRegExp, QRegularExpression, QPointF
|
Qt, QSize, QTimer, pyqtSlot, pyqtSignal, QRegExp, QRegularExpression,
|
||||||
|
QPointF, QObject, QRunnable
|
||||||
)
|
)
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QTextCursor, QTextOption, QKeySequence, QFont, QColor, QPalette,
|
QTextCursor, QTextOption, QKeySequence, QFont, QColor, QPalette,
|
||||||
@@ -135,14 +137,15 @@ class GuiDocEditor(QTextEdit):
|
|||||||
activated=self._followTag
|
activated=self._followTag
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set Up Word Count Thread and Timer
|
# Set Up Word Counter
|
||||||
self.wcInterval = self.mainConf.wordCountTimer
|
self.wcInterval = self.mainConf.wordCountTimer
|
||||||
self.wcTimer = QTimer()
|
self.wcTimer = QTimer()
|
||||||
self.wcTimer.setInterval(int(self.wcInterval*1000))
|
self.wcTimer.setInterval(int(self.wcInterval*1000))
|
||||||
self.wcTimer.timeout.connect(self._runCounter)
|
self.wcTimer.timeout.connect(self._runCounter)
|
||||||
|
|
||||||
self.wCounter = BackgroundWordCounter(self)
|
self.wCounter = BackgroundWordCounter(self)
|
||||||
self.wCounter.finished.connect(self._updateCounts)
|
self.wCounter.setAutoDelete(False)
|
||||||
|
self.wCounter.signals.countsReady.connect(self._updateCounts)
|
||||||
|
|
||||||
self.initEditor()
|
self.initEditor()
|
||||||
|
|
||||||
@@ -282,7 +285,7 @@ class GuiDocEditor(QTextEdit):
|
|||||||
|
|
||||||
self._allowAutoReplace(True)
|
self._allowAutoReplace(True)
|
||||||
afTime = time()
|
afTime = time()
|
||||||
logger.debug("Document highlighted in %.3f milliseconds" % (1000*(afTime-bfTime)))
|
logger.debug("Document highlighted in %.3f ms" % (1000*(afTime-bfTime)))
|
||||||
|
|
||||||
self.lastEdit = time()
|
self.lastEdit = time()
|
||||||
self._runCounter()
|
self._runCounter()
|
||||||
@@ -503,7 +506,11 @@ class GuiDocEditor(QTextEdit):
|
|||||||
theLang = self.theProject.projLang
|
theLang = self.theProject.projLang
|
||||||
|
|
||||||
self.theDict.setLanguage(theLang, self.theProject.projDict)
|
self.theDict.setLanguage(theLang, self.theProject.projDict)
|
||||||
self.theParent.statusBar.setLanguage(self.theDict.spellLanguage)
|
|
||||||
|
aLang, aName = self.theDict.describeDict()
|
||||||
|
self.theParent.statusBar.setLanguage(
|
||||||
|
aLang, "%s [%s]" % (self.mainConf.spellTool.title(), aName.title())
|
||||||
|
)
|
||||||
|
|
||||||
if not self.bigDoc:
|
if not self.bigDoc:
|
||||||
self.spellCheckDocument()
|
self.spellCheckDocument()
|
||||||
@@ -550,9 +557,8 @@ class GuiDocEditor(QTextEdit):
|
|||||||
qApp.restoreOverrideCursor()
|
qApp.restoreOverrideCursor()
|
||||||
afTime = time()
|
afTime = time()
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Document re-highlighted in %.3f milliseconds" % (1000*(afTime-bfTime))
|
"Document highlighted in %.3f ms" % (1000*(afTime-bfTime))
|
||||||
)
|
)
|
||||||
|
|
||||||
self.theParent.statusBar.showMessage("Spell check complete")
|
self.theParent.statusBar.showMessage("Spell check complete")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@@ -857,7 +863,7 @@ class GuiDocEditor(QTextEdit):
|
|||||||
mnuHead = QAction("Spelling Suggestion(s)", mnuContext)
|
mnuHead = QAction("Spelling Suggestion(s)", mnuContext)
|
||||||
mnuContext.addAction(mnuHead)
|
mnuContext.addAction(mnuHead)
|
||||||
|
|
||||||
theSuggest = self.theDict.suggestWords(theWord)
|
theSuggest = self.theDict.suggestWords(theWord)[:15]
|
||||||
if len(theSuggest) > 0:
|
if len(theSuggest) > 0:
|
||||||
for aWord in theSuggest:
|
for aWord in theSuggest:
|
||||||
mnuWord = QAction("%s %s" % (nwUnicode.U_ENDASH, aWord), mnuContext)
|
mnuWord = QAction("%s %s" % (nwUnicode.U_ENDASH, aWord), mnuContext)
|
||||||
@@ -910,21 +916,18 @@ class GuiDocEditor(QTextEdit):
|
|||||||
"""Decide whether to run the word counter, or stop the timer due
|
"""Decide whether to run the word counter, or stop the timer due
|
||||||
to inactivity.
|
to inactivity.
|
||||||
"""
|
"""
|
||||||
sinceActive = time()-self.lastEdit
|
if self.wCounter.isRunning():
|
||||||
if sinceActive > 5*self.wcInterval:
|
logger.verbose("Word counter is busy")
|
||||||
logger.debug(
|
return
|
||||||
"Stopping word count timer: no activity last %.1f seconds" % sinceActive
|
|
||||||
)
|
if time() - self.lastEdit < 5*self.wcInterval:
|
||||||
self.wcTimer.stop()
|
logger.verbose("Running word counter")
|
||||||
elif self.wCounter.isRunning():
|
self.theParent.threadPool.start(self.wCounter)
|
||||||
logger.verbose("Word counter thread is busy")
|
|
||||||
else:
|
|
||||||
logger.verbose("Starting word counter")
|
|
||||||
self.wCounter.start()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot(int, int, int)
|
||||||
def _updateCounts(self):
|
def _updateCounts(self, cCount, wCount, pCount):
|
||||||
"""Slot for the word counter's finished signal
|
"""Slot for the word counter's finished signal
|
||||||
"""
|
"""
|
||||||
theItem = self.nwDocument.getCurrentItem()
|
theItem = self.nwDocument.getCurrentItem()
|
||||||
@@ -933,19 +936,17 @@ class GuiDocEditor(QTextEdit):
|
|||||||
|
|
||||||
logger.verbose("Updating word count")
|
logger.verbose("Updating word count")
|
||||||
|
|
||||||
self.charCount = self.wCounter.charCount
|
self.charCount = cCount
|
||||||
self.wordCount = self.wCounter.wordCount
|
self.wordCount = wCount
|
||||||
self.paraCount = self.wCounter.paraCount
|
self.paraCount = pCount
|
||||||
theItem.setCharCount(self.charCount)
|
theItem.setCharCount(cCount)
|
||||||
theItem.setWordCount(self.wordCount)
|
theItem.setWordCount(wCount)
|
||||||
theItem.setParaCount(self.paraCount)
|
theItem.setParaCount(pCount)
|
||||||
|
|
||||||
self.theParent.treeView.propagateCount(self.theHandle, self.wordCount)
|
self.theParent.treeView.propagateCount(self.theHandle, wCount)
|
||||||
self.theParent.treeView.projectWordCount()
|
self.theParent.treeView.projectWordCount()
|
||||||
self.theParent.treeMeta.updateCounts(
|
self.theParent.treeMeta.updateCounts(self.theHandle, cCount, wCount, pCount)
|
||||||
self.theHandle, self.charCount, self.wordCount, self.paraCount
|
self._checkDocSize(self.qDocument.characterCount())
|
||||||
)
|
|
||||||
self._checkDocSize(self.charCount)
|
|
||||||
self.docFooter.updateCounts()
|
self.docFooter.updateCounts()
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -1519,33 +1520,42 @@ class GuiDocEditor(QTextEdit):
|
|||||||
# END Class GuiDocEditor
|
# END Class GuiDocEditor
|
||||||
|
|
||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
# The Off GUI Thread Word Counter
|
# The Off-GUI Thread Word Counter
|
||||||
# Runs the word counter in the background for the DocEditor
|
# A runnable for the word counter to be run in the thread pool off the main GUI thread.
|
||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
|
|
||||||
class BackgroundWordCounter(QThread):
|
class BackgroundWordCounter(QRunnable):
|
||||||
|
|
||||||
def __init__(self, docEditor):
|
def __init__(self, docEditor):
|
||||||
QThread.__init__(self, docEditor)
|
QRunnable.__init__(self)
|
||||||
self.docEditor = docEditor
|
self.docEditor = docEditor
|
||||||
self.charCount = 0
|
self.signals = BackgroundWordCounterSignals()
|
||||||
self.wordCount = 0
|
self._isRunning = False
|
||||||
self.paraCount = 0
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def isRunning(self):
|
||||||
|
return self._isRunning
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Overloaded run function for the word counter, forwarding the
|
"""Overloaded run function for the word counter, forwarding the
|
||||||
call to the function that does the actual counting.
|
call to the function that does the actual counting.
|
||||||
"""
|
"""
|
||||||
|
self._isRunning = True
|
||||||
theText = self.docEditor.getText()
|
theText = self.docEditor.getText()
|
||||||
cC, wC, pC = countWords(theText)
|
cC, wC, pC = countWords(theText)
|
||||||
self.charCount = cC
|
self.signals.countsReady.emit(cC, wC, pC)
|
||||||
self.wordCount = wC
|
self._isRunning = False
|
||||||
self.paraCount = pC
|
|
||||||
return
|
return
|
||||||
|
|
||||||
## END Class BackgroundWordCounter
|
## END Class BackgroundWordCounter
|
||||||
|
|
||||||
|
class BackgroundWordCounterSignals(QObject):
|
||||||
|
|
||||||
|
countsReady = pyqtSignal(int, int, int)
|
||||||
|
|
||||||
|
# END Class BackgroundWordCounterSignals
|
||||||
|
|
||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
# The Embedded Document Search/Replace Feature
|
# The Embedded Document Search/Replace Feature
|
||||||
# Only used by DocEditor, and is at a fixed position in the QTextEdit's viewport
|
# Only used by DocEditor, and is at a fixed position in the QTextEdit's viewport
|
||||||
|
|||||||
+10
-3
@@ -28,6 +28,8 @@
|
|||||||
import nw
|
import nw
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from time import time
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt, QRegularExpression
|
from PyQt5.QtCore import Qt, QRegularExpression
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QColor, QTextCharFormat, QFont, QSyntaxHighlighter, QBrush
|
QColor, QTextCharFormat, QFont, QSyntaxHighlighter, QBrush
|
||||||
@@ -203,7 +205,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
# Build a QRegExp for spell checker
|
# Build a QRegExp for spell checker
|
||||||
# Include additional characters that the highlighter should
|
# Include additional characters that the highlighter should
|
||||||
# consider to be word separators
|
# consider to be word separators
|
||||||
wordSep = r"_\+/"
|
wordSep = r"\-_\+/"
|
||||||
wordSep += nwUnicode.U_ENDASH
|
wordSep += nwUnicode.U_ENDASH
|
||||||
wordSep += nwUnicode.U_EMDASH
|
wordSep += nwUnicode.U_EMDASH
|
||||||
self.spellRx = QRegularExpression(r"\b[^\s"+wordSep+r"]+\b")
|
self.spellRx = QRegularExpression(r"\b[^\s"+wordSep+r"]+\b")
|
||||||
@@ -244,10 +246,15 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
"""
|
"""
|
||||||
qDocument = self.document()
|
qDocument = self.document()
|
||||||
nBlocks = qDocument.blockCount()
|
nBlocks = qDocument.blockCount()
|
||||||
|
bfTime = time()
|
||||||
for i in range(nBlocks):
|
for i in range(nBlocks):
|
||||||
theBlock = qDocument.findBlockByNumber(i)
|
theBlock = qDocument.findBlockByNumber(i)
|
||||||
if theBlock.userState() & theType == theType:
|
if theBlock.userState() & theType > 0:
|
||||||
self.rehighlightBlock(theBlock)
|
self.rehighlightBlock(theBlock)
|
||||||
|
afTime = time()
|
||||||
|
logger.debug(
|
||||||
|
"Document highlighted in %.3f ms" % (1000*(afTime-bfTime))
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -343,7 +350,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
while rxSpell.hasNext():
|
while rxSpell.hasNext():
|
||||||
rxMatch = rxSpell.next()
|
rxMatch = rxSpell.next()
|
||||||
if not self.theDict.checkWord(rxMatch.captured(0)):
|
if not self.theDict.checkWord(rxMatch.captured(0)):
|
||||||
if rxMatch.captured(0) == rxMatch.captured(0).upper():
|
if rxMatch.captured(0).isupper() or rxMatch.captured(0).isnumeric():
|
||||||
continue
|
continue
|
||||||
xPos = rxMatch.capturedStart(0)
|
xPos = rxMatch.capturedStart(0)
|
||||||
xLen = rxMatch.capturedLength(0)
|
xLen = rxMatch.capturedLength(0)
|
||||||
|
|||||||
+5
-1
@@ -152,13 +152,17 @@ class GuiMainStatus(QStatusBar):
|
|||||||
qApp.processEvents()
|
qApp.processEvents()
|
||||||
return
|
return
|
||||||
|
|
||||||
def setLanguage(self, theLanguage):
|
def setLanguage(self, theLanguage, theProvider=""):
|
||||||
"""Set the language code for the spell checker.
|
"""Set the language code for the spell checker.
|
||||||
"""
|
"""
|
||||||
if theLanguage is None:
|
if theLanguage is None:
|
||||||
self.langText.setText("None")
|
self.langText.setText("None")
|
||||||
|
self.langText.setToolTip("")
|
||||||
else:
|
else:
|
||||||
self.langText.setText(NWSpellCheck.expandLanguage(theLanguage))
|
self.langText.setText(NWSpellCheck.expandLanguage(theLanguage))
|
||||||
|
self.langText.setToolTip(
|
||||||
|
"Provider: %s" % (theProvider if theProvider else "unknown")
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
def setProjectStatus(self, isChanged):
|
def setProjectStatus(self, isChanged):
|
||||||
|
|||||||
+2
-1
@@ -32,7 +32,7 @@ import os
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt, QTimer
|
from PyQt5.QtCore import Qt, QTimer, QThreadPool
|
||||||
from PyQt5.QtGui import QIcon, QPixmap, QColor, QKeySequence, QCursor
|
from PyQt5.QtGui import QIcon, QPixmap, QColor, QKeySequence, QCursor
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
qApp, QMainWindow, QVBoxLayout, QWidget, QSplitter, QFileDialog, QShortcut,
|
qApp, QMainWindow, QVBoxLayout, QWidget, QSplitter, QFileDialog, QShortcut,
|
||||||
@@ -60,6 +60,7 @@ class GuiMain(QMainWindow):
|
|||||||
logger.debug("Initialising GUI ...")
|
logger.debug("Initialising GUI ...")
|
||||||
self.setObjectName("GuiMain")
|
self.setObjectName("GuiMain")
|
||||||
self.mainConf = nw.CONFIG
|
self.mainConf = nw.CONFIG
|
||||||
|
self.threadPool = QThreadPool()
|
||||||
|
|
||||||
# Some runtime info useful for debugging
|
# Some runtime info useful for debugging
|
||||||
logger.info("OS: %s" % self.mainConf.osType)
|
logger.info("OS: %s" % self.mainConf.osType)
|
||||||
|
|||||||
@@ -377,6 +377,10 @@ def testSpellEnchant(nwTemp, nwConf):
|
|||||||
dList = spChk.listDictionaries()
|
dList = spChk.listDictionaries()
|
||||||
assert len(dList) > 0
|
assert len(dList) > 0
|
||||||
|
|
||||||
|
aTag, aName = spChk.describeDict()
|
||||||
|
assert aTag == "en"
|
||||||
|
assert aName != ""
|
||||||
|
|
||||||
@pytest.mark.project
|
@pytest.mark.project
|
||||||
def testSpellSimple(nwTemp, nwConf):
|
def testSpellSimple(nwTemp, nwConf):
|
||||||
wList = os.path.join(nwTemp, "wordlist.txt")
|
wList = os.path.join(nwTemp, "wordlist.txt")
|
||||||
@@ -402,6 +406,10 @@ def testSpellSimple(nwTemp, nwConf):
|
|||||||
dList = spChk.listDictionaries()
|
dList = spChk.listDictionaries()
|
||||||
assert len(dList) > 0
|
assert len(dList) > 0
|
||||||
|
|
||||||
|
aTag, aName = spChk.describeDict()
|
||||||
|
assert aTag == "en"
|
||||||
|
assert aName == "internal"
|
||||||
|
|
||||||
@pytest.mark.project
|
@pytest.mark.project
|
||||||
def testProjectOptions(nwDummy, nwLipsum):
|
def testProjectOptions(nwDummy, nwLipsum):
|
||||||
"""Test the class that holds all the GUI state user options that are
|
"""Test the class that holds all the GUI state user options that are
|
||||||
|
|||||||
Reference in New Issue
Block a user