From 6ebc4ca268032c3863c06162d121970d081c5be5 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Tue, 8 Sep 2020 18:19:22 +0200
Subject: [PATCH 1/8] Cleaned up the way navigation is done in the document
viewer
---
nw/core/tohtml.py | 2 +-
nw/gui/docviewer.py | 24 ++++++++++++++----------
nw/guimain.py | 4 ++--
3 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/nw/core/tohtml.py b/nw/core/tohtml.py
index cb8cfa1a..720ac9cd 100644
--- a/nw/core/tohtml.py
+++ b/nw/core/tohtml.py
@@ -189,7 +189,7 @@ class ToHtml(Tokenizer):
hStyle = ""
if self.linkHeaders:
- aNm = "" % (self.theHandle, tLine)
+ aNm = "" % tLine
else:
aNm = ""
diff --git a/nw/gui/docviewer.py b/nw/gui/docviewer.py
index 0c8c51b1..17b668c8 100644
--- a/nw/gui/docviewer.py
+++ b/nw/gui/docviewer.py
@@ -168,6 +168,7 @@ class GuiDocViewer(QTextBrowser):
self.setTabStopWidth(self.mainConf.getTabWidth())
self.setHtml(aDoc.theResult.replace("\t", "!!tab!!"))
+ self.setDocumentTitle(tHandle)
# Loop through the text and put back in the tabs. Tabs are removed by
# the setHtml function, so the ToHtml class puts in a placeholder.
@@ -203,7 +204,7 @@ class GuiDocViewer(QTextBrowser):
index being up to date.
"""
logger.debug("Loading document from tag '%s'" % theTag)
- tHandle, onLine, sTitle = self.theParent.theIndex.getTagSource(theTag)
+ tHandle, _, sTitle = self.theParent.theIndex.getTagSource(theTag)
if tHandle is None:
self.theParent.makeAlert((
"Could not find the reference for tag '%s'. It either doesn't "
@@ -215,8 +216,9 @@ class GuiDocViewer(QTextBrowser):
# Let the parent handle the opening as it also ensures that
# the doc view panel is visible in case this request comes
# from outside this class.
+ logger.verbose("Tag points to %s#%s" % (tHandle, sTitle))
self.theParent.viewDocument(tHandle)
- self.navigateTo("#head_%s:%s" % (tHandle, sTitle))
+ self.navigateTo("#%s" % sTitle)
return True
def docAction(self, theAction):
@@ -240,13 +242,14 @@ class GuiDocViewer(QTextBrowser):
return False
return True
- def navigateTo(self, navLink):
+ def navigateTo(self, tAnchor):
"""Go to a specific #link in the document.
"""
- if not isinstance(navLink, str):
+ if not isinstance(tAnchor, str):
return False
- if navLink.startswith("#"):
- self.setSource(QUrl(navLink))
+ if tAnchor.startswith("#"):
+ logger.verbose("Moving to anchor %s" % tAnchor)
+ self.setSource(QUrl(tAnchor))
return True
def updateDocMargins(self):
@@ -818,7 +821,7 @@ class GuiDocViewDetails(QScrollArea):
for tHandle in theRefs:
tItem = self.theProject.projTree[tHandle]
if tItem is not None:
- theList.append("%s" % (
+ theList.append("%s" % (
tHandle, theRefs[tHandle], self.linkStyle, tItem.itemName
))
@@ -835,9 +838,10 @@ class GuiDocViewDetails(QScrollArea):
class for handling.
"""
logger.verbose("Clicked link: '%s'" % theLink)
- if len(theLink) == 27:
- tHandle = theLink[6:19]
- self.theParent.viewDocument(tHandle, theLink)
+ if len(theLink) == 21:
+ tHandle = theLink[:13]
+ tAnchor = theLink[13:]
+ self.theParent.viewDocument(tHandle, tAnchor)
return
# END Class GuiDocViewDetails
diff --git a/nw/guimain.py b/nw/guimain.py
index 86401a5b..0729a7df 100644
--- a/nw/guimain.py
+++ b/nw/guimain.py
@@ -525,7 +525,7 @@ class GuiMain(QMainWindow):
self.docEditor.saveText()
return True
- def viewDocument(self, tHandle=None, navLink=None):
+ def viewDocument(self, tHandle=None, tAnchor=None):
"""Load a document for viewing in the view panel.
"""
if tHandle is None:
@@ -562,7 +562,7 @@ class GuiMain(QMainWindow):
vPos[1] = bPos[1] - vPos[0]
self.splitDocs.setSizes(vPos)
self.viewMeta.setVisible(self.mainConf.showRefPanel)
- self.docViewer.navigateTo(navLink)
+ self.docViewer.navigateTo(tAnchor)
return True
From 2a3df92b202c07ebf6bef41ab3fc79505c49dc0b Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Tue, 8 Sep 2020 18:44:08 +0200
Subject: [PATCH 2/8] Added starte view history class and connected mouse, menu
and keyboard
---
nw/gui/docviewer.py | 73 +++++++++++++++++++++++++++++++++++++++++----
nw/gui/mainmenu.py | 17 +++++++++++
2 files changed, 84 insertions(+), 6 deletions(-)
diff --git a/nw/gui/docviewer.py b/nw/gui/docviewer.py
index 17b668c8..e8333a00 100644
--- a/nw/gui/docviewer.py
+++ b/nw/gui/docviewer.py
@@ -63,20 +63,22 @@ class GuiDocViewer(QTextBrowser):
self.setMinimumWidth(self.mainConf.pxInt(300))
self.setAutoFillBackground(True)
self.setOpenExternalLinks(False)
+ self.setFocusPolicy(Qt.StrongFocus)
self.initViewer()
# Document Header and Footer
- self.docHeader = GuiDocViewHeader(self)
- self.docFooter = GuiDocViewFooter(self)
- self.stickyRef = False
+ self.docHeader = GuiDocViewHeader(self)
+ self.docFooter = GuiDocViewFooter(self)
+ self.docHistory = GuiDocViewHistory(self)
+ self.stickyRef = False
theOpt = QTextOption()
if self.mainConf.doJustify:
theOpt.setAlignment(Qt.AlignJustify)
self.qDocument.setDefaultTextOption(theOpt)
+ # Signals
self.anchorClicked.connect(self._linkClicked)
- self.setFocusPolicy(Qt.StrongFocus)
# Context Menu
self.setContextMenuPolicy(Qt.CustomContextMenu)
@@ -169,6 +171,7 @@ class GuiDocViewer(QTextBrowser):
self.setHtml(aDoc.theResult.replace("\t", "!!tab!!"))
self.setDocumentTitle(tHandle)
+ self.docHistory.append(tHandle)
# Loop through the text and put back in the tabs. Tabs are removed by
# the setHtml function, so the ToHtml class puts in a placeholder.
@@ -217,8 +220,7 @@ class GuiDocViewer(QTextBrowser):
# the doc view panel is visible in case this request comes
# from outside this class.
logger.verbose("Tag points to %s#%s" % (tHandle, sTitle))
- self.theParent.viewDocument(tHandle)
- self.navigateTo("#%s" % sTitle)
+ self.theParent.viewDocument(tHandle, "#%s" % sTitle)
return True
def docAction(self, theAction):
@@ -252,6 +254,18 @@ class GuiDocViewer(QTextBrowser):
self.setSource(QUrl(tAnchor))
return True
+ def navBackward(self):
+ """Navigate backwards in the document view history.
+ """
+ self.docHistory.backward()
+ return
+
+ def navForward(self):
+ """Navigate forwards in the document view history.
+ """
+ self.docHistory.forward()
+ return
+
def updateDocMargins(self):
"""Automatically adjust the margins so the text is centred if
Config.textFixedW is enabled or we're in Focus Mode. Otherwise,
@@ -382,6 +396,15 @@ class GuiDocViewer(QTextBrowser):
self.updateDocMargins()
return
+ def mouseReleaseEvent(self, theEvent):
+ """Capture mouse click events on the document.
+ """
+ if theEvent.button() == Qt.BackButton:
+ self.navBackward()
+ elif theEvent.button() == Qt.ForwardButton:
+ self.navForward()
+ return
+
##
# Internal Functions
##
@@ -481,6 +504,44 @@ class GuiDocViewer(QTextBrowser):
# END Class GuiDocViewer
+class GuiDocViewHistory():
+
+ def __init__(self, docViewer):
+
+ self.docViewer = docViewer
+
+ self._navHistory = []
+ self._navPosition = -1
+
+ return
+
+ def clear(self):
+ logger.verbose("Clear view history")
+ self._navHistory = []
+ self._navPosition = -1
+ return
+
+ def append(self, tHandle):
+ logger.verbose("Added %s to view history" % tHandle)
+ return
+
+ def forward(self):
+ logger.verbose("Move forwards in view history")
+ return True
+
+ def backward(self):
+ logger.verbose("Move backwards in view history")
+ return True
+
+ ##
+ # Internal Functions
+ ##
+
+ def _truncateHistory(self, atPos):
+ return
+
+# END Class GuiDocViewHistory
+
# =============================================================================================== #
# The Embedded Document Header
# Only used by DocViewer, and is at a fixed position in the QTextBrowser's viewport
diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py
index b904ffd9..ed96a4ee 100644
--- a/nw/gui/mainmenu.py
+++ b/nw/gui/mainmenu.py
@@ -475,6 +475,23 @@ class GuiMainMenu(QMenuBar):
# View > Separator
self.viewMenu.addSeparator()
+ # View > Navigate Viewer Backward
+ self.aViewPrev = QAction("Navigate Viewer Backward", self)
+ self.aViewPrev.setStatusTip("Show the previous document in the right pane")
+ self.aViewPrev.setShortcut("Alt+Left")
+ self.aViewPrev.triggered.connect(self.theParent.docViewer.navBackward)
+ self.viewMenu.addAction(self.aViewPrev)
+
+ # View > Navigate Viewer Forward
+ self.aViewNext = QAction("Navigate Viewer Forward", self)
+ self.aViewNext.setStatusTip("Show the next document in the right pane")
+ self.aViewNext.setShortcut("Alt+Right")
+ self.aViewNext.triggered.connect(self.theParent.docViewer.navForward)
+ self.viewMenu.addAction(self.aViewNext)
+
+ # View > Separator
+ self.viewMenu.addSeparator()
+
# View > Toggle Distraction Free Mode
self.aFocusMode = QAction("Distraction Free Mode", self)
self.aFocusMode.setStatusTip("Toggles distraction free mode, only showing text editor")
From e30064ba0b181bbe923690a5b72da1fcb2fb202d Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Tue, 8 Sep 2020 21:20:38 +0200
Subject: [PATCH 3/8] Nav history in doc viewer now works
---
nw/gui/docviewer.py | 128 ++++++++++++++++++++++++++++++++++++++++----
nw/guimain.py | 1 +
2 files changed, 118 insertions(+), 11 deletions(-)
diff --git a/nw/gui/docviewer.py b/nw/gui/docviewer.py
index e8333a00..024b1723 100644
--- a/nw/gui/docviewer.py
+++ b/nw/gui/docviewer.py
@@ -10,6 +10,7 @@
Created: 2019-10-31 [0.3.2] GuiDocViewDetails
Created: 2020-04-25 [0.4.5] GuiDocViewHeader
Created: 2020-06-09 [0.8.0] GuiDocViewFooter
+ Created: 2020-09-08 [1.0b1] GuiDocViewHistory
This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen
@@ -131,7 +132,7 @@ class GuiDocViewer(QTextBrowser):
return True
- def loadText(self, tHandle):
+ def loadText(self, tHandle, updateHistory=True):
"""Load text into the viewer from an item handle.
"""
tItem = self.theProject.projTree[tHandle]
@@ -169,9 +170,12 @@ class GuiDocViewer(QTextBrowser):
else:
self.setTabStopWidth(self.mainConf.getTabWidth())
+ # Must be before setHtml
+ if updateHistory:
+ self.docHistory.append(tHandle)
+
self.setHtml(aDoc.theResult.replace("\t", "!!tab!!"))
self.setDocumentTitle(tHandle)
- self.docHistory.append(tHandle)
# Loop through the text and put back in the tabs. Tabs are removed by
# the setHtml function, so the ToHtml class puts in a placeholder.
@@ -266,6 +270,12 @@ class GuiDocViewer(QTextBrowser):
self.docHistory.forward()
return
+ def clearNavHistory(self):
+ """Clear the navigation history.
+ """
+ self.docHistory.clear()
+ return
+
def updateDocMargins(self):
"""Automatically adjust the margins so the text is centred if
Config.textFixedW is enabled or we're in Focus Mode. Otherwise,
@@ -326,6 +336,26 @@ class GuiDocViewer(QTextBrowser):
logger.verbose("Cursor moved to line %d" % theLine)
return True
+ def setScrollPosition(self, thePos):
+ """Set the scrollbar position.
+ """
+ vBar = self.verticalScrollBar()
+ if vBar.isVisible():
+ vBar.setValue(thePos)
+ return
+
+ ##
+ # Getters
+ ##
+
+ def getScrollPosition(self):
+ """Get the scrollbar position. Returns 0 if no scrollbar.
+ """
+ vBar = self.verticalScrollBar()
+ if vBar.isVisible():
+ return vBar.value()
+ return 0
+
##
# Slots
##
@@ -403,6 +433,8 @@ class GuiDocViewer(QTextBrowser):
self.navBackward()
elif theEvent.button() == Qt.ForwardButton:
self.navForward()
+ else:
+ QTextBrowser.mouseReleaseEvent(self, theEvent)
return
##
@@ -511,35 +543,109 @@ class GuiDocViewHistory():
self.docViewer = docViewer
self._navHistory = []
- self._navPosition = -1
+ self._posHistory = []
+ self._currPos = -1
+ self._prevPos = -1
return
def clear(self):
- logger.verbose("Clear view history")
+ """Clear the view history.
+ """
+ logger.verbose("View history cleared")
self._navHistory = []
- self._navPosition = -1
+ self._posHistory = []
+ self._currPos = -1
+ self._prevPos = -1
return
def append(self, tHandle):
+ """Append a document handle and its scroll bar position to the
+ history, but only if the document is different than the current
+ active entry. Any further entries are truncated.
+ """
+ if self._currPos >= 0 and self._currPos < len(self._navHistory):
+ if tHandle == self._navHistory[self._currPos]:
+ logger.verbose("Not updating view hsitory")
+ return False
+
+ self._truncateHistory(self._currPos)
+
+ self._navHistory.append(tHandle)
+ self._posHistory.append(0)
+
+ self._prevPos = self._currPos
+ self._currPos = len(self._navHistory) - 1
+ self._updateScrollBar()
+
+ self._dumpHistory()
+
logger.verbose("Added %s to view history" % tHandle)
- return
+
+ return True
def forward(self):
- logger.verbose("Move forwards in view history")
- return True
+ """Navigate to the next entry in the view history.
+ """
+ newPos = self._currPos + 1
+ if newPos < len(self._navHistory):
+ logger.verbose("Move forward in view history")
+ self._prevPos = self._currPos
+ self._updateScrollBar()
+
+ self.docViewer.loadText(self._navHistory[newPos], updateHistory=False)
+ self.docViewer.setScrollPosition(self._posHistory[newPos])
+ self._currPos = newPos
+
+ self._dumpHistory()
+
+ return
def backward(self):
- logger.verbose("Move backwards in view history")
- return True
+ """Navigate to the previous entry in the view history.
+ """
+ newPos = self._currPos - 1
+ if newPos >= 0:
+ logger.verbose("Move backward in view history")
+ self._prevPos = self._currPos
+ self._updateScrollBar()
+
+ self.docViewer.loadText(self._navHistory[newPos], updateHistory=False)
+ self.docViewer.setScrollPosition(self._posHistory[newPos])
+ self._currPos = newPos
+
+ self._dumpHistory()
+
+ return
##
# Internal Functions
##
- def _truncateHistory(self, atPos):
+ def _updateScrollBar(self):
+ """Update the scrollbar position of the previous entry.
+ """
+ if self._prevPos >= 0 and self._prevPos < len(self._posHistory):
+ self._posHistory[self._prevPos] = self.docViewer.getScrollPosition()
return
+ def _truncateHistory(self, atPos):
+ """Truncate the navigation history to the given position.
+ """
+ nSkip = 1 if atPos > 49 else 0
+
+ self._navHistory = self._navHistory[nSkip:atPos + 1]
+ self._posHistory = self._posHistory[nSkip:atPos + 1]
+
+ self._currPos -= nSkip
+ self._prevPos -= nSkip
+
+ return
+
+ def _dumpHistory(self):
+ for i, (h, p) in enumerate(zip(self._navHistory, self._posHistory)):
+ print("%s %3d %13s %6d" % (">" if i == self._currPos else " ", i, h, p))
+
# END Class GuiDocViewHistory
# =============================================================================================== #
diff --git a/nw/guimain.py b/nw/guimain.py
index 0729a7df..73209394 100644
--- a/nw/guimain.py
+++ b/nw/guimain.py
@@ -346,6 +346,7 @@ class GuiMain(QMainWindow):
if saveOK:
self.closeDocument()
+ self.docViewer.clearNavHistory()
self.projView.closeOutline()
self.theProject.closeProject()
self.theIndex.clearIndex()
From 7bd190726193ba0ae9511a64c03332f6b139be94 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Tue, 8 Sep 2020 21:59:44 +0200
Subject: [PATCH 4/8] Added icons for backward and forward navigation buttons
---
.../typicons_colour_dark/chevron-left.svg | 31 +++++++++++++++++++
.../typicons_colour_dark/chevron-right.svg | 31 +++++++++++++++++++
.../icons/typicons_colour_dark/icons.conf | 2 ++
.../typicons_colour_light/chevron-left.svg | 31 +++++++++++++++++++
.../typicons_colour_light/chevron-right.svg | 31 +++++++++++++++++++
.../icons/typicons_colour_light/icons.conf | 2 ++
.../icons/typicons_grey_dark/chevron-left.svg | 31 +++++++++++++++++++
.../typicons_grey_dark/chevron-right.svg | 31 +++++++++++++++++++
nw/assets/icons/typicons_grey_dark/icons.conf | 2 ++
.../typicons_grey_light/chevron-left.svg | 31 +++++++++++++++++++
.../typicons_grey_light/chevron-right.svg | 31 +++++++++++++++++++
.../icons/typicons_grey_light/icons.conf | 2 ++
12 files changed, 256 insertions(+)
create mode 100644 nw/assets/icons/typicons_colour_dark/chevron-left.svg
create mode 100644 nw/assets/icons/typicons_colour_dark/chevron-right.svg
create mode 100644 nw/assets/icons/typicons_colour_light/chevron-left.svg
create mode 100644 nw/assets/icons/typicons_colour_light/chevron-right.svg
create mode 100644 nw/assets/icons/typicons_grey_dark/chevron-left.svg
create mode 100644 nw/assets/icons/typicons_grey_dark/chevron-right.svg
create mode 100644 nw/assets/icons/typicons_grey_light/chevron-left.svg
create mode 100644 nw/assets/icons/typicons_grey_light/chevron-right.svg
diff --git a/nw/assets/icons/typicons_colour_dark/chevron-left.svg b/nw/assets/icons/typicons_colour_dark/chevron-left.svg
new file mode 100644
index 00000000..df4d0635
--- /dev/null
+++ b/nw/assets/icons/typicons_colour_dark/chevron-left.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/nw/assets/icons/typicons_colour_dark/chevron-right.svg b/nw/assets/icons/typicons_colour_dark/chevron-right.svg
new file mode 100644
index 00000000..b5671fa7
--- /dev/null
+++ b/nw/assets/icons/typicons_colour_dark/chevron-right.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/nw/assets/icons/typicons_colour_dark/icons.conf b/nw/assets/icons/typicons_colour_dark/icons.conf
index 8432bf1a..a5930cfc 100644
--- a/nw/assets/icons/typicons_colour_dark/icons.conf
+++ b/nw/assets/icons/typicons_colour_dark/icons.conf
@@ -51,5 +51,7 @@ check = tick.svg
cross = times.svg
hash = hash.svg
reference = at.svg
+backward = chevron-left.svg
+forward = chevron-right.svg
sticky-on = pin.svg
sticky-off = pin-outline.svg
diff --git a/nw/assets/icons/typicons_colour_light/chevron-left.svg b/nw/assets/icons/typicons_colour_light/chevron-left.svg
new file mode 100644
index 00000000..6125533e
--- /dev/null
+++ b/nw/assets/icons/typicons_colour_light/chevron-left.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/nw/assets/icons/typicons_colour_light/chevron-right.svg b/nw/assets/icons/typicons_colour_light/chevron-right.svg
new file mode 100644
index 00000000..b4f300e1
--- /dev/null
+++ b/nw/assets/icons/typicons_colour_light/chevron-right.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/nw/assets/icons/typicons_colour_light/icons.conf b/nw/assets/icons/typicons_colour_light/icons.conf
index eb0f9b2e..934ad1d6 100644
--- a/nw/assets/icons/typicons_colour_light/icons.conf
+++ b/nw/assets/icons/typicons_colour_light/icons.conf
@@ -51,5 +51,7 @@ check = tick.svg
cross = times.svg
hash = hash.svg
reference = at.svg
+backward = chevron-left.svg
+forward = chevron-right.svg
sticky-on = pin.svg
sticky-off = pin-outline.svg
diff --git a/nw/assets/icons/typicons_grey_dark/chevron-left.svg b/nw/assets/icons/typicons_grey_dark/chevron-left.svg
new file mode 100644
index 00000000..bc1c987f
--- /dev/null
+++ b/nw/assets/icons/typicons_grey_dark/chevron-left.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/nw/assets/icons/typicons_grey_dark/chevron-right.svg b/nw/assets/icons/typicons_grey_dark/chevron-right.svg
new file mode 100644
index 00000000..18eafe98
--- /dev/null
+++ b/nw/assets/icons/typicons_grey_dark/chevron-right.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/nw/assets/icons/typicons_grey_dark/icons.conf b/nw/assets/icons/typicons_grey_dark/icons.conf
index 5fa6d680..81829f57 100644
--- a/nw/assets/icons/typicons_grey_dark/icons.conf
+++ b/nw/assets/icons/typicons_grey_dark/icons.conf
@@ -51,5 +51,7 @@ check = tick.svg
cross = times.svg
hash = hash.svg
reference = at.svg
+backward = chevron-left.svg
+forward = chevron-right.svg
sticky-on = pin.svg
sticky-off = pin-outline.svg
diff --git a/nw/assets/icons/typicons_grey_light/chevron-left.svg b/nw/assets/icons/typicons_grey_light/chevron-left.svg
new file mode 100644
index 00000000..2e7af570
--- /dev/null
+++ b/nw/assets/icons/typicons_grey_light/chevron-left.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/nw/assets/icons/typicons_grey_light/chevron-right.svg b/nw/assets/icons/typicons_grey_light/chevron-right.svg
new file mode 100644
index 00000000..8da983ca
--- /dev/null
+++ b/nw/assets/icons/typicons_grey_light/chevron-right.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/nw/assets/icons/typicons_grey_light/icons.conf b/nw/assets/icons/typicons_grey_light/icons.conf
index 4363e16f..145dc153 100644
--- a/nw/assets/icons/typicons_grey_light/icons.conf
+++ b/nw/assets/icons/typicons_grey_light/icons.conf
@@ -51,5 +51,7 @@ check = tick.svg
cross = times.svg
hash = hash.svg
reference = at.svg
+backward = chevron-left.svg
+forward = chevron-right.svg
sticky-on = pin.svg
sticky-off = pin-outline.svg
From a7a345f05cb3fde0ba48f8371eb420cdd87be074 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Tue, 8 Sep 2020 22:00:07 +0200
Subject: [PATCH 5/8] Added backward and forward nav buttons
---
nw/gui/docviewer.py | 59 +++++++++++++++++++++++++++++++++++++++++----
nw/gui/theme.py | 2 ++
2 files changed, 56 insertions(+), 5 deletions(-)
diff --git a/nw/gui/docviewer.py b/nw/gui/docviewer.py
index 024b1723..e075f80b 100644
--- a/nw/gui/docviewer.py
+++ b/nw/gui/docviewer.py
@@ -577,6 +577,7 @@ class GuiDocViewHistory():
self._prevPos = self._currPos
self._currPos = len(self._navHistory) - 1
self._updateScrollBar()
+ self._updateNavButtons()
self._dumpHistory()
@@ -596,6 +597,7 @@ class GuiDocViewHistory():
self.docViewer.loadText(self._navHistory[newPos], updateHistory=False)
self.docViewer.setScrollPosition(self._posHistory[newPos])
self._currPos = newPos
+ self._updateNavButtons()
self._dumpHistory()
@@ -613,6 +615,7 @@ class GuiDocViewHistory():
self.docViewer.loadText(self._navHistory[newPos], updateHistory=False)
self.docViewer.setScrollPosition(self._posHistory[newPos])
self._currPos = newPos
+ self._updateNavButtons()
self._dumpHistory()
@@ -629,10 +632,16 @@ class GuiDocViewHistory():
self._posHistory[self._prevPos] = self.docViewer.getScrollPosition()
return
+ def _updateNavButtons(self):
+ """Update the navigation buttons in the document header.
+ """
+ self.docViewer.docHeader.updateNavButtons(0, len(self._navHistory) - 1, self._currPos)
+ return
+
def _truncateHistory(self, atPos):
"""Truncate the navigation history to the given position.
"""
- nSkip = 1 if atPos > 49 else 0
+ nSkip = 1 if atPos > 19 else 0
self._navHistory = self._navHistory[nSkip:atPos + 1]
self._posHistory = self._posHistory[nSkip:atPos + 1]
@@ -643,8 +652,15 @@ class GuiDocViewHistory():
return
def _dumpHistory(self):
- for i, (h, p) in enumerate(zip(self._navHistory, self._posHistory)):
- print("%s %3d %13s %6d" % (">" if i == self._currPos else " ", i, h, p))
+ """Debug function to dump history. Since it is a for loop, it is
+ skipped entirely if log level isn't VERBOSE.
+ """
+ if logger.getEffectiveLevel() < logging.DEBUG:
+ for i, (h, p) in enumerate(zip(self._navHistory, self._posHistory)):
+ logger.verbose(
+ "History: %s %2d %13s %5d" % (">" if i == self._currPos else " ", i, h, p)
+ )
+ return
# END Class GuiDocViewHistory
@@ -674,10 +690,8 @@ class GuiDocViewHeader(QWidget):
fPx = int(0.9*self.theTheme.fontPixelSize)
hSp = self.mainConf.pxInt(6)
- self.buttonSize = fPx + hSp
# Main Widget Settings
- self.setContentsMargins(2*self.buttonSize, 0, 0, 0)
self.setAutoFillBackground(True)
self.setPalette(self.thePalette)
@@ -702,6 +716,28 @@ class GuiDocViewHeader(QWidget):
).format(*self.theTheme.colText)
# Buttons
+ self.backButton = QToolButton(self)
+ self.backButton.setIcon(self.theTheme.getIcon("backward"))
+ self.backButton.setContentsMargins(0, 0, 0, 0)
+ self.backButton.setIconSize(QSize(fPx, fPx))
+ self.backButton.setFixedSize(fPx, fPx)
+ self.backButton.setStyleSheet(buttonStyle)
+ self.backButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
+ self.backButton.setVisible(False)
+ self.backButton.setToolTip("Go backward")
+ self.backButton.clicked.connect(self.docViewer.navBackward)
+
+ self.forwardButton = QToolButton(self)
+ self.forwardButton.setIcon(self.theTheme.getIcon("forward"))
+ self.forwardButton.setContentsMargins(0, 0, 0, 0)
+ self.forwardButton.setIconSize(QSize(fPx, fPx))
+ self.forwardButton.setFixedSize(fPx, fPx)
+ self.forwardButton.setStyleSheet(buttonStyle)
+ self.forwardButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
+ self.forwardButton.setVisible(False)
+ self.forwardButton.setToolTip("Go forward")
+ self.forwardButton.clicked.connect(self.docViewer.navForward)
+
self.refreshButton = QToolButton(self)
self.refreshButton.setIcon(self.theTheme.getIcon("refresh"))
self.refreshButton.setContentsMargins(0, 0, 0, 0)
@@ -727,6 +763,8 @@ class GuiDocViewHeader(QWidget):
# Assemble Layout
self.outerBox = QHBoxLayout()
self.outerBox.setSpacing(hSp)
+ self.outerBox.addWidget(self.backButton, 0)
+ self.outerBox.addWidget(self.forwardButton, 0)
self.outerBox.addWidget(self.theTitle, 1)
self.outerBox.addWidget(self.refreshButton, 0)
self.outerBox.addWidget(self.closeButton, 0)
@@ -747,6 +785,8 @@ class GuiDocViewHeader(QWidget):
self.theHandle = tHandle
if tHandle is None:
self.theTitle.setText("")
+ self.backButton.setVisible(False)
+ self.forwardButton.setVisible(False)
self.closeButton.setVisible(False)
self.refreshButton.setVisible(False)
return True
@@ -766,11 +806,20 @@ class GuiDocViewHeader(QWidget):
return False
self.theTitle.setText(nwItem.itemName)
+ self.backButton.setVisible(True)
+ self.forwardButton.setVisible(True)
self.closeButton.setVisible(True)
self.refreshButton.setVisible(True)
return True
+ def updateNavButtons(self, firstIdx, lastIdx, currIdx):
+ """Enable and disable nav buttons based on index in history.
+ """
+ self.backButton.setEnabled(currIdx > firstIdx)
+ self.forwardButton.setEnabled(currIdx < lastIdx)
+ return
+
##
# Slots
##
diff --git a/nw/gui/theme.py b/nw/gui/theme.py
index fd2826a0..9abfb523 100644
--- a/nw/gui/theme.py
+++ b/nw/gui/theme.py
@@ -554,6 +554,8 @@ class GuiIcons:
"minimise" : (None, None),
"refresh" : (None, None),
"reference" : (None, None),
+ "backward" : (None, None),
+ "forward" : (None, None),
## Switches
"sticky-on" : (None, None),
From d8aa29f656dc08a4dd9e09057f458f25bc01e110 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Tue, 8 Sep 2020 22:10:08 +0200
Subject: [PATCH 6/8] Added test coverage of navigation buttons and class
---
tests/test_gui.py | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/tests/test_gui.py b/tests/test_gui.py
index bdb684ff..524e74c9 100644
--- a/tests/test_gui.py
+++ b/tests/test_gui.py
@@ -1163,6 +1163,22 @@ def testDocAction(qtbot, nwLipsum, nwTemp):
"nunc lacus, imperdiet nec posuere ac, interdum non lectus."
)
+ # Navigation History
+ assert nwGUI.viewDocument("04468803b92e1")
+ assert nwGUI.docViewer.theHandle == "04468803b92e1"
+ assert nwGUI.docViewer.docHeader.backButton.isEnabled()
+ assert not nwGUI.docViewer.docHeader.forwardButton.isEnabled()
+
+ qtbot.mouseClick(nwGUI.docViewer.docHeader.backButton, Qt.LeftButton)
+ assert nwGUI.docViewer.theHandle == "4c4f28287af27"
+ assert not nwGUI.docViewer.docHeader.backButton.isEnabled()
+ assert nwGUI.docViewer.docHeader.forwardButton.isEnabled()
+
+ qtbot.mouseClick(nwGUI.docViewer.docHeader.forwardButton, Qt.LeftButton)
+ assert nwGUI.docViewer.theHandle == "04468803b92e1"
+ assert nwGUI.docViewer.docHeader.backButton.isEnabled()
+ assert not nwGUI.docViewer.docHeader.forwardButton.isEnabled()
+
# qtbot.stopForInteraction()
nwGUI.closeMain()
From b67a518b9897db7f06a0caf8a11863cf365f24c1 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Tue, 8 Sep 2020 22:25:37 +0200
Subject: [PATCH 7/8] Renamed menu entries and updated docs
---
docs/source/int_interface.rst | 2 ++
nw/gui/mainmenu.py | 12 ++++++------
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/docs/source/int_interface.rst b/docs/source/int_interface.rst
index 3c4b772a..599757dc 100644
--- a/docs/source/int_interface.rst
+++ b/docs/source/int_interface.rst
@@ -328,6 +328,8 @@ Most features are available as keyboard shortcuts. These are as follows:
":kbd:`Alt`:kbd:`1`", "Switch focus to the project tree."
":kbd:`Alt`:kbd:`2`", "Switch focus to document editor."
":kbd:`Alt`:kbd:`3`", "Switch focus to document viewer."
+ ":kbd:`Alt`:kbd:`Left`", "Move backward in the view history of the document viewer."
+ ":kbd:`Alt`:kbd:`Right`", "Move forward in the view history of the document viewer."
":kbd:`Ctrl`:kbd:`.`", "Open menu to correct word under cursor."
":kbd:`Ctrl`:kbd:`,`", "Open the :guilabel:`Preferences` dialog."
":kbd:`Ctrl`:kbd:`/`", "Change block format to comment."
diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py
index ed96a4ee..9c4ce12c 100644
--- a/nw/gui/mainmenu.py
+++ b/nw/gui/mainmenu.py
@@ -475,16 +475,16 @@ class GuiMainMenu(QMenuBar):
# View > Separator
self.viewMenu.addSeparator()
- # View > Navigate Viewer Backward
- self.aViewPrev = QAction("Navigate Viewer Backward", self)
- self.aViewPrev.setStatusTip("Show the previous document in the right pane")
+ # View > Go Backward
+ self.aViewPrev = QAction("Go Backward", self)
+ self.aViewPrev.setStatusTip("Move backward in the view history of the right pane")
self.aViewPrev.setShortcut("Alt+Left")
self.aViewPrev.triggered.connect(self.theParent.docViewer.navBackward)
self.viewMenu.addAction(self.aViewPrev)
- # View > Navigate Viewer Forward
- self.aViewNext = QAction("Navigate Viewer Forward", self)
- self.aViewNext.setStatusTip("Show the next document in the right pane")
+ # View > Go Forward
+ self.aViewNext = QAction("Go Forward", self)
+ self.aViewNext.setStatusTip("Move forward in the view history of the right pane")
self.aViewNext.setShortcut("Alt+Right")
self.aViewNext.triggered.connect(self.theParent.docViewer.navForward)
self.viewMenu.addAction(self.aViewNext)
From ad8d3845375b2f7652b7e2fef662440a4138a8c6 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Tue, 8 Sep 2020 22:42:18 +0200
Subject: [PATCH 8/8] Add fallback icons
---
nw/assets/icons/fallback/backward-dark.svg | 31 ++++++++++++++++++++++
nw/assets/icons/fallback/backward.svg | 31 ++++++++++++++++++++++
nw/assets/icons/fallback/forward-dark.svg | 31 ++++++++++++++++++++++
nw/assets/icons/fallback/forward.svg | 31 ++++++++++++++++++++++
4 files changed, 124 insertions(+)
create mode 100644 nw/assets/icons/fallback/backward-dark.svg
create mode 100644 nw/assets/icons/fallback/backward.svg
create mode 100644 nw/assets/icons/fallback/forward-dark.svg
create mode 100644 nw/assets/icons/fallback/forward.svg
diff --git a/nw/assets/icons/fallback/backward-dark.svg b/nw/assets/icons/fallback/backward-dark.svg
new file mode 100644
index 00000000..bc1c987f
--- /dev/null
+++ b/nw/assets/icons/fallback/backward-dark.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/nw/assets/icons/fallback/backward.svg b/nw/assets/icons/fallback/backward.svg
new file mode 100644
index 00000000..2e7af570
--- /dev/null
+++ b/nw/assets/icons/fallback/backward.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/nw/assets/icons/fallback/forward-dark.svg b/nw/assets/icons/fallback/forward-dark.svg
new file mode 100644
index 00000000..18eafe98
--- /dev/null
+++ b/nw/assets/icons/fallback/forward-dark.svg
@@ -0,0 +1,31 @@
+
+
diff --git a/nw/assets/icons/fallback/forward.svg b/nw/assets/icons/fallback/forward.svg
new file mode 100644
index 00000000..8da983ca
--- /dev/null
+++ b/nw/assets/icons/fallback/forward.svg
@@ -0,0 +1,31 @@
+
+