From 2b98e0d4d293198ac42f8584dc76190f898bd47d Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 6 Sep 2023 17:47:25 +0200 Subject: [PATCH 1/5] Make the editor a plain text editor again --- novelwriter/gui/doceditor.py | 17 ++++++------ tests/test_gui/test_gui_doceditor.py | 2 +- tests/test_gui/test_gui_mainmenu.py | 40 ++++++++++++++-------------- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 58f718f4..5e8ffb25 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -42,11 +42,13 @@ from PyQt5.QtCore import ( ) from PyQt5.QtGui import ( QColor, QCursor, QFont, QFontMetrics, QKeyEvent, QKeySequence, QMouseEvent, - QPalette, QPixmap, QResizeEvent, QTextBlock, QTextCursor, QTextDocument, QTextOption + QPalette, QPixmap, QResizeEvent, QTextBlock, QTextCursor, QTextDocument, + QTextOption ) from PyQt5.QtWidgets import ( - QAction, qApp, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QMenu, - QPushButton, QShortcut, QTextEdit, QToolBar, QToolButton, QWidget + QAction, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QMenu, + QPlainTextEdit, QPushButton, QShortcut, QToolBar, QToolButton, QWidget, + qApp ) from novelwriter import CONFIG, SHARED @@ -63,7 +65,7 @@ if TYPE_CHECKING: # pragma: no cover logger = logging.getLogger(__name__) -class GuiDocEditor(QTextEdit): +class GuiDocEditor(QPlainTextEdit): """Gui Widget: Main Document Editor""" MOVE_KEYS = ( @@ -141,7 +143,6 @@ class GuiDocEditor(QTextEdit): # Editor Settings self.setMinimumWidth(CONFIG.pxInt(300)) - self.setAcceptRichText(False) self.setAutoFillBackground(True) self.setFrameStyle(QFrame.NoFrame) @@ -678,9 +679,9 @@ class GuiDocEditor(QTextEdit): lineIdx = line - 1 # Block index is 0 offset, lineNo is 1 offset if lineIdx >= 0: - theBlock = self.document().findBlockByLineNumber(lineIdx) - if theBlock: - self.setCursorPosition(theBlock.position()) + block = self.document().findBlockByNumber(lineIdx) + if block: + self.setCursorPosition(block.position()) logger.debug("Cursor moved to line %d", line) return True diff --git a/tests/test_gui/test_gui_doceditor.py b/tests/test_gui/test_gui_doceditor.py index 0bf4afe2..2e0c046f 100644 --- a/tests/test_gui/test_gui_doceditor.py +++ b/tests/test_gui/test_gui_doceditor.py @@ -44,7 +44,7 @@ def testGuiEditor_Init(qtbot, nwGUI, projPath, ipsumText, mockRnd): buildTestProject(nwGUI, projPath) assert nwGUI.openDocument(C.hSceneDoc) - nwGUI.docEditor.setText("### Lorem Ipsum\n\n%s" % ipsumText[0]) + nwGUI.docEditor.setPlainText("### Lorem Ipsum\n\n%s" % ipsumText[0]) assert nwGUI.saveDocument() # Check Defaults diff --git a/tests/test_gui/test_gui_mainmenu.py b/tests/test_gui/test_gui_mainmenu.py index 1ea0a680..a667331d 100644 --- a/tests/test_gui/test_gui_mainmenu.py +++ b/tests/test_gui/test_gui_mainmenu.py @@ -212,7 +212,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum): # ================== cleanText = "A single, short paragraph.\n\n" - nwGUI.docEditor.setText(cleanText) + nwGUI.docEditor.setPlainText(cleanText) assert nwGUI.docEditor.setCursorPosition(0) # Left Align @@ -247,7 +247,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum): # Other Checks # Replace Quotes - nwGUI.docEditor.setText(( + nwGUI.docEditor.setPlainText(( "### New Text\n\n" "Text with 'single' quotes and 'tricky stuff's'.\n\n" "Also text with \"double\" quotes which are \"less tricky\".\n\n" @@ -270,7 +270,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum): ) # Remove in-paragraph line breaks - nwGUI.docEditor.setText(( + nwGUI.docEditor.setPlainText(( "### New Text\n\n" "@char: Someone\n" "@location: Somewhere\n\n" @@ -288,7 +288,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum): "With another paragraph here.\n" ) - nwGUI.docEditor.setText(( + nwGUI.docEditor.setPlainText(( "### New Text\n\n" "@char: Someone\n" "@location: Somewhere\n\n" @@ -314,7 +314,7 @@ def testGuiMenu_EditFormat(qtbot, monkeypatch, nwGUI, prjLipsum): assert not nwGUI.docEditor.docAction(nwDocAction.NO_ACTION) # Test Invalid Formats - nwGUI.docEditor.setText(( + nwGUI.docEditor.setPlainText(( "### New Text\n\n" "@tag: Bod\n\n" "Text with 'single' quotes and 'tricky stuff's'.\n\n" @@ -541,43 +541,43 @@ def testGuiMenu_Insert(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockRnd): # Insert Keywords # =============== - nwGUI.docEditor.setText("Stuff") + nwGUI.docEditor.setPlainText("Stuff") nwGUI.mainMenu.mInsKWItems[nwKeyWords.TAG_KEY][0].activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.TAG_KEY - nwGUI.docEditor.setText("Stuff") + nwGUI.docEditor.setPlainText("Stuff") nwGUI.mainMenu.mInsKWItems[nwKeyWords.POV_KEY][0].activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.POV_KEY - nwGUI.docEditor.setText("Stuff") + nwGUI.docEditor.setPlainText("Stuff") nwGUI.mainMenu.mInsKWItems[nwKeyWords.FOCUS_KEY][0].activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.FOCUS_KEY - nwGUI.docEditor.setText("Stuff") + nwGUI.docEditor.setPlainText("Stuff") nwGUI.mainMenu.mInsKWItems[nwKeyWords.CHAR_KEY][0].activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.CHAR_KEY - nwGUI.docEditor.setText("Stuff") + nwGUI.docEditor.setPlainText("Stuff") nwGUI.mainMenu.mInsKWItems[nwKeyWords.PLOT_KEY][0].activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.PLOT_KEY - nwGUI.docEditor.setText("Stuff") + nwGUI.docEditor.setPlainText("Stuff") nwGUI.mainMenu.mInsKWItems[nwKeyWords.TIME_KEY][0].activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.TIME_KEY - nwGUI.docEditor.setText("Stuff") + nwGUI.docEditor.setPlainText("Stuff") nwGUI.mainMenu.mInsKWItems[nwKeyWords.WORLD_KEY][0].activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.WORLD_KEY - nwGUI.docEditor.setText("Stuff") + nwGUI.docEditor.setPlainText("Stuff") nwGUI.mainMenu.mInsKWItems[nwKeyWords.OBJECT_KEY][0].activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.OBJECT_KEY - nwGUI.docEditor.setText("Stuff") + nwGUI.docEditor.setPlainText("Stuff") nwGUI.mainMenu.mInsKWItems[nwKeyWords.ENTITY_KEY][0].activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.ENTITY_KEY - nwGUI.docEditor.setText("Stuff") + nwGUI.docEditor.setPlainText("Stuff") nwGUI.mainMenu.mInsKWItems[nwKeyWords.CUSTOM_KEY][0].activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "Stuff\n%s: " % nwKeyWords.CUSTOM_KEY @@ -592,22 +592,22 @@ def testGuiMenu_Insert(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockRnd): # Insert Special Comments # ======================= - nwGUI.docEditor.setText("Stuff\n") + nwGUI.docEditor.setPlainText("Stuff\n") nwGUI.mainMenu.aInsSynopsis.activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "Stuff\n% Synopsis: \n" # Insert Break or Space # ===================== - nwGUI.docEditor.setText("### Stuff\n") + nwGUI.docEditor.setPlainText("### Stuff\n") nwGUI.mainMenu.aInsNewPage.activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "[NEW PAGE]\n### Stuff\n" - nwGUI.docEditor.setText("### Stuff\n") + nwGUI.docEditor.setPlainText("### Stuff\n") nwGUI.mainMenu.aInsVSpaceS.activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "[VSPACE]\n### Stuff\n" - nwGUI.docEditor.setText("### Stuff\n") + nwGUI.docEditor.setPlainText("### Stuff\n") nwGUI.mainMenu.aInsVSpaceM.activate(QAction.Trigger) assert nwGUI.docEditor.getText() == "[VSPACE:2]\n### Stuff\n" @@ -637,7 +637,7 @@ def testGuiMenu_Insert(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockRnd): # Open the document from before, and add some text to it nwGUI.openDocument(C.hSceneDoc) - nwGUI.docEditor.setText("Bar") + nwGUI.docEditor.setPlainText("Bar") assert nwGUI.docEditor.getText() == "Bar" # The document isn't empty, so the message box should pop From 8c3e906fc5d47ab4120d9a7a0d6ffee3b9c4d488 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 6 Sep 2023 17:56:39 +0200 Subject: [PATCH 2/5] Remove the big doc limit feature --- novelwriter/config.py | 3 -- novelwriter/dialogs/preferences.py | 17 +------ novelwriter/gui/doceditor.py | 44 +------------------ tests/reference/baseConfig_novelwriter.conf | 1 - .../reference/guiPreferences_novelwriter.conf | 1 - tests/test_dialogs/test_dlg_preferences.py | 3 -- tests/test_gui/test_gui_doceditor.py | 6 --- 7 files changed, 3 insertions(+), 72 deletions(-) diff --git a/novelwriter/config.py b/novelwriter/config.py index d0bd7fc3..526938de 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -149,7 +149,6 @@ class Config: self.autoScrollPos = 30 # Start point for typewriter-like scrolling self.wordCountTimer = 5.0 # Interval for word count update in seconds - self.bigDocLimit = 800 # Size threshold for heavy editor features in kilobytes self.incNotesWCount = True # The status bar word count includes notes self.highlightQuotes = True # Highlight text in quotes @@ -588,7 +587,6 @@ class Config: self.showLineEndings = conf.rdBool(sec, "showlineendings", self.showLineEndings) self.showMultiSpaces = conf.rdBool(sec, "showmultispaces", self.showMultiSpaces) self.wordCountTimer = conf.rdFlt(sec, "wordcounttimer", self.wordCountTimer) - self.bigDocLimit = conf.rdInt(sec, "bigdoclimit", self.bigDocLimit) self.incNotesWCount = conf.rdBool(sec, "incnoteswcount", self.incNotesWCount) self.showFullPath = conf.rdBool(sec, "showfullpath", self.showFullPath) self.highlightQuotes = conf.rdBool(sec, "highlightquotes", self.highlightQuotes) @@ -712,7 +710,6 @@ class Config: "showlineendings": str(self.showLineEndings), "showmultispaces": str(self.showMultiSpaces), "wordcounttimer": str(self.wordCountTimer), - "bigdoclimit": str(self.bigDocLimit), "incnoteswcount": str(self.incNotesWCount), "showfullpath": str(self.showFullPath), "highlightquotes": str(self.highlightQuotes), diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index 72120448..24bee775 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -675,19 +675,6 @@ class GuiPreferencesEditor(QWidget): self.tr("Available languages are determined by your system.") ) - # Big Document Size Limit - self.bigDocLimit = QSpinBox(self) - self.bigDocLimit.setMinimum(10) - self.bigDocLimit.setMaximum(10000) - self.bigDocLimit.setSingleStep(10) - self.bigDocLimit.setValue(CONFIG.bigDocLimit) - self.mainForm.addRow( - self.tr("Big document limit"), - self.bigDocLimit, - self.tr("Full spell checking is disabled above this limit."), - unit=self.tr("kB") - ) - # Word Count # ========== self.mainForm.addGroupLabel(self.tr("Word Count")) @@ -775,11 +762,9 @@ class GuiPreferencesEditor(QWidget): return def saveValues(self): - """Save the values set for this tab. - """ + """Save the values set for this tab.""" # Spell Checking CONFIG.spellLanguage = self.spellLanguage.currentData() - CONFIG.bigDocLimit = self.bigDocLimit.value() # Word Count CONFIG.wordCountTimer = self.wordCountTimer.value() diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 5e8ffb25..cf018b56 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -106,7 +106,6 @@ class GuiDocEditor(QPlainTextEdit): self._lastEdit = 0 # Time stamp of last edit self._lastActive = 0.0 # Time stamp of last activity self._lastFind = None # Position of the last found search word - self._bigDoc = False # Flag for very large document size self._doReplace = False # Switch to temporarily disable auto-replace self._queuePos = None # Used for delayed change of cursor position @@ -238,7 +237,6 @@ class GuiDocEditor(QPlainTextEdit): self._lastEdit = 0 self._lastActive = 0.0 self._lastFind = None - self._bigDoc = False self._doReplace = False self._queuePos = None @@ -396,13 +394,6 @@ class GuiDocEditor(QPlainTextEdit): qApp.setOverrideCursor(QCursor(Qt.WaitCursor)) self.highLight.setHandle(tHandle) - # Check that the document is not too big for full, initial spell - # checking. If it is too big, we switch to only check as we type - self._checkDocSize(docSize) - spTemp = self.highLight.spellCheck - if self._bigDoc: - self.highLight.setSpellCheck(False) - bfTime = time() self._allowAutoReplace(False) self.setPlainText(theDoc) @@ -422,7 +413,6 @@ class GuiDocEditor(QPlainTextEdit): self.docHeader.setTitleFromHandle(self._docHandle) self.docFooter.setHandle(self._docHandle) self.updateDocMargins() - self.highLight.setSpellCheck(spTemp) if tLine is None and self._nwItem is not None: # For large documents, we queue the repositioning until the @@ -714,8 +704,7 @@ class GuiDocEditor(QPlainTextEdit): self.mainGui.mainMenu.setSpellCheck(state) SHARED.project.data.setSpellCheck(state) self.highLight.setSpellCheck(state) - if not self._bigDoc or state is False: - # We don't run the spell checker automatically on big docs + if state is False: self.spellCheckDocument() logger.debug("Spell check is set to '%s'", str(state)) @@ -731,11 +720,7 @@ class GuiDocEditor(QPlainTextEdit): logger.debug("Running spell checker") start = time() qApp.setOverrideCursor(QCursor(Qt.WaitCursor)) - if self._bigDoc: - # This is much faster for large documents - self.setPlainText(self.getText()) - else: - self.highLight.rehighlight() + self.highLight.rehighlight() qApp.restoreOverrideCursor() logger.debug("Document highlighted in %.3f ms", 1000*(time() - start)) self.statusMessage.emit(self.tr("Spell check complete")) @@ -1261,8 +1246,6 @@ class GuiDocEditor(QPlainTextEdit): # Must not be emitted if docHandle is None! self.docCountsChanged.emit(self._docHandle, cCount, wCount, pCount) - - self._checkDocSize(self.document().characterCount()) self.docFooter.updateCounts() return @@ -2022,29 +2005,6 @@ class GuiDocEditor(QPlainTextEdit): return False return True - def _checkDocSize(self, size: int) -> None: - """Check if document size crosses the big document limit set in - config. If so, we will set the big document flag to True. - """ - bigLim = round(CONFIG.bigDocLimit*1000) - newState = size > bigLim - - if newState != self._bigDoc: - if newState: - logger.info( - f"The document size is {size:n} > {bigLim:n}, " - f"big doc mode has been enabled" - ) - else: - logger.info( - f"The document size is {size:n} <= {bigLim:n}, " - f"big doc mode has been disabled" - ) - - self._bigDoc = newState - - return - def _autoSelect(self) -> QTextCursor: """Return a cursor which may or may not have a selection based on user settings and document action. diff --git a/tests/reference/baseConfig_novelwriter.conf b/tests/reference/baseConfig_novelwriter.conf index e1554e94..2f4b05e1 100644 --- a/tests/reference/baseConfig_novelwriter.conf +++ b/tests/reference/baseConfig_novelwriter.conf @@ -58,7 +58,6 @@ showtabsnspaces = False showlineendings = False showmultispaces = True wordcounttimer = 5.0 -bigdoclimit = 800 incnoteswcount = True showfullpath = True highlightquotes = True diff --git a/tests/reference/guiPreferences_novelwriter.conf b/tests/reference/guiPreferences_novelwriter.conf index de16e4e6..a8700427 100644 --- a/tests/reference/guiPreferences_novelwriter.conf +++ b/tests/reference/guiPreferences_novelwriter.conf @@ -58,7 +58,6 @@ showtabsnspaces = True showlineendings = True showmultispaces = True wordcounttimer = 5.0 -bigdoclimit = 500 incnoteswcount = True showfullpath = False highlightquotes = False diff --git a/tests/test_dialogs/test_dlg_preferences.py b/tests/test_dialogs/test_dlg_preferences.py index 14712795..fe6b807a 100644 --- a/tests/test_dialogs/test_dlg_preferences.py +++ b/tests/test_dialogs/test_dlg_preferences.py @@ -159,9 +159,6 @@ def testDlgPreferences_Main(qtbot, monkeypatch, nwGUI, tstPaths): qtbot.wait(KEY_DELAY) tabEditor.scrollPastEnd.setValue(0) - qtbot.wait(KEY_DELAY) - tabEditor.bigDocLimit.setValue(500) - # Syntax Settings qtbot.wait(KEY_DELAY) tabSyntax = nwPrefs.tabSyntax diff --git a/tests/test_gui/test_gui_doceditor.py b/tests/test_gui/test_gui_doceditor.py index 2e0c046f..7e3cbc26 100644 --- a/tests/test_gui/test_gui_doceditor.py +++ b/tests/test_gui/test_gui_doceditor.py @@ -104,7 +104,6 @@ def testGuiEditor_LoadText(qtbot, monkeypatch, caplog, nwGUI, projPath, ipsumTex # Regular open assert nwGUI.docEditor.loadText(C.hSceneDoc) is True - assert nwGUI.docEditor._bigDoc is False # Reload too big text with monkeypatch.context() as mp: @@ -112,11 +111,6 @@ def testGuiEditor_LoadText(qtbot, monkeypatch, caplog, nwGUI, projPath, ipsumTex assert nwGUI.docEditor.replaceText(longText) is False assert "The document you are trying to open is too big." in caplog.text - # Big doc handling - CONFIG.bigDocLimit = 50 - assert nwGUI.docEditor.loadText(C.hSceneDoc) is True - assert nwGUI.docEditor._bigDoc is True - # Regular open, with line number (1 indexed) assert nwGUI.docEditor.loadText(C.hSceneDoc, tLine=4) is True cursPos = nwGUI.docEditor.getCursorPosition() From 0bfa3cb592b30bb9bafc9c3d23b4a219555953f0 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 6 Sep 2023 18:20:25 +0200 Subject: [PATCH 3/5] Simplify setting cursor position in the editor --- novelwriter/gui/doceditor.py | 68 ++-------- tests/test_gui/test_gui_doceditor.py | 179 +++++++++++++-------------- tests/test_gui/test_gui_mainmenu.py | 23 ++-- 3 files changed, 111 insertions(+), 159 deletions(-) diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index cf018b56..2d9b5847 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -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 ## diff --git a/tests/test_gui/test_gui_doceditor.py b/tests/test_gui/test_gui_doceditor.py index 7e3cbc26..547c7649 100644 --- a/tests/test_gui/test_gui_doceditor.py +++ b/tests/test_gui/test_gui_doceditor.py @@ -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=", "") @@ -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" diff --git a/tests/test_gui/test_gui_mainmenu.py b/tests/test_gui/test_gui_mainmenu.py index a667331d..5fe1ae49 100644 --- a/tests/test_gui/test_gui_mainmenu.py +++ b/tests/test_gui/test_gui_mainmenu.py @@ -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 From 0ef46ef0ea4841aa1d844b5dbe59eef58a82d811 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 6 Sep 2023 20:05:13 +0200 Subject: [PATCH 4/5] Simplify editor scrolling features --- novelwriter/config.py | 3 - novelwriter/dialogs/preferences.py | 14 ---- novelwriter/gui/doceditor.py | 65 ++++++------------- tests/reference/baseConfig_novelwriter.conf | 1 - .../reference/guiPreferences_novelwriter.conf | 1 - tests/test_dialogs/test_dlg_preferences.py | 3 - tests/test_gui/test_gui_doceditor.py | 13 ++-- 7 files changed, 28 insertions(+), 72 deletions(-) diff --git a/novelwriter/config.py b/novelwriter/config.py index 526938de..c7994d1c 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -144,7 +144,6 @@ class Config: self.doReplaceDash = True # Replace multiple hyphens with dashes self.doReplaceDots = True # Replace three dots with ellipsis - self.scrollPastEnd = 25 # Number of lines to scroll past end of document self.autoScroll = False # Typewriter-like scrolling self.autoScrollPos = 30 # Start point for typewriter-like scrolling @@ -572,7 +571,6 @@ class Config: self.doReplaceDQuote = conf.rdBool(sec, "repdquotes", self.doReplaceDQuote) self.doReplaceDash = conf.rdBool(sec, "repdash", self.doReplaceDash) self.doReplaceDots = conf.rdBool(sec, "repdots", self.doReplaceDots) - self.scrollPastEnd = conf.rdInt(sec, "scrollpastend", self.scrollPastEnd) self.autoScroll = conf.rdBool(sec, "autoscroll", self.autoScroll) self.autoScrollPos = conf.rdInt(sec, "autoscrollpos", self.autoScrollPos) self.fmtSQuoteOpen = conf.rdStr(sec, "fmtsquoteopen", self.fmtSQuoteOpen) @@ -695,7 +693,6 @@ class Config: "repdquotes": str(self.doReplaceDQuote), "repdash": str(self.doReplaceDash), "repdots": str(self.doReplaceDots), - "scrollpastend": str(self.scrollPastEnd), "autoscroll": str(self.autoScroll), "autoscrollpos": str(self.autoScrollPos), "fmtsquoteopen": str(self.fmtSQuoteOpen), diff --git a/novelwriter/dialogs/preferences.py b/novelwriter/dialogs/preferences.py index 24bee775..76178d05 100644 --- a/novelwriter/dialogs/preferences.py +++ b/novelwriter/dialogs/preferences.py @@ -724,19 +724,6 @@ class GuiPreferencesEditor(QWidget): # ================ self.mainForm.addGroupLabel(self.tr("Scroll Behaviour")) - # Scroll Past End - self.scrollPastEnd = QSpinBox(self) - self.scrollPastEnd.setMinimum(0) - self.scrollPastEnd.setMaximum(100) - self.scrollPastEnd.setSingleStep(1) - self.scrollPastEnd.setValue(int(CONFIG.scrollPastEnd)) - self.mainForm.addRow( - self.tr("Scroll past end of the document"), - self.scrollPastEnd, - self.tr("Set to 0 to disable this feature."), - unit=self.tr("lines") - ) - # Typewriter Scrolling self.autoScroll = NSwitch() self.autoScroll.setChecked(CONFIG.autoScroll) @@ -775,7 +762,6 @@ class GuiPreferencesEditor(QWidget): CONFIG.showLineEndings = self.showLineEndings.isChecked() # Scroll Behaviour - CONFIG.scrollPastEnd = self.scrollPastEnd.value() CONFIG.autoScroll = self.autoScroll.isChecked() CONFIG.autoScrollPos = self.autoScrollPos.value() diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index 2d9b5847..d74c50c7 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -37,13 +37,12 @@ from time import time from typing import TYPE_CHECKING from PyQt5.QtCore import ( - pyqtSignal, pyqtSlot, QObject, QPoint, QPropertyAnimation, QRegExp, - QRegularExpression, QRunnable, QSize, Qt, QTimer + pyqtSignal, pyqtSlot, QObject, QPoint, QRegExp, QRegularExpression, + QRunnable, QSize, Qt, QTimer ) from PyQt5.QtGui import ( - QColor, QCursor, QFont, QFontMetrics, QKeyEvent, QKeySequence, QMouseEvent, - QPalette, QPixmap, QResizeEvent, QTextBlock, QTextCursor, QTextDocument, - QTextOption + QColor, QCursor, QFont, QKeyEvent, QKeySequence, QMouseEvent, QPalette, + QPixmap, QResizeEvent, QTextBlock, QTextCursor, QTextDocument, QTextOption ) from PyQt5.QtWidgets import ( QAction, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QMenu, @@ -142,6 +141,7 @@ class GuiDocEditor(QPlainTextEdit): self.setMinimumWidth(CONFIG.pxInt(300)) self.setAutoFillBackground(True) self.setFrameStyle(QFrame.NoFrame) + self.setCenterOnScroll(True) # Custom Shortcuts self.keyContext = QShortcut(self) @@ -311,7 +311,7 @@ class GuiDocEditor(QPlainTextEdit): # Set default text margins # Due to cursor visibility, a part of the margin must be # allocated to the document itself. See issue #1112. - cW = self.cursorWidth() + cW = 2*self.cursorWidth() qDoc = self.document() qDoc.setDocumentMargin(cW) self._vpMargin = max(CONFIG.getTextMargin() - cW, 0) @@ -369,13 +369,13 @@ class GuiDocEditor(QPlainTextEdit): self._nwDocument = SHARED.project.storage.getDocument(tHandle) self._nwItem = self._nwDocument.nwItem - theDoc = self._nwDocument.readDocument() - if theDoc is None: + docText = self._nwDocument.readDocument() + if docText is None: # There was an io error self.clearEditor() return False - docSize = len(theDoc) + docSize = len(docText) if docSize > nwConst.MAX_DOCSIZE: SHARED.error(self.tr( "The document you are trying to open is too big. " @@ -389,22 +389,20 @@ class GuiDocEditor(QPlainTextEdit): return False qApp.setOverrideCursor(QCursor(Qt.WaitCursor)) + self._docHandle = tHandle self.highLight.setHandle(tHandle) - bfTime = time() + tStart = time() self._allowAutoReplace(False) - self.setPlainText(theDoc) - qApp.processEvents() - + self.setPlainText(docText) self._allowAutoReplace(True) - afTime = time() - logger.debug("Document highlighted in %.3f ms", 1000*(afTime-bfTime)) + logger.debug("Document text loaded in %.3f ms", 1000*(time() - tStart)) + qApp.processEvents() self._lastEdit = time() self._lastActive = time() self._runDocCounter() self.wcTimerDoc.start() - self._docHandle = tHandle self.setReadOnly(False) self.docHeader.setTitleFromHandle(self._docHandle) @@ -416,12 +414,6 @@ class GuiDocEditor(QPlainTextEdit): elif isinstance(tLine, int): self.setCursorLine(tLine) - if CONFIG.scrollPastEnd > 0: - fSize = QFontMetrics(self.font()).lineSpacing() - docFrame = self.document().rootFrame().frameFormat() - docFrame.setBottomMargin(round(CONFIG.scrollPastEnd * fSize)) - self.document().rootFrame().setFrameFormat(docFrame) - self.docFooter.updateLineCount() qApp.processEvents() @@ -636,19 +628,14 @@ class GuiDocEditor(QPlainTextEdit): self._nwItem.setCursorPos(cursPos) return - def setCursorLine(self, line: int | None) -> bool: + def setCursorLine(self, line: int | None) -> None: """Move the cursor to a given line in the document.""" - if not isinstance(line, int): - return False - - lineIdx = line - 1 # Block index is 0 offset, lineNo is 1 offset - if lineIdx >= 0: - block = self.document().findBlockByNumber(lineIdx) + if isinstance(line, int) and line > 0: + block = self.document().findBlockByNumber(line - 1) if block: self.setCursorPosition(block.position()) logger.debug("Cursor moved to line %d", line) - - return True + return ## # Spell Checking @@ -950,26 +937,16 @@ class GuiDocEditor(QPlainTextEdit): return if CONFIG.autoScroll: - - cOld = self.cursorRect().center().y() + cPos = self.cursorRect().topLeft().y() super().keyPressEvent(event) - kMod = event.modifiers() okMod = kMod == Qt.NoModifier or kMod == Qt.ShiftModifier okKey = event.key() not in self.MOVE_KEYS if okMod and okKey: - cNew = self.cursorRect().center().y() - cMov = cNew - cOld mPos = CONFIG.autoScrollPos*0.01 * self.viewport().height() - if abs(cMov) > 0 and cOld > mPos: - # Move the scroll bar + if cPos > mPos: vBar = self.verticalScrollBar() - doAnim = QPropertyAnimation(vBar, b"value", self) - doAnim.setDuration(120) - doAnim.setStartValue(vBar.value()) - doAnim.setEndValue(vBar.value() + cMov) - doAnim.start() - + vBar.setValue(vBar.value() + 1) else: super().keyPressEvent(event) diff --git a/tests/reference/baseConfig_novelwriter.conf b/tests/reference/baseConfig_novelwriter.conf index 2f4b05e1..f3434415 100644 --- a/tests/reference/baseConfig_novelwriter.conf +++ b/tests/reference/baseConfig_novelwriter.conf @@ -43,7 +43,6 @@ repsquotes = True repdquotes = True repdash = True repdots = True -scrollpastend = 25 autoscroll = False autoscrollpos = 30 fmtsquoteopen = ‘ diff --git a/tests/reference/guiPreferences_novelwriter.conf b/tests/reference/guiPreferences_novelwriter.conf index a8700427..dfa3f3fd 100644 --- a/tests/reference/guiPreferences_novelwriter.conf +++ b/tests/reference/guiPreferences_novelwriter.conf @@ -43,7 +43,6 @@ repsquotes = True repdquotes = True repdash = True repdots = True -scrollpastend = 0 autoscroll = True autoscrollpos = 30 fmtsquoteopen = ‘ diff --git a/tests/test_dialogs/test_dlg_preferences.py b/tests/test_dialogs/test_dlg_preferences.py index fe6b807a..dc51fd32 100644 --- a/tests/test_dialogs/test_dlg_preferences.py +++ b/tests/test_dialogs/test_dlg_preferences.py @@ -156,9 +156,6 @@ def testDlgPreferences_Main(qtbot, monkeypatch, nwGUI, tstPaths): qtbot.mouseClick(tabEditor.autoScroll, Qt.LeftButton) assert tabEditor.autoScroll.isChecked() - qtbot.wait(KEY_DELAY) - tabEditor.scrollPastEnd.setValue(0) - # Syntax Settings qtbot.wait(KEY_DELAY) tabSyntax = nwPrefs.tabSyntax diff --git a/tests/test_gui/test_gui_doceditor.py b/tests/test_gui/test_gui_doceditor.py index 547c7649..056523cf 100644 --- a/tests/test_gui/test_gui_doceditor.py +++ b/tests/test_gui/test_gui_doceditor.py @@ -200,8 +200,9 @@ def testGuiEditor_MetaData(qtbot, nwGUI, projPath, mockRnd): nwGUI.docEditor.saveCursorPosition() assert SHARED.project.tree[C.hSceneDoc].cursorPos == 10 - assert nwGUI.docEditor.setCursorLine(None) is False - assert nwGUI.docEditor.setCursorLine(3) is True + nwGUI.docEditor.setCursorLine(None) + assert nwGUI.docEditor.getCursorPosition() == 10 + nwGUI.docEditor.setCursorLine(3) assert nwGUI.docEditor.getCursorPosition() == 15 # Document Changed Signal @@ -499,7 +500,7 @@ def testGuiEditor_Insert(qtbot, monkeypatch, nwGUI, projPath, ipsumText, mockRnd theText = "### A Scene\n\n\n%s" % ipsumText[0] assert nwGUI.docEditor.replaceText(theText) is True - assert nwGUI.docEditor.setCursorLine(3) + nwGUI.docEditor.setCursorLine(3) # Invalid Keyword assert nwGUI.docEditor.insertKeyWord("stuff") is False @@ -1039,7 +1040,7 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText # Third Line # This also needs to add a new block assert nwGUI.docEditor.replaceText("#### Title\n\nThe Text\n\n") is True - assert nwGUI.docEditor.setCursorLine(3) is True + nwGUI.docEditor.setCursorLine(3) assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_COM) is True assert nwGUI.docEditor.getText() == "#### Title\n\n% The Text\n\n" @@ -1072,11 +1073,11 @@ def testGuiEditor_Tags(qtbot, nwGUI, projPath, ipsumText, mockRnd): assert nwGUI.openDocument(C.hSceneDoc) is True # Empty Block - assert nwGUI.docEditor.setCursorLine(2) is True + nwGUI.docEditor.setCursorLine(2) assert nwGUI.docEditor._followTag() is False # Not On Tag - assert nwGUI.docEditor.setCursorLine(1) is True + nwGUI.docEditor.setCursorLine(1) assert nwGUI.docEditor._followTag() is False # On Tag Keyword From 915b9da5d068d990bd7ce24d7940bc88a5583fa3 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Wed, 6 Sep 2023 20:35:48 +0200 Subject: [PATCH 5/5] Remove document size constraint --- novelwriter/constants.py | 4 - novelwriter/core/tokenizer.py | 10 +- novelwriter/gui/doceditor.py | 56 ++------ novelwriter/guimain.py | 3 + tests/test_core/test_core_tokenizer.py | 8 -- tests/test_gui/test_gui_doceditor.py | 173 +++++++++++-------------- 6 files changed, 93 insertions(+), 161 deletions(-) diff --git a/novelwriter/constants.py b/novelwriter/constants.py index 3e7d0bb6..b1855f98 100644 --- a/novelwriter/constants.py +++ b/novelwriter/constants.py @@ -40,10 +40,6 @@ class nwConst: FMT_FSTAMP = "%Y-%m-%d %H.%M.%S" # FileName safe format FMT_DSTAMP = "%Y-%m-%d" # Date only format - # Various Hard Limits - MAX_DOCSIZE = 5000000 # Maximum size of a single document - MAX_BUILDSIZE = 10000000 # Maximum size of a project build - # URLs URL_WEB = "https://novelwriter.io" URL_DOCS = "https://docs.novelwriter.io" diff --git a/novelwriter/core/tokenizer.py b/novelwriter/core/tokenizer.py index 6fc281b3..0f7a0219 100644 --- a/novelwriter/core/tokenizer.py +++ b/novelwriter/core/tokenizer.py @@ -38,7 +38,7 @@ from PyQt5.QtCore import QCoreApplication, QRegularExpression from novelwriter.enum import nwItemLayout from novelwriter.common import formatTimeStamp, numberToRoman, checkInt -from novelwriter.constants import nwConst, nwHeadFmt, nwRegEx, nwUnicode +from novelwriter.constants import nwHeadFmt, nwRegEx, nwUnicode from novelwriter.core.project import NWProject logger = logging.getLogger(__name__) @@ -349,14 +349,6 @@ class Tokenizer(ABC): self._text = text - docSize = len(self._text) - if docSize > nwConst.MAX_DOCSIZE: - errVal = self.tr("Document '{0}' is too big ({1} MB). Skipping.").format( - self._nwItem.itemName, f"{docSize/1.0e6:.2f}" - ) - self._text = "# {0}\n\n{1}\n\n".format(self.tr("ERROR"), errVal) - self._errData.append(errVal) - self._isNone = self._nwItem.itemLayout == nwItemLayout.NO_LAYOUT self._isNovel = self._nwItem.itemLayout == nwItemLayout.DOCUMENT self._isNote = self._nwItem.itemLayout == nwItemLayout.NOTE diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py index d74c50c7..9b81c765 100644 --- a/novelwriter/gui/doceditor.py +++ b/novelwriter/gui/doceditor.py @@ -53,7 +53,7 @@ from PyQt5.QtWidgets import ( from novelwriter import CONFIG, SHARED from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwItemClass from novelwriter.common import minmax, transferCase -from novelwriter.constants import nwConst, nwKeyWords, nwUnicode +from novelwriter.constants import nwKeyWords, nwUnicode from novelwriter.core.index import countWords from novelwriter.gui.dochighlight import GuiDocHighlighter from novelwriter.extensions.wheeleventfilter import WheelEventFilter @@ -358,7 +358,7 @@ class GuiDocEditor(QPlainTextEdit): return def loadText(self, tHandle, tLine=None) -> bool: - """Load text from a document into the editor. If we have an io + """Load text from a document into the editor. If we have an I/O error, we must handle this and clear the editor so that we don't risk overwriting the file if it exists. This can for instance happen of the file contains binary elements or an encoding that @@ -371,20 +371,7 @@ class GuiDocEditor(QPlainTextEdit): docText = self._nwDocument.readDocument() if docText is None: - # There was an io error - self.clearEditor() - return False - - docSize = len(docText) - if docSize > nwConst.MAX_DOCSIZE: - SHARED.error(self.tr( - "The document you are trying to open is too big. " - "The document size is {0} MB. " - "The maximum size allowed is {1} MB." - ).format( - f"{docSize/1.0e6:.2f}", - f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}" - )) + # There was an I/O error self.clearEditor() return False @@ -416,17 +403,17 @@ class GuiDocEditor(QPlainTextEdit): self.docFooter.updateLineCount() - qApp.processEvents() - self.document().clearUndoRedoStacks() - self.setDocumentChanged(False) - qApp.restoreOverrideCursor() - # This is a hack to fix invisible cursor on an empty document if self.document().characterCount() <= 1: self.setPlainText("\n") self.setPlainText("") self.setCursorPosition(0) + qApp.processEvents() + self.document().clearUndoRedoStacks() + self.setDocumentChanged(False) + qApp.restoreOverrideCursor() + # Update the status bar if self._nwItem is not None: self.statusMessage.emit(self.tr("Opened Document: {0}").format(self._nwItem.itemName)) @@ -444,29 +431,16 @@ class GuiDocEditor(QPlainTextEdit): self.updateDocMargins() return - def replaceText(self, text: str) -> bool: + def replaceText(self, text: str) -> None: """Replace the text of the current document with the provided text. This also clears undo history. """ - docSize = len(text) - if docSize > nwConst.MAX_DOCSIZE: - SHARED.error(self.tr( - "The text you are trying to add is too big. " - "The text size is {0} MB. " - "The maximum size allowed is {1} MB." - ).format( - f"{docSize/1.0e6:.2f}", - f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}" - )) - return False - qApp.setOverrideCursor(QCursor(Qt.WaitCursor)) self.setPlainText(text) self.updateDocMargins() self.setDocumentChanged(True) qApp.restoreOverrideCursor() - - return True + return def saveText(self) -> bool: """Save the text currently in the editor to the NWDocument @@ -1013,16 +987,6 @@ class GuiDocEditor(QPlainTextEdit): self._lastEdit = time() self._lastFind = None - if self.document().characterCount() > nwConst.MAX_DOCSIZE: - SHARED.error(self.tr( - "The document has grown too big and you cannot add more text to it. " - "The maximum size of a single novelWriter document is {0} MB." - ).format( - f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}" - )) - self.undo() - return - if not self._docChanged: self.setDocumentChanged(removed != 0 or added != 0) diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index 03cc58e8..8f89a9ed 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -340,6 +340,7 @@ class GuiMain(QMainWindow): def postLaunchTasks(self, cmdOpen: str | None) -> None: """Process tasks after the main window has been created.""" if cmdOpen: + qApp.processEvents() logger.info("Command line path: %s", cmdOpen) self.openProject(cmdOpen) @@ -513,10 +514,12 @@ class GuiMain(QMainWindow): break if lastEdited is not None: + qApp.processEvents() self.openDocument(lastEdited, doScroll=True) lastViewed = SHARED.project.data.getLastHandle("viewer") if lastViewed is not None: + qApp.processEvents() self.viewDocument(lastViewed) # Check if we need to rebuild the index diff --git a/tests/test_core/test_core_tokenizer.py b/tests/test_core/test_core_tokenizer.py index d746418d..c27fd9de 100644 --- a/tests/test_core/test_core_tokenizer.py +++ b/tests/test_core/test_core_tokenizer.py @@ -183,14 +183,6 @@ def testCoreToken_TextOps(monkeypatch, mockGUI, mockRnd, fncPath): assert theToken.setText(C.hSceneDoc) is True assert theToken._text == docText - with monkeypatch.context() as mp: - mp.setattr("novelwriter.constants.nwConst.MAX_DOCSIZE", 100) - assert theToken.setText(C.hSceneDoc, docText) is True - assert theToken._text == ( - "# ERROR\n\n" - "Document 'New Scene' is too big (0.00 MB). Skipping.\n\n" - ) - assert theToken.setText(C.hSceneDoc, docText) is True assert theToken._text == docText diff --git a/tests/test_gui/test_gui_doceditor.py b/tests/test_gui/test_gui_doceditor.py index 056523cf..8bee4ab4 100644 --- a/tests/test_gui/test_gui_doceditor.py +++ b/tests/test_gui/test_gui_doceditor.py @@ -96,21 +96,9 @@ def testGuiEditor_LoadText(qtbot, monkeypatch, caplog, nwGUI, projPath, ipsumTex # Invalid handle assert nwGUI.docEditor.loadText("abcdefghijklm") is False - # Document too big - with monkeypatch.context() as mp: - mp.setattr("novelwriter.constants.nwConst.MAX_DOCSIZE", 100) - assert nwGUI.docEditor.loadText(C.hSceneDoc) is False - assert "The document you are trying to open is too big." in caplog.text - # Regular open assert nwGUI.docEditor.loadText(C.hSceneDoc) is True - # Reload too big text - with monkeypatch.context() as mp: - mp.setattr("novelwriter.constants.nwConst.MAX_DOCSIZE", 100) - assert nwGUI.docEditor.replaceText(longText) is False - assert "The document you are trying to open is too big." in caplog.text - # Regular open, with line number (1 indexed) assert nwGUI.docEditor.loadText(C.hSceneDoc, tLine=4) is True cursPos = nwGUI.docEditor.getCursorPosition() @@ -184,7 +172,7 @@ def testGuiEditor_MetaData(qtbot, nwGUI, projPath, mockRnd): "Some\u2028text.\u2029" "More\u00a0text.\u2029" ) - assert nwGUI.docEditor.replaceText(newText) + nwGUI.docEditor.replaceText(newText) assert nwGUI.docEditor.getText() == "### New Scene\n\nSome\ntext.\nMore\u00a0text.\n" # Check Propertoes @@ -227,7 +215,7 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd): assert nwGUI.openDocument(C.hSceneDoc) is True theText = "### A Scene\n\n%s" % "\n\n".join(ipsumText) - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) theDoc = nwGUI.docEditor.document() @@ -251,7 +239,7 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd): assert theCursor.selectedText() == ipsumText[1] # Cut Selected Text - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(1000) assert nwGUI.docEditor.docAction(nwDocAction.SEL_PARA) is True assert nwGUI.docEditor.docAction(nwDocAction.CUT) is True @@ -269,7 +257,7 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd): assert nwGUI.docEditor.getText() == theText # Copy Next Paragraph - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(1500) assert nwGUI.docEditor.docAction(nwDocAction.SEL_PARA) is True assert nwGUI.docEditor.docAction(nwDocAction.COPY) is True @@ -292,7 +280,7 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd): # ================== theText = "### A Scene\n\n%s" % ipsumText[0] - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) # Emphasis nwGUI.docEditor.setCursorPosition(50) @@ -325,7 +313,7 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd): # ====== theText = "### A Scene\n\n%s" % ipsumText[0] - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) # Add Single Quotes nwGUI.docEditor.setCursorPosition(50) @@ -343,14 +331,14 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd): # Replace Single Quotes repText = theText.replace("consectetur", "'consectetur'") - assert nwGUI.docEditor.replaceText(repText) is True + nwGUI.docEditor.replaceText(repText) assert nwGUI.docEditor.docAction(nwDocAction.SEL_ALL) is True assert nwGUI.docEditor.docAction(nwDocAction.REPL_SNG) is True assert nwGUI.docEditor.getText() == theText.replace("consectetur", "\u2018consectetur\u2019") # Replace Double Quotes repText = theText.replace("consectetur", "\"consectetur\"") - assert nwGUI.docEditor.replaceText(repText) is True + nwGUI.docEditor.replaceText(repText) assert nwGUI.docEditor.docAction(nwDocAction.SEL_ALL) is True assert nwGUI.docEditor.docAction(nwDocAction.REPL_DBL) is True assert nwGUI.docEditor.getText() == theText.replace("consectetur", "\u201cconsectetur\u201d") @@ -360,7 +348,7 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd): theText = "### A Scene\n\n%s" % ipsumText[0] repText = theText[:100] + theText[100:].replace(" ", "\n", 3) - assert nwGUI.docEditor.replaceText(repText) is True + nwGUI.docEditor.replaceText(repText) assert nwGUI.docEditor.docAction(nwDocAction.RM_BREAKS) is True assert nwGUI.docEditor.getText().strip() == theText.strip() @@ -368,7 +356,7 @@ def testGuiEditor_Actions(qtbot, nwGUI, projPath, ipsumText, mockRnd): # ============ theText = "## Scene Title\n\nScene text.\n\n" - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) # Header 1 nwGUI.docEditor.setCursorPosition(0) @@ -456,13 +444,13 @@ def testGuiEditor_Insert(qtbot, monkeypatch, nwGUI, projPath, ipsumText, mockRnd assert nwGUI.openDocument(C.hSceneDoc) is True theText = "### A Scene\n\n%s" % "\n\n".join(ipsumText) - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) # Insert Text # =========== theText = "### A Scene\n\n%s" % ipsumText[0] - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) # No Document Handle nwGUI.docEditor._docHandle = None @@ -476,7 +464,7 @@ def testGuiEditor_Insert(qtbot, monkeypatch, nwGUI, projPath, ipsumText, mockRnd assert nwGUI.docEditor.getText() == theText[:24] + ", ipsumer," + theText[24:] # Single Quotes - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(41) assert nwGUI.docEditor.insertText(nwDocInsert.QUOTE_LS) is True nwGUI.docEditor.setCursorPosition(53) @@ -484,7 +472,7 @@ def testGuiEditor_Insert(qtbot, monkeypatch, nwGUI, projPath, ipsumText, mockRnd assert nwGUI.docEditor.getText() == theText.replace("consectetur", "\u2018consectetur\u2019") # Double Quotes - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(41) assert nwGUI.docEditor.insertText(nwDocInsert.QUOTE_LD) is True nwGUI.docEditor.setCursorPosition(53) @@ -499,7 +487,7 @@ def testGuiEditor_Insert(qtbot, monkeypatch, nwGUI, projPath, ipsumText, mockRnd # =============== theText = "### A Scene\n\n\n%s" % ipsumText[0] - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorLine(3) # Invalid Keyword @@ -538,14 +526,14 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex assert nwGUI.openDocument(C.hSceneDoc) is True theText = "### A Scene\n\n%s" % "\n\n".join(ipsumText) - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) # Clear Surrounding # ================= # No Selection theText = "### A Scene\n\n%s" % ipsumText[0] - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(45) theCursor = nwGUI.docEditor.textCursor() @@ -553,7 +541,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 + nwGUI.docEditor.replaceText(repText) nwGUI.docEditor.setCursorPosition(45) theCursor = nwGUI.docEditor.textCursor() @@ -563,7 +551,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 + nwGUI.docEditor.replaceText(repText) nwGUI.docEditor.setCursorPosition(45) theCursor = nwGUI.docEditor.textCursor() @@ -575,7 +563,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 + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(45) # No Selection @@ -584,19 +572,19 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex assert nwGUI.docEditor._wrapSelection("=", "=") is False # Wrap Equal - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) 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 + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(45) assert nwGUI.docEditor._wrapSelection("=", "*") is True assert nwGUI.docEditor.getText() == theText.replace("consectetur", "=consectetur*") # Past Paragraph - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) theCursor = nwGUI.docEditor.textCursor() theCursor.setPosition(13, QTextCursor.MoveAnchor) theCursor.setPosition(1000, QTextCursor.KeepAnchor) @@ -612,7 +600,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 + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(45) # No Selection @@ -621,13 +609,13 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex assert nwGUI.docEditor._toggleFormat(2, "=") is False # Wrap Single Equal - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(45) assert nwGUI.docEditor._toggleFormat(1, "=") is True assert nwGUI.docEditor.getText() == theText.replace("consectetur", "=consectetur=") # Past Paragraph - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) theCursor = nwGUI.docEditor.textCursor() theCursor.setPosition(13, QTextCursor.MoveAnchor) theCursor.setPosition(1000, QTextCursor.KeepAnchor) @@ -640,20 +628,20 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex assert newPara[2] == ipsumText[1] # Wrap Double Equal - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) 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 + nwGUI.docEditor.replaceText(theText) 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 + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(45) assert nwGUI.docEditor._toggleFormat(3, "=") is True assert nwGUI.docEditor._toggleFormat(2, "=") is True @@ -661,7 +649,7 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex # Toggle Unequal repText = theText.replace("consectetur", "=consectetur==") - assert nwGUI.docEditor.replaceText(repText) is True + nwGUI.docEditor.replaceText(repText) nwGUI.docEditor.setCursorPosition(45) assert nwGUI.docEditor._toggleFormat(1, "=") is True assert nwGUI.docEditor.getText() == theText.replace("consectetur", "consectetur=") @@ -673,14 +661,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 + nwGUI.docEditor.replaceText(theText) 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 + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(45) assert nwGUI.docEditor.docAction(nwDocAction.SEL_PARA) assert nwGUI.docEditor._replaceQuotes("=", "<", ">") is True @@ -692,7 +680,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 + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(45) assert nwGUI.docEditor.docAction(nwDocAction.SEL_ALL) assert nwGUI.docEditor._replaceQuotes("=", "<", ">") is True @@ -706,7 +694,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 + nwGUI.docEditor.replaceText(theText) nwGUI.docEditor.setCursorPosition(45) nwGUI.docEditor._removeInParLineBreaks() assert nwGUI.docEditor.getText() == "### A Scene\n\n%s\n" % "\n\n".join(ipsumText[0:2]) @@ -714,7 +702,7 @@ def testGuiEditor_TextManipulation(qtbot, monkeypatch, nwGUI, projPath, ipsumTex # Remove First Paragraph # Second paragraphs should remain unchanged theText = "### A Scene\n\n%s\n\n%s" % (parOne, parTwo) - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) theCursor = nwGUI.docEditor.textCursor() theCursor.setPosition(16, QTextCursor.MoveAnchor) theCursor.setPosition(680, QTextCursor.KeepAnchor) @@ -743,14 +731,11 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText buildTestProject(nwGUI, projPath) assert nwGUI.openDocument(C.hSceneDoc) is True - theText = "### A Scene\n\n%s" % "\n\n".join(ipsumText) - assert nwGUI.docEditor.replaceText(theText) is True - # Invalid and Generic # =================== theText = "### A Scene\n\n%s" % ipsumText[0] - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) # Invalid Block nwGUI.docEditor.setCursorPosition(0) @@ -759,14 +744,14 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is False # Keyword - assert nwGUI.docEditor.replaceText("@pov: Jane\n\n") is True + nwGUI.docEditor.replaceText("@pov: Jane\n\n") 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 + nwGUI.docEditor.replaceText("% Comment\n\n") nwGUI.docEditor.setCursorPosition(5) assert nwGUI.docEditor._formatBlock(nwDocAction.NO_ACTION) is False @@ -774,91 +759,91 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText # =========================== # Strip Comment w/Space - assert nwGUI.docEditor.replaceText("% Comment\n\n") is True + nwGUI.docEditor.replaceText("% Comment\n\n") 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 + nwGUI.docEditor.replaceText("%Comment\n\n") 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 + nwGUI.docEditor.replaceText("# Title\n\n") 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 + nwGUI.docEditor.replaceText("## Title\n\n") 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 + nwGUI.docEditor.replaceText("### Title\n\n") 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 + nwGUI.docEditor.replaceText("#### Title\n\n") 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 + nwGUI.docEditor.replaceText("#! Title\n\n") 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 + nwGUI.docEditor.replaceText("##! Title\n\n") 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 + nwGUI.docEditor.replaceText("Generic text\n\n") 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 + nwGUI.docEditor.replaceText(">> Some text\n\n") 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 + nwGUI.docEditor.replaceText("> Some text\n\n") 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 + nwGUI.docEditor.replaceText(">>Some text\n\n") 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 + nwGUI.docEditor.replaceText(">Some text\n\n") nwGUI.docEditor.setCursorPosition(5) assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True assert nwGUI.docEditor.getText() == "Some text\n\n" @@ -868,28 +853,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 + nwGUI.docEditor.replaceText("Some text <<\n\n") 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 + nwGUI.docEditor.replaceText("Some text <\n\n") 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 + nwGUI.docEditor.replaceText("Some text<<\n\n") 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 + nwGUI.docEditor.replaceText("Some text<\n\n") nwGUI.docEditor.setCursorPosition(5) assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True assert nwGUI.docEditor.getText() == "Some text\n\n" @@ -898,15 +883,15 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText # Block Stripping : Both Sides # ============================ - assert nwGUI.docEditor.replaceText(">> Some text <<\n\n") is True + nwGUI.docEditor.replaceText(">> Some text <<\n\n") assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True assert nwGUI.docEditor.getText() == "Some text\n\n" - assert nwGUI.docEditor.replaceText(">Some text <<\n\n") is True + nwGUI.docEditor.replaceText(">Some text <<\n\n") assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True assert nwGUI.docEditor.getText() == "Some text\n\n" - assert nwGUI.docEditor.replaceText(">Some text<\n\n") is True + nwGUI.docEditor.replaceText(">Some text<\n\n") assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True assert nwGUI.docEditor.getText() == "Some text\n\n" @@ -914,84 +899,84 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText # =========== # Comment - assert nwGUI.docEditor.replaceText("Some text\n\n") is True + nwGUI.docEditor.replaceText("Some text\n\n") 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 + nwGUI.docEditor.replaceText("% Some text\n\n") 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 + nwGUI.docEditor.replaceText("%Some text\n\n") 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 + nwGUI.docEditor.replaceText("Some text\n\n") 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 + nwGUI.docEditor.replaceText("Some text\n\n") 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 + nwGUI.docEditor.replaceText("Some text\n\n") 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 + nwGUI.docEditor.replaceText("Some text\n\n") 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 + nwGUI.docEditor.replaceText("Some text\n\n") 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 + nwGUI.docEditor.replaceText("Some text\n\n") 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 + nwGUI.docEditor.replaceText("Some text\n\n") 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 + nwGUI.docEditor.replaceText("Some text\n\n") 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 + nwGUI.docEditor.replaceText("Some text\n\n") nwGUI.docEditor.setCursorPosition(5) assert nwGUI.docEditor._formatBlock(nwDocAction.INDENT_L) is True assert nwGUI.docEditor._formatBlock(nwDocAction.INDENT_R) is True @@ -999,28 +984,28 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText assert nwGUI.docEditor.getCursorPosition() == 7 # Left Align - assert nwGUI.docEditor.replaceText("Some text\n\n") is True + nwGUI.docEditor.replaceText("Some text\n\n") 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 + nwGUI.docEditor.replaceText("Some text\n\n") 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 + nwGUI.docEditor.replaceText("Some text\n\n") 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 + nwGUI.docEditor.replaceText("Some text\n\n") nwGUI.docEditor.setCursorPosition(5) assert nwGUI.docEditor._formatBlock(nwDocAction.ALIGN_L) is True assert nwGUI.docEditor._formatBlock(nwDocAction.ALIGN_R) is True @@ -1031,7 +1016,7 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText # ============ # Final Cursor Position Out of Range - assert nwGUI.docEditor.replaceText("#### Title\n\n") is True + nwGUI.docEditor.replaceText("#### Title\n\n") nwGUI.docEditor.setCursorPosition(3) assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_TXT) is True assert nwGUI.docEditor.getText() == "Title\n\n" @@ -1039,7 +1024,7 @@ def testGuiEditor_BlockFormatting(qtbot, monkeypatch, nwGUI, projPath, ipsumText # Third Line # This also needs to add a new block - assert nwGUI.docEditor.replaceText("#### Title\n\nThe Text\n\n") is True + nwGUI.docEditor.replaceText("#### Title\n\nThe Text\n\n") nwGUI.docEditor.setCursorLine(3) assert nwGUI.docEditor._formatBlock(nwDocAction.BLOCK_COM) is True assert nwGUI.docEditor.getText() == "#### Title\n\n% The Text\n\n" @@ -1057,13 +1042,13 @@ def testGuiEditor_Tags(qtbot, nwGUI, projPath, ipsumText, mockRnd): # Create Scene theText = "### A Scene\n\n@char: Jane, John\n\n" + ipsumText[0] + "\n\n" - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) # Create Character theText = "### Jane Doe\n\n@tag: Jane\n\n" + ipsumText[1] + "\n\n" cHandle = SHARED.project.newFile("Jane Doe", C.hCharRoot) assert nwGUI.openDocument(cHandle) is True - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) assert nwGUI.saveDocument() is True assert nwGUI.projView.projTree.revealNewTreeItem(cHandle) nwGUI.docEditor.updateTagHighLighting() @@ -1145,7 +1130,7 @@ def testGuiEditor_WordCounters(qtbot, monkeypatch, nwGUI, projPath, ipsumText, m theText = "\n\n".join(ipsumText) cC, wC, pC = countWords(theText) - assert nwGUI.docEditor.replaceText(theText) is True + nwGUI.docEditor.replaceText(theText) # Check that a busy counter is blocked with monkeypatch.context() as mp: