From 4340b6b8b5725323c9366712f27ec54bdf9ffd56 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Mon, 25 May 2020 23:31:41 +0200
Subject: [PATCH] It should now be possible to navigate to positions within the
documents when clicking links in various places
---
nw/core/index.py | 21 +++++++-------
nw/gui/elements/docviewer.py | 52 +++++++++++++++-------------------
nw/gui/elements/viewdetails.py | 15 +++-------
nw/guimain.py | 4 +--
4 files changed, 40 insertions(+), 52 deletions(-)
diff --git a/nw/core/index.py b/nw/core/index.py
index 79e6ddba..456b415c 100644
--- a/nw/core/index.py
+++ b/nw/core/index.py
@@ -199,7 +199,7 @@ class NWIndex():
try:
for tTag in self.tagIndex:
- if len(self.tagIndex[tTag]) != 3:
+ if len(self.tagIndex[tTag]) != 4:
self.indexBroken = True
for tHandle in self.refIndex:
@@ -228,7 +228,7 @@ class NWIndex():
if self.indexBroken:
self.clearIndex()
self.theParent.makeAlert(
- "The index loaded from project cache contains errors. Rebuilding index.",
+ "The project index is outdated or broken. Rebuilding index.",
nwAlert.WARN
)
@@ -301,7 +301,7 @@ class NWIndex():
elif aLine.startswith(r"@"):
self._indexNoteRef(tHandle, aLine, nLine, nTitle)
- self._indexTag(tHandle, aLine, nLine, itemClass)
+ self._indexTag(tHandle, aLine, nLine, nTitle, itemClass)
elif aLine.startswith(r"%"):
if nTitle > 0:
@@ -436,7 +436,7 @@ class NWIndex():
return True
- def _indexTag(self, tHandle, aLine, nLine, itemClass):
+ def _indexTag(self, tHandle, aLine, nLine, nTitle, itemClass):
"""Validate and save the information from a tag.
"""
isValid, theBits, thePos = self.scanThis(aLine)
@@ -444,7 +444,8 @@ class NWIndex():
return False
if theBits[0] == nwKeyWords.TAG_KEY:
- self.tagIndex[theBits[1]] = [nLine, tHandle, itemClass.name]
+ sTitle = "T%06d" % nTitle
+ self.tagIndex[theBits[1]] = [nLine, tHandle, itemClass.name, sTitle]
return True
@@ -606,10 +607,10 @@ class NWIndex():
if tHandle is None:
return theRefs
- theTags = []
+ theTags = set()
for tTag in self.tagIndex:
if tHandle == self.tagIndex[tTag][1]:
- theTags.append(tTag)
+ theTags.add(tTag)
if theTags:
for tHandle in self.refIndex:
@@ -625,8 +626,8 @@ class NWIndex():
"""
if theTag in self.tagIndex:
theRef = self.tagIndex[theTag]
- if len(theRef) == 3:
- return theRef[1], theRef[0]
- return None, 0
+ if len(theRef) == 4:
+ return theRef[1], theRef[0], theRef[3]
+ return None, 0, "T000000"
# END Class NWIndex
diff --git a/nw/gui/elements/docviewer.py b/nw/gui/elements/docviewer.py
index 6d90c2f5..df1355be 100644
--- a/nw/gui/elements/docviewer.py
+++ b/nw/gui/elements/docviewer.py
@@ -28,7 +28,7 @@
import logging
import nw
-from PyQt5.QtCore import Qt
+from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtWidgets import QTextBrowser
from PyQt5.QtGui import QTextOption, QFont, QPalette, QColor, QTextCursor
@@ -133,6 +133,7 @@ class GuiDocViewer(QTextBrowser):
sPos = self.verticalScrollBar().value()
aDoc = ToHtml(self.theProject, self.theParent)
aDoc.setPreview(True, self.mainConf.viewComments)
+ aDoc.setLinkHeaders(True)
aDoc.setText(tHandle)
aDoc.doAutoReplace()
aDoc.tokenizeText()
@@ -162,19 +163,17 @@ class GuiDocViewer(QTextBrowser):
index being up to date.
"""
logger.debug("Loading document from tag '%s'" % theTag)
-
- if theTag in self.theParent.theIndex.tagIndex.keys():
- theTarget = self.theParent.theIndex.tagIndex[theTag]
+ tHandle, onLine, 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 "
+ "exist, or the index is out of date. The index can be updated "
+ "from the Tools menu, or by pressing F9."
+ ) % theTag, nwAlert.ERROR)
+ return
else:
- logger.debug("The tag was not found in the index")
- return False
-
- if len(theTarget) != 3:
- # Just to make sure the index is not messed up
- return False
-
- self.loadText(theTarget[1])
-
+ self.loadText(tHandle)
+ self.navigateTo("#head_%s:%s" % (tHandle, sTitle))
return True
def docAction(self, theAction):
@@ -198,6 +197,15 @@ class GuiDocViewer(QTextBrowser):
return False
return True
+ def navigateTo(self, navLink):
+ """Go to a specific #link in the document.
+ """
+ if not isinstance(navLink, str):
+ return False
+ if navLink.startswith("#"):
+ self.setSource(QUrl(navLink))
+ return True
+
def updateDocTitle(self, tHandle):
"""Called when an item label is changed to check if the document
title bar needs updating,
@@ -271,25 +279,11 @@ class GuiDocViewer(QTextBrowser):
"""Slot for a link in the document being clicked.
"""
theLink = theURL.url()
- tHandle = None
- onLine = 0
- theTag = ""
+ logger.verbose("Clicked link: '%s'" % theLink)
if len(theLink) > 0:
theBits = theLink.split("=")
if len(theBits) == 2:
- theTag = theBits[1]
- tHandle, onLine = self.theParent.theIndex.getTagSource(theBits[1])
-
- if tHandle is None:
- self.theParent.makeAlert((
- "Could not find the reference for tag '%s'. It either doesn't exist, or the index "
- "is out of date. The index can be updated from the Tools menu.") % theTag,
- nwAlert.ERROR
- )
- return
- else:
- self.loadText(tHandle)
-
+ self.loadFromTag(theBits[1])
return
def _makeStyleSheet(self):
diff --git a/nw/gui/elements/viewdetails.py b/nw/gui/elements/viewdetails.py
index d5ab7ee8..d4b2621c 100644
--- a/nw/gui/elements/viewdetails.py
+++ b/nw/gui/elements/viewdetails.py
@@ -107,12 +107,10 @@ class GuiDocViewDetails(QWidget):
for tHandle in theRefs:
tItem = self.theProject.projTree[tHandle]
if tItem is not None:
- theList.append("%s" % (
+ theList.append("%s" % (
tHandle, theRefs[tHandle], tItem.itemName
))
- # print(theList)
-
self.refList.setText(", ".join(theList))
self.refList.adjustSize()
@@ -127,14 +125,9 @@ class GuiDocViewDetails(QWidget):
class for handling.
"""
logger.verbose("Clicked link: '%s'" % theLink)
- if len(theLink) == 26:
- tHandle = theLink[5:18]
- tLine = theLink[19:26]
- if tLine[1:].isdigit():
- nLine = int(tLine[1:])
- else:
- nLine = 1
- self.theParent.viewDocument(tHandle, nLine)
+ if len(theLink) == 27:
+ tHandle = theLink[6:19]
+ self.theParent.viewDocument(tHandle, theLink)
return
def _doShowHide(self, chState):
diff --git a/nw/guimain.py b/nw/guimain.py
index 8aeb7143..f0d0d3cc 100644
--- a/nw/guimain.py
+++ b/nw/guimain.py
@@ -485,7 +485,7 @@ class GuiMain(QMainWindow):
self.docEditor.saveText()
return True
- def viewDocument(self, tHandle=None, nLine=0):
+ def viewDocument(self, tHandle=None, navLink=None):
"""Load a document for viewing in the view panel.
"""
if tHandle is None:
@@ -511,7 +511,7 @@ class GuiMain(QMainWindow):
vPos[0] = int(bPos[1]/2)
vPos[1] = bPos[1]-vPos[0]
self.splitView.setSizes(vPos)
- self.docViewer.setCursorLine(nLine)
+ self.docViewer.navigateTo(navLink)
return True