From 7d1e85c0d450cd499160d0e33e11a77fdebe94d1 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Tue, 13 Oct 2020 21:51:49 +0200 Subject: [PATCH 1/4] Animate the scroll bar movement when following cursor --- nw/gui/custom.py | 2 +- nw/gui/doceditor.py | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/nw/gui/custom.py b/nw/gui/custom.py index 03fc6318..2955c447 100644 --- a/nw/gui/custom.py +++ b/nw/gui/custom.py @@ -326,7 +326,7 @@ class QSwitch(QAbstractButton): """ super().mouseReleaseEvent(event) if event.button() == Qt.LeftButton: - doAnim = QPropertyAnimation(self, b'offset', self) + doAnim = QPropertyAnimation(self, b"offset", self) doAnim.setDuration(120) doAnim.setStartValue(self.offset) if self.isChecked(): diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index a7779845..34ae52f2 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -38,7 +38,7 @@ from time import time from PyQt5.QtCore import ( Qt, QSize, QTimer, pyqtSlot, pyqtSignal, QRegExp, QRegularExpression, - QPointF, QObject, QRunnable + QPointF, QObject, QRunnable, QPropertyAnimation ) from PyQt5.QtGui import ( QTextCursor, QTextOption, QKeySequence, QFont, QColor, QPalette, @@ -774,11 +774,22 @@ class GuiDocEditor(QTextEdit): if self.mainConf.scollWithCursor: kMod = keyEvent.modifiers() if kMod == Qt.NoModifier or kMod == Qt.ShiftModifier: + hWid = self.viewport().height() cPos = self.cursorRect().center().y() - mPos = self.mainConf.scollToPoint * self.viewport().height() + mPos = self.mainConf.scollToPoint * hWid vBar = self.verticalScrollBar() - vBar.setValue(vBar.value() + cPos - round(mPos * 0.01)) - self.ensureCursorVisible() + + # Compute the needed scroll and duration + pOld = vBar.value() + pNew = pOld + cPos - round(mPos*0.01) + aDur = 150 + round(abs(pNew - pOld)/hWid*500) + + if pNew >= 0: + doAnim = QPropertyAnimation(vBar, b"value", self) + doAnim.setDuration(aDur) + doAnim.setStartValue(pOld) + doAnim.setEndValue(pNew) + doAnim.start() return From 10e97a567b9729c62a75c38c95daa1fae054ee53 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Tue, 13 Oct 2020 21:59:02 +0200 Subject: [PATCH 2/4] Make sure the scrolling effect is covered by test --- tests/test_gui.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_gui.py b/tests/test_gui.py index 0b32327e..4afaaa2b 100644 --- a/tests/test_gui.py +++ b/tests/test_gui.py @@ -168,6 +168,13 @@ def testDocEditor(qtbot, yesToAll, nwFuncTemp, nwTempGUI, nwRef, nwTemp): nwGUI.mainMenu.aSpellCheck.setChecked(True) assert nwGUI.mainMenu._toggleSpellCheck() + # Change some settings + nwGUI.mainConf.hideHScroll = True + nwGUI.mainConf.hideVScroll = True + nwGUI.mainConf.scrollPastEnd = True + nwGUI.mainConf.scollToPoint = 80 + nwGUI.mainConf.scollWithCursor = True + # Add a Character File nwGUI.setFocus(1) nwGUI.treeView.clearSelection() From 3fbe5e218c63c07763267668c13765a6195a2175 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Tue, 13 Oct 2020 22:14:17 +0200 Subject: [PATCH 3/4] Make sure the scroll bar anim cannot go past 650 ms, and add a percentage of total to the line counter --- nw/gui/doceditor.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index 34ae52f2..16c2c08c 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -782,7 +782,7 @@ class GuiDocEditor(QTextEdit): # Compute the needed scroll and duration pOld = vBar.value() pNew = pOld + cPos - round(mPos*0.01) - aDur = 150 + round(abs(pNew - pOld)/hWid*500) + aDur = 150 + round(min(abs(pNew - pOld)/hWid, 1.0)*500) if pNew >= 0: doAnim = QPropertyAnimation(vBar, b"value", self) @@ -2346,11 +2346,13 @@ class GuiDocEditFooter(QWidget): """ if self.theItem is None: iLine = 0 + iDist = 0 else: theCursor = self.docEditor.textCursor() iLine = theCursor.blockNumber() + 1 + iDist = 100*iLine/self.docEditor.qDocument.blockCount() - self.linesText.setText(f"Line: {iLine:n}") + self.linesText.setText(f"Line: {iLine:n} ({iDist:.0f}\u202f%)") return From 25b77c91db89d2c66b48d60823cb224bde8d9316 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Tue, 13 Oct 2020 22:46:39 +0200 Subject: [PATCH 4/4] Add 'Follow Tag' to the context meny when right clicking a tag, and disable spell check for it --- nw/gui/doceditor.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index 16c2c08c..b41fd764 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -860,11 +860,18 @@ class GuiDocEditor(QTextEdit): """ userCursor = self.textCursor() userSelection = userCursor.hasSelection() + posCursor = self.cursorForPosition(thePos) mnuContext = QMenu() - # Cut, Copy and Paste - # =================== + # Follow, Cut, Copy and Paste + # =========================== + + if self._followTag(theCursor=posCursor, loadTag=False): + mnuTag = QAction("Follow Tag", mnuContext) + mnuTag.triggered.connect(lambda: self._followTag(theCursor=posCursor)) + mnuContext.addAction(mnuTag) + mnuContext.addSeparator() if userSelection: mnuCut = QAction("Cut", mnuContext) @@ -903,10 +910,13 @@ class GuiDocEditor(QTextEdit): # Spell Checking # ============== + posCursor = self.cursorForPosition(thePos) spellCheck = self.spellCheck + if posCursor.block().text().startswith("@"): + spellCheck = False + if spellCheck: - posCursor = self.cursorForPosition(thePos) posCursor.select(QTextCursor.WordUnderCursor) theWord = posCursor.selectedText().strip().strip(self.nonWord) spellCheck &= theWord != "" @@ -970,8 +980,8 @@ class GuiDocEditor(QTextEdit): @pyqtSlot() def _runCounter(self): - """Decide whether to run the word counter, or stop the timer due - to inactivity. + """Decide whether to run the word counter, or not due to + inactivity. """ if self.wCounter.isRunning(): logger.verbose("Word counter is busy") @@ -1035,7 +1045,7 @@ class GuiDocEditor(QTextEdit): # Internal Functions ## - def _followTag(self, theCursor=None): + def _followTag(self, theCursor=None, loadTag=True): """Activated by Ctrl+Enter. Checks that we're in a block starting with '@'. We then find the word under the cursor and check that it is after the ':'. If all this is fine, we have a @@ -1060,10 +1070,15 @@ class GuiDocEditor(QTextEdit): if wPos <= cPos: return False - logger.verbose("Attempting to follow tag '%s'" % theWord) - self.theParent.docViewer.loadFromTag(theWord) + if loadTag: + logger.verbose("Attempting to follow tag '%s'" % theWord) + self.theParent.docViewer.loadFromTag(theWord) + else: + logger.verbose("Potential tag '%s'" % theWord) - return True + return True + + return False def _openSpellContext(self): """Opens the spell check context menu at the current point of