Simplify setting cursor position in the editor

This commit is contained in:
Veronica Berglyd Olsen
2023-09-06 18:20:25 +02:00
parent 8c3e906fc5
commit 0bfa3cb592
3 changed files with 111 additions and 159 deletions
+11 -57
View File
@@ -37,8 +37,8 @@ from time import time
from typing import TYPE_CHECKING
from PyQt5.QtCore import (
pyqtSignal, pyqtSlot, QObject, QPoint, QPointF, QPropertyAnimation,
QRegExp, QRegularExpression, QRunnable, QSize, QSizeF, Qt, QTimer
pyqtSignal, pyqtSlot, QObject, QPoint, QPropertyAnimation, QRegExp,
QRegularExpression, QRunnable, QSize, Qt, QTimer
)
from PyQt5.QtGui import (
QColor, QCursor, QFont, QFontMetrics, QKeyEvent, QKeySequence, QMouseEvent,
@@ -107,7 +107,6 @@ class GuiDocEditor(QPlainTextEdit):
self._lastActive = 0.0 # Time stamp of last activity
self._lastFind = None # Position of the last found search word
self._doReplace = False # Switch to temporarily disable auto-replace
self._queuePos = None # Used for delayed change of cursor position
# Typography Cache
self._typPadChar = " "
@@ -125,7 +124,6 @@ class GuiDocEditor(QPlainTextEdit):
# Core Elements and Signals
qDoc = self.document()
qDoc.contentsChange.connect(self._docChange)
qDoc.documentLayout().documentSizeChanged.connect(self._docSizeChanged)
self.selectionChanged.connect(self._updateSelectedStatus)
# Document Title
@@ -238,7 +236,6 @@ class GuiDocEditor(QPlainTextEdit):
self._lastActive = 0.0
self._lastFind = None
self._doReplace = False
self._queuePos = None
self.setDocumentChanged(False)
self.docHeader.setTitleFromHandle(self._docHandle)
@@ -415,14 +412,7 @@ class GuiDocEditor(QPlainTextEdit):
self.updateDocMargins()
if tLine is None and self._nwItem is not None:
# For large documents, we queue the repositioning until the
# document layout has grown past the point we want to move
# the cursor to. This makes the loading significantly
# faster.
if docSize > 50000:
self._queuePos = self._nwItem.cursorPos
else:
self.setCursorPosition(self._nwItem.cursorPos)
self.setCursorPosition(self._nwItem.cursorPos)
elif isinstance(tLine, int):
self.setCursorLine(tLine)
@@ -628,32 +618,16 @@ class GuiDocEditor(QPlainTextEdit):
self.editedStatusChanged.emit(self._docChanged)
return self._docChanged
def setCursorPosition(self, position: int) -> bool:
def setCursorPosition(self, position: int) -> None:
"""Move the cursor to a given position in the document."""
if not isinstance(position, int):
return False
nChars = self.document().characterCount()
if nChars > 1:
theCursor = self.textCursor()
theCursor.setPosition(minmax(position, 0, nChars-1))
self.setTextCursor(theCursor)
# By default, the editor scrolls so the cursor is on the
# last line, so we must correct it. The user setting for
# auto-scroll is used to determine the scroll distance. This
# makes it compatible with the typewriter scrolling feature
# when it is enabled. By default, it's 30% of viewport.
vPos = self.verticalScrollBar().value()
cPos = self.cursorRect().topLeft().y()
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))
if nChars > 1 and isinstance(position, int):
cursor = self.textCursor()
cursor.setPosition(minmax(position, 0, nChars-1))
self.setTextCursor(cursor)
self.centerCursor()
self.docFooter.updateLineCount()
return True
return
def saveCursorPosition(self) -> None:
"""Save the cursor position to the current project item."""
@@ -1283,8 +1257,7 @@ class GuiDocEditor(QPlainTextEdit):
@pyqtSlot(int, int, int)
def _updateSelCounts(self, cCount: int, wCount: int, pCount: int) -> None:
"""Slot for the word counter's finished signal
"""
"""Update the counts on the counter's finished signal."""
if self._docHandle is None or self._nwItem is None:
return
@@ -1294,25 +1267,6 @@ class GuiDocEditor(QPlainTextEdit):
return
@pyqtSlot("QSizeF")
def _docSizeChanged(self, size: QSizeF) -> None:
"""Called whenever the underlying document layout size changes.
This is used to queue the repositioning of the cursor for very
large documents to ensure the region where the cursor is being
moved to has been drawn before the move is made.
"""
if self._queuePos is not None:
thePos = self.document().documentLayout().hitTest(
QPointF(size.width(), size.height()), Qt.FuzzyHit
)
if self._queuePos <= thePos:
logger.debug("Allowed cursor move to %d <= %d", self._queuePos, thePos)
self.setCursorPosition(self._queuePos)
self._queuePos = None
else:
logger.debug("Denied cursor move to %d > %d", self._queuePos, thePos)
return
##
# Search & Replace
##
+89 -90
View File
@@ -194,8 +194,7 @@ def testGuiEditor_MetaData(qtbot, nwGUI, projPath, mockRnd):
assert nwGUI.docEditor.isEmpty is False
# Cursor Position
assert nwGUI.docEditor.setCursorPosition(None) is False
assert nwGUI.docEditor.setCursorPosition(10) is True
nwGUI.docEditor.setCursorPosition(10)
assert nwGUI.docEditor.getCursorPosition() == 10
assert SHARED.project.tree[C.hSceneDoc].cursorPos != 10
nwGUI.docEditor.saveCursorPosition()
@@ -244,7 +243,7 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd):
theCursor.clearSelection()
# Select Paragraph
assert nwGUI.docEditor.setCursorPosition(1000) is True
nwGUI.docEditor.setCursorPosition(1000)
assert nwGUI.docEditor.getCursorPosition() == 1000
assert nwGUI.docEditor.docAction(nwDocAction.SEL_PARA) is True
theCursor = nwGUI.docEditor.textCursor()
@@ -252,7 +251,7 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd):
# Cut Selected Text
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(1000) is True
nwGUI.docEditor.setCursorPosition(1000)
assert nwGUI.docEditor.docAction(nwDocAction.SEL_PARA) is True
assert nwGUI.docEditor.docAction(nwDocAction.CUT) is True
@@ -270,12 +269,12 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd):
# Copy Next Paragraph
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(1500) is True
nwGUI.docEditor.setCursorPosition(1500)
assert nwGUI.docEditor.docAction(nwDocAction.SEL_PARA) is True
assert nwGUI.docEditor.docAction(nwDocAction.COPY) is True
# Paste at End
assert nwGUI.docEditor.setCursorPosition(theDoc.characterCount()) is True
nwGUI.docEditor.setCursorPosition(theDoc.characterCount())
theCursor = nwGUI.docEditor.textCursor()
theCursor.insertBlock()
theCursor.insertBlock()
@@ -295,21 +294,21 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd):
assert nwGUI.docEditor.replaceText(theText) is True
# Emphasis
assert nwGUI.docEditor.setCursorPosition(50) is True
nwGUI.docEditor.setCursorPosition(50)
assert nwGUI.docEditor.docAction(nwDocAction.EMPH) is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "_consectetur_")
assert nwGUI.docEditor.docAction(nwDocAction.UNDO) is True
assert nwGUI.docEditor.getText() == theText
# Strong
assert nwGUI.docEditor.setCursorPosition(50) is True
nwGUI.docEditor.setCursorPosition(50)
assert nwGUI.docEditor.docAction(nwDocAction.STRONG) is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "**consectetur**")
assert nwGUI.docEditor.docAction(nwDocAction.UNDO) is True
assert nwGUI.docEditor.getText() == theText
# Strikeout
assert nwGUI.docEditor.setCursorPosition(50) is True
nwGUI.docEditor.setCursorPosition(50)
assert nwGUI.docEditor.docAction(nwDocAction.STRIKE) is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "~~consectetur~~")
assert nwGUI.docEditor.docAction(nwDocAction.UNDO) is True
@@ -328,14 +327,14 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd):
assert nwGUI.docEditor.replaceText(theText) is True
# Add Single Quotes
assert nwGUI.docEditor.setCursorPosition(50) is True
nwGUI.docEditor.setCursorPosition(50)
assert nwGUI.docEditor.docAction(nwDocAction.S_QUOTE) is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "\u2018consectetur\u2019")
assert nwGUI.docEditor.docAction(nwDocAction.UNDO) is True
assert nwGUI.docEditor.getText() == theText
# Add Double Quotes
assert nwGUI.docEditor.setCursorPosition(50) is True
nwGUI.docEditor.setCursorPosition(50)
assert nwGUI.docEditor.docAction(nwDocAction.D_QUOTE) is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "\u201cconsectetur\u201d")
assert nwGUI.docEditor.docAction(nwDocAction.UNDO) is True
@@ -371,62 +370,62 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd):
assert nwGUI.docEditor.replaceText(theText) is True
# Header 1
assert nwGUI.docEditor.setCursorPosition(0) is True
nwGUI.docEditor.setCursorPosition(0)
assert nwGUI.docEditor.docAction(nwDocAction.BLOCK_H1) is True
assert nwGUI.docEditor.getText() == "# Scene Title\n\nScene text.\n\n"
# Header 2
assert nwGUI.docEditor.setCursorPosition(0) is True
nwGUI.docEditor.setCursorPosition(0)
assert nwGUI.docEditor.docAction(nwDocAction.BLOCK_H2) is True
assert nwGUI.docEditor.getText() == "## Scene Title\n\nScene text.\n\n"
# Header 3
assert nwGUI.docEditor.setCursorPosition(0) is True
nwGUI.docEditor.setCursorPosition(0)
assert nwGUI.docEditor.docAction(nwDocAction.BLOCK_H3) is True
assert nwGUI.docEditor.getText() == "### Scene Title\n\nScene text.\n\n"
# Header 4
assert nwGUI.docEditor.setCursorPosition(0) is True
nwGUI.docEditor.setCursorPosition(0)
assert nwGUI.docEditor.docAction(nwDocAction.BLOCK_H4) is True
assert nwGUI.docEditor.getText() == "#### Scene Title\n\nScene text.\n\n"
# Comment
assert nwGUI.docEditor.setCursorPosition(20) is True
nwGUI.docEditor.setCursorPosition(20)
assert nwGUI.docEditor.docAction(nwDocAction.BLOCK_COM) is True
assert nwGUI.docEditor.getText() == "#### Scene Title\n\n% Scene text.\n\n"
# Text
assert nwGUI.docEditor.setCursorPosition(20) is True
nwGUI.docEditor.setCursorPosition(20)
assert nwGUI.docEditor.docAction(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "#### Scene Title\n\nScene text.\n\n"
# Align Left
assert nwGUI.docEditor.setCursorPosition(20) is True
nwGUI.docEditor.setCursorPosition(20)
assert nwGUI.docEditor.docAction(nwDocAction.ALIGN_L) is True
assert nwGUI.docEditor.getText() == "#### Scene Title\n\nScene text. <<\n\n"
# Align Right
assert nwGUI.docEditor.setCursorPosition(20) is True
nwGUI.docEditor.setCursorPosition(20)
assert nwGUI.docEditor.docAction(nwDocAction.ALIGN_R) is True
assert nwGUI.docEditor.getText() == "#### Scene Title\n\n>> Scene text.\n\n"
# Align Centre
assert nwGUI.docEditor.setCursorPosition(20) is True
nwGUI.docEditor.setCursorPosition(20)
assert nwGUI.docEditor.docAction(nwDocAction.ALIGN_C) is True
assert nwGUI.docEditor.getText() == "#### Scene Title\n\n>> Scene text. <<\n\n"
# Indent Left
assert nwGUI.docEditor.setCursorPosition(20) is True
nwGUI.docEditor.setCursorPosition(20)
assert nwGUI.docEditor.docAction(nwDocAction.INDENT_L) is True
assert nwGUI.docEditor.getText() == "#### Scene Title\n\n> Scene text.\n\n"
# Indent Right
assert nwGUI.docEditor.setCursorPosition(20) is True
nwGUI.docEditor.setCursorPosition(20)
assert nwGUI.docEditor.docAction(nwDocAction.INDENT_R) is True
assert nwGUI.docEditor.getText() == "#### Scene Title\n\n> Scene text. <\n\n"
# Text (Reset)
assert nwGUI.docEditor.setCursorPosition(20) is True
nwGUI.docEditor.setCursorPosition(20)
assert nwGUI.docEditor.docAction(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "#### Scene Title\n\nScene text.\n\n"
@@ -466,28 +465,28 @@ def testGuiEditor_Insert(qtbot, monkeypatch, nwGUI, projPath, ipsumText, mockRnd
# No Document Handle
nwGUI.docEditor._docHandle = None
assert nwGUI.docEditor.setCursorPosition(24) is True
nwGUI.docEditor.setCursorPosition(24)
assert nwGUI.docEditor.insertText("Stuff") is False
nwGUI.docEditor._docHandle = C.hSceneDoc
# Insert String
assert nwGUI.docEditor.setCursorPosition(24) is True
nwGUI.docEditor.setCursorPosition(24)
assert nwGUI.docEditor.insertText(", ipsumer,") is True
assert nwGUI.docEditor.getText() == theText[:24] + ", ipsumer," + theText[24:]
# Single Quotes
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(41) is True
nwGUI.docEditor.setCursorPosition(41)
assert nwGUI.docEditor.insertText(nwDocInsert.QUOTE_LS) is True
assert nwGUI.docEditor.setCursorPosition(53) is True
nwGUI.docEditor.setCursorPosition(53)
assert nwGUI.docEditor.insertText(nwDocInsert.QUOTE_RS) is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "\u2018consectetur\u2019")
# Double Quotes
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(41) is True
nwGUI.docEditor.setCursorPosition(41)
assert nwGUI.docEditor.insertText(nwDocInsert.QUOTE_LD) is True
assert nwGUI.docEditor.setCursorPosition(53) is True
nwGUI.docEditor.setCursorPosition(53)
assert nwGUI.docEditor.insertText(nwDocInsert.QUOTE_RD) is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "\u201cconsectetur\u201d")
@@ -519,7 +518,7 @@ def testGuiEditor_Insert(qtbot, monkeypatch, nwGUI, projPath, ipsumText, mockRnd
assert nwGUI.docEditor.insertKeyWord(nwKeyWords.POV_KEY) is False
# Insert In-Block
assert nwGUI.docEditor.setCursorPosition(20) is True
nwGUI.docEditor.setCursorPosition(20)
assert nwGUI.docEditor.insertKeyWord(nwKeyWords.CHAR_KEY) is True
assert nwGUI.docEditor.insertText("John")
assert nwGUI.docEditor.getText() == theText.replace(
@@ -546,7 +545,7 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex
# No Selection
theText = "### A Scene\n\n%s" % ipsumText[0]
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
theCursor = nwGUI.docEditor.textCursor()
assert nwGUI.docEditor._clearSurrounding(theCursor, 1) is False
@@ -554,7 +553,7 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex
# Clear Characters, 1 Layer
repText = theText.replace("consectetur", "=consectetur=")
assert nwGUI.docEditor.replaceText(repText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
theCursor = nwGUI.docEditor.textCursor()
theCursor.select(QTextCursor.WordUnderCursor)
@@ -564,7 +563,7 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex
# Clear Characters, 2 Layers
repText = theText.replace("consectetur", "==consectetur==")
assert nwGUI.docEditor.replaceText(repText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
theCursor = nwGUI.docEditor.textCursor()
theCursor.select(QTextCursor.WordUnderCursor)
@@ -576,7 +575,7 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex
theText = "### A Scene\n\n%s" % "\n\n".join(ipsumText[0:2])
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
# No Selection
with monkeypatch.context() as mp:
@@ -585,13 +584,13 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex
# Wrap Equal
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
assert nwGUI.docEditor._wrapSelection("=") is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "=consectetur=")
# Wrap Unequal
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
assert nwGUI.docEditor._wrapSelection("=", "*") is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "=consectetur*")
@@ -613,7 +612,7 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex
theText = "### A Scene\n\n%s" % "\n\n".join(ipsumText[0:2])
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
# No Selection
with monkeypatch.context() as mp:
@@ -622,7 +621,7 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex
# Wrap Single Equal
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
assert nwGUI.docEditor._toggleFormat(1, "=") is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "=consectetur=")
@@ -641,20 +640,20 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex
# Wrap Double Equal
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
assert nwGUI.docEditor._toggleFormat(2, "=") is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "==consectetur==")
# Toggle Double Equal
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
assert nwGUI.docEditor._toggleFormat(2, "=") is True
assert nwGUI.docEditor._toggleFormat(2, "=") is True
assert nwGUI.docEditor.getText() == theText
# Toggle Triple+Double Equal
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
assert nwGUI.docEditor._toggleFormat(3, "=") is True
assert nwGUI.docEditor._toggleFormat(2, "=") is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "=consectetur=")
@@ -662,7 +661,7 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex
# Toggle Unequal
repText = theText.replace("consectetur", "=consectetur==")
assert nwGUI.docEditor.replaceText(repText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
assert nwGUI.docEditor._toggleFormat(1, "=") is True
assert nwGUI.docEditor.getText() == theText.replace("consectetur", "consectetur=")
assert nwGUI.docEditor._toggleFormat(1, "=") is True
@@ -674,14 +673,14 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex
# No Selection
theText = "### A Scene\n\n%s" % ipsumText[0].replace("consectetur", "=consectetur=")
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
assert nwGUI.docEditor._replaceQuotes("=", "<", ">") is False
# First Paragraph Selected
# This should not replace anything in second paragraph
theText = "### A Scene\n\n%s" % "\n\n".join(ipsumText[0:2]).replace("ipsum", "=ipsum=")
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
assert nwGUI.docEditor.docAction(nwDocAction.SEL_PARA)
assert nwGUI.docEditor._replaceQuotes("=", "<", ">") is True
@@ -693,7 +692,7 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex
# Edge of Document
theText = ipsumText[0].replace("Lorem", "=Lorem=")
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
assert nwGUI.docEditor.docAction(nwDocAction.SEL_ALL)
assert nwGUI.docEditor._replaceQuotes("=", "<", ">") is True
assert nwGUI.docEditor.getText() == theText.replace("=Lorem=", "<Lorem>")
@@ -707,7 +706,7 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex
# Remove All
theText = "### A Scene\n\n%s\n\n%s" % (parOne, parTwo)
assert nwGUI.docEditor.replaceText(theText) is True
assert nwGUI.docEditor.setCursorPosition(45) is True
nwGUI.docEditor.setCursorPosition(45)
nwGUI.docEditor._removeInParLineBreaks()
assert nwGUI.docEditor.getText() == "### A Scene\n\n%s\n" % "\n\n".join(ipsumText[0:2])
@@ -753,21 +752,21 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText
assert nwGUI.docEditor.replaceText(theText) is True
# Invalid Block
assert nwGUI.docEditor.setCursorPosition(0) is True
nwGUI.docEditor.setCursorPosition(0)
with monkeypatch.context() as mp:
mp.setattr(QTextBlock, "isValid", lambda *a, **k: False)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is False
# Keyword
assert nwGUI.docEditor.replaceText("@pov: Jane\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is False
assert nwGUI.docEditor.getText() == "@pov: Jane\n\n"
assert nwGUI.docEditor.getCursorPosition() == 5
# Unsupported Format
assert nwGUI.docEditor.replaceText("% Comment\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.NO_ACTION) is False
# Block Stripping : Left Side
@@ -775,91 +774,91 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText
# Strip Comment w/Space
assert nwGUI.docEditor.replaceText("% Comment\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Comment\n\n"
assert nwGUI.docEditor.getCursorPosition() == 3
# Strip Comment wo/Space
assert nwGUI.docEditor.replaceText("%Comment\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Comment\n\n"
assert nwGUI.docEditor.getCursorPosition() == 4
# Strip Header 1
assert nwGUI.docEditor.replaceText("# Title\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Title\n\n"
assert nwGUI.docEditor.getCursorPosition() == 3
# Strip Header 2
assert nwGUI.docEditor.replaceText("## Title\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Title\n\n"
assert nwGUI.docEditor.getCursorPosition() == 2
# Strip Header 3
assert nwGUI.docEditor.replaceText("### Title\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Title\n\n"
assert nwGUI.docEditor.getCursorPosition() == 1
# Strip Header 4
assert nwGUI.docEditor.replaceText("#### Title\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Title\n\n"
assert nwGUI.docEditor.getCursorPosition() == 0
# Strip Novel Title
assert nwGUI.docEditor.replaceText("#! Title\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Title\n\n"
assert nwGUI.docEditor.getCursorPosition() == 2
# Strip Unnumbered CHapter
assert nwGUI.docEditor.replaceText("##! Title\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Title\n\n"
assert nwGUI.docEditor.getCursorPosition() == 1
# Strip Text
assert nwGUI.docEditor.replaceText("Generic text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Generic text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 5
# Strip Left Angle Brackets : Double w/Space
assert nwGUI.docEditor.replaceText(">> Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 2
# Strip Left Angle Brackets : Single w/Space
assert nwGUI.docEditor.replaceText("> Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 3
# Strip Left Angle Brackets : Double wo/Space
assert nwGUI.docEditor.replaceText(">>Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 3
# Strip Left Angle Brackets : Single wo/Space
assert nwGUI.docEditor.replaceText(">Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 4
@@ -869,28 +868,28 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText
# Strip Right Angle Brackets : Double w/Space
assert nwGUI.docEditor.replaceText("Some text <<\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 5
# Strip Right Angle Brackets : Single w/Space
assert nwGUI.docEditor.replaceText("Some text <\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 5
# Strip Right Angle Brackets : Double wo/Space
assert nwGUI.docEditor.replaceText("Some text<<\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 5
# Strip Right Angle Brackets : Single wo/Space
assert nwGUI.docEditor.replaceText("Some text<\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 5
@@ -915,84 +914,84 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText
# Comment
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_COM) is True
assert nwGUI.docEditor.getText() == "% Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 7
# Toggle Comment w/Space
assert nwGUI.docEditor.replaceText("% Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_COM) is True
assert nwGUI.docEditor.getText() == "Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 3
# Toggle Comment wo/Space
assert nwGUI.docEditor.replaceText("%Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_COM) is True
assert nwGUI.docEditor.getText() == "Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 4
# Header 1
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_H1) is True
assert nwGUI.docEditor.getText() == "# Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 7
# Header 2
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_H2) is True
assert nwGUI.docEditor.getText() == "## Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 8
# Header 3
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_H3) is True
assert nwGUI.docEditor.getText() == "### Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 9
# Header 4
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_H4) is True
assert nwGUI.docEditor.getText() == "#### Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 10
# Novel Title
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TTL) is True
assert nwGUI.docEditor.getText() == "#! Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 8
# Unnumbered Chapter
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_UNN) is True
assert nwGUI.docEditor.getText() == "##! Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 9
# Left Indent
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.INDENT_L) is True
assert nwGUI.docEditor.getText() == "> Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 7
# Right Indent
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.INDENT_R) is True
assert nwGUI.docEditor.getText() == "Some text <\n\n"
assert nwGUI.docEditor.getCursorPosition() == 5
# Right/Left Indent
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.INDENT_L) is True
assert nwGUI.docEditor._formatBlock(nwDocAction.INDENT_R) is True
assert nwGUI.docEditor.getText() == "> Some text <\n\n"
@@ -1000,28 +999,28 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText
# Left Align
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.ALIGN_L) is True
assert nwGUI.docEditor.getText() == "Some text <<\n\n"
assert nwGUI.docEditor.getCursorPosition() == 5
# Right Align
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.ALIGN_R) is True
assert nwGUI.docEditor.getText() == ">> Some text\n\n"
assert nwGUI.docEditor.getCursorPosition() == 8
# Centre Align
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.ALIGN_C) is True
assert nwGUI.docEditor.getText() == ">> Some text <<\n\n"
assert nwGUI.docEditor.getCursorPosition() == 8
# Left/Right Align (Overrides)
assert nwGUI.docEditor.replaceText("Some text\n\n") is True
assert nwGUI.docEditor.setCursorPosition(5) is True
nwGUI.docEditor.setCursorPosition(5)
assert nwGUI.docEditor._formatBlock(nwDocAction.ALIGN_L) is True
assert nwGUI.docEditor._formatBlock(nwDocAction.ALIGN_R) is True
assert nwGUI.docEditor.getText() == ">> Some text\n\n"
@@ -1032,7 +1031,7 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText
# Final Cursor Position Out of Range
assert nwGUI.docEditor.replaceText("#### Title\n\n") is True
assert nwGUI.docEditor.setCursorPosition(3) is True
nwGUI.docEditor.setCursorPosition(3)
assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True
assert nwGUI.docEditor.getText() == "Title\n\n"
assert nwGUI.docEditor.getCursorPosition() == 5
@@ -1081,21 +1080,21 @@ def testGuiEditor_Tags(qtbot, nwGUI, projPath, ipsumText, mockRnd):
assert nwGUI.docEditor._followTag() is False
# On Tag Keyword
assert nwGUI.docEditor.setCursorPosition(15) is True
nwGUI.docEditor.setCursorPosition(15)
assert nwGUI.docEditor._followTag() is False
# On Unknown Tag
assert nwGUI.docEditor.setCursorPosition(28) is True
nwGUI.docEditor.setCursorPosition(28)
assert nwGUI.docEditor._followTag() is True
assert nwGUI.docViewer._docHandle is None
# On Known Tag, No Follow
assert nwGUI.docEditor.setCursorPosition(22) is True
nwGUI.docEditor.setCursorPosition(22)
assert nwGUI.docEditor._followTag(loadTag=False) is True
assert nwGUI.docViewer._docHandle is None
# On Known Tag, Follow
assert nwGUI.docEditor.setCursorPosition(22) is True
nwGUI.docEditor.setCursorPosition(22)
assert nwGUI.docViewer._docHandle is None
assert nwGUI.docEditor._followTag(loadTag=True) is True
assert nwGUI.docViewer._docHandle == cHandle
@@ -1228,7 +1227,7 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, prjLipsum):
# Close search
nwGUI.docEditor.docSearch.cancelSearch.activate(QAction.Trigger)
assert nwGUI.docEditor.docSearch.isVisible() is False
assert nwGUI.docEditor.setCursorPosition(15)
nwGUI.docEditor.setCursorPosition(15)
# Toggle search again with header button
qtbot.mouseClick(nwGUI.docEditor.docHeader.searchButton, Qt.LeftButton, delay=KEY_DELAY)
@@ -1298,7 +1297,7 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, prjLipsum):
assert nwGUI.docEditor.docSearch.doMatchCap is True
# Replace "Sus" with "Foo" via menu
assert nwGUI.docEditor.setCursorPosition(590)
nwGUI.docEditor.setCursorPosition(590)
nwGUI.mainMenu.aFindNext.activate(QAction.Trigger)
nwGUI.mainMenu.aReplaceNext.activate(QAction.Trigger)
assert nwGUI.docEditor.getText()[608:619] == "Foopendisse"
@@ -1327,7 +1326,7 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, prjLipsum):
# Close search and select "est" again
nwGUI.docEditor.docSearch.cancelSearch.activate(QAction.Trigger)
assert nwGUI.docEditor.setCursorPosition(630)
nwGUI.docEditor.setCursorPosition(630)
nwGUI.docEditor._makeSelection(QTextCursor.WordUnderCursor)
theCursor = nwGUI.docEditor.textCursor()
assert theCursor.selectedText() == "est"
+11 -12
View File
@@ -46,8 +46,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
# Split By Chapter
assert nwGUI.openDocument("4c4f28287af27") is True
assert nwGUI.docEditor.setCursorPosition(42) is True
nwGUI.docEditor.setCursorPosition(42)
cleanText = nwGUI.docEditor.getText()[39:86]
# Bold
@@ -95,7 +94,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
# Block Formats
# =============
# cSpell:ignore Pellentesque erat nulla posuere commodo
assert nwGUI.docEditor.setCursorPosition(42)
nwGUI.docEditor.setCursorPosition(42)
# Header 1
nwGUI.mainMenu.aFmtHead1.activate(QAction.Trigger)
@@ -141,7 +140,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
assert nwGUI.docEditor.getText()[39:86] == cleanText
# Check comment with no space before text
assert nwGUI.docEditor.setCursorPosition(39)
nwGUI.docEditor.setCursorPosition(39)
assert nwGUI.docEditor.insertText("%")
fmtStr = "%Pellentesque nec erat ut nulla posuere commodo."
assert nwGUI.docEditor.getText()[39:87] == fmtStr
@@ -157,7 +156,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
assert nwGUI.docEditor.getText()[39:86] == cleanText
# Cut, Copy and Paste
assert nwGUI.docEditor.setCursorPosition(39)
nwGUI.docEditor.setCursorPosition(39)
nwGUI.docEditor._makeSelection(QTextCursor.WordUnderCursor)
nwGUI.mainMenu.aEditCut.activate(QAction.Trigger)
@@ -170,7 +169,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
"Pellentesque nec erat ut nulla posuere commodo. Cu"
)
assert nwGUI.docEditor.setCursorPosition(39)
nwGUI.docEditor.setCursorPosition(39)
nwGUI.docEditor._makeSelection(QTextCursor.WordUnderCursor)
nwGUI.mainMenu.aEditCopy.activate(QAction.Trigger)
@@ -178,7 +177,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
"Pellentesque nec erat ut nulla posuere commodo. Cu"
)
assert nwGUI.docEditor.setCursorPosition(39)
nwGUI.docEditor.setCursorPosition(39)
nwGUI.mainMenu.aEditPaste.activate(QAction.Trigger)
assert nwGUI.docEditor.getText()[39:89] == (
"PellentesquePellentesque nec erat ut nulla posuere"
@@ -186,7 +185,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
nwGUI.mainMenu.aEditUndo.activate(QAction.Trigger)
# Select Paragraph/All
assert nwGUI.docEditor.setCursorPosition(42)
nwGUI.docEditor.setCursorPosition(42)
nwGUI.mainMenu.aSelectPar.activate(QAction.Trigger)
theCursor = nwGUI.docEditor.textCursor()
assert theCursor.selectedText() == (
@@ -199,7 +198,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
"nunc lacus, imperdiet nec posuere ac, interdum non lectus."
)
assert nwGUI.docEditor.setCursorPosition(42)
nwGUI.docEditor.setCursorPosition(42)
nwGUI.mainMenu.aSelectAll.activate(QAction.Trigger)
theCursor = nwGUI.docEditor.textCursor()
assert len(theCursor.selectedText()) == 1895
@@ -213,7 +212,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
cleanText = "A single, short paragraph.\n\n"
nwGUI.docEditor.setPlainText(cleanText)
assert nwGUI.docEditor.setCursorPosition(0)
nwGUI.docEditor.setCursorPosition(0)
# Left Align
nwGUI.mainMenu.aFmtAlignLeft.activate(QAction.Trigger)
@@ -322,11 +321,11 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum):
))
# Cannot Format Tag
assert nwGUI.docEditor.setCursorPosition(17)
nwGUI.docEditor.setCursorPosition(17)
assert not nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT)
# Invalid Action
assert nwGUI.docEditor.setCursorPosition(30)
nwGUI.docEditor.setCursorPosition(30)
assert not nwGUI.docEditor._formatBlock(nwDocAction.NO_ACTION)
# Ensure No Changes