Merge branch 'main' into release_1.0b2

This commit is contained in:
Veronica K. B. Olsen
2020-09-08 23:21:33 +02:00
24 changed files with 678 additions and 25 deletions
+2
View File
@@ -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."
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8980"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata8986">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8984" />
<path
style="fill:#aeaeae;fill-opacity:1;stroke-width:1.28574"
id="path8978"
d="m 17.565474,3.7531206 c -1.002875,-1.0041608 -2.63319,-1.0041608 -3.636065,0 L 5.6814051,11.999839 13.929409,20.246558 C 14.430847,20.749281 15.089144,21 15.747442,21 c 0.658297,0 1.316595,-0.250719 1.818032,-0.753442 1.004161,-1.004161 1.004161,-2.631904 0,-3.636065 l -4.609368,-4.610654 4.609368,-4.6106535 c 1.004161,-1.0041608 1.004161,-2.6319041 0,-3.6360649 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

+31
View File
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8980"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata8986">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8984" />
<path
style="fill:#000000;fill-opacity:0.78;stroke-width:1.28574"
id="path8978"
d="m 17.565474,3.7531206 c -1.002875,-1.0041608 -2.63319,-1.0041608 -3.636065,0 L 5.6814051,11.999839 13.929409,20.246558 C 14.430847,20.749281 15.089144,21 15.747442,21 c 0.658297,0 1.316595,-0.250719 1.818032,-0.753442 1.004161,-1.004161 1.004161,-2.631904 0,-3.636065 l -4.609368,-4.610654 4.609368,-4.6106535 c 1.004161,-1.0041608 1.004161,-2.6319041 0,-3.6360649 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+31
View File
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8980"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata8986">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8984" />
<path
style="fill:#aeaeae;fill-opacity:1;stroke-width:1.28574"
id="path8978"
d="m 6.4345258,3.7531206 c 1.002875,-1.0041608 2.63319,-1.0041608 3.6360652,0 l 8.248004,8.2467184 -8.248004,8.246719 C 9.5691528,20.749281 8.9108558,21 8.2525578,21 c -0.658297,0 -1.316595,-0.250719 -1.818032,-0.753442 -1.004161,-1.004161 -1.004161,-2.631904 0,-3.636065 L 11.043894,11.999839 6.4345258,7.3891855 c -1.004161,-1.0041608 -1.004161,-2.6319041 0,-3.6360649 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+31
View File
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8980"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata8986">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8984" />
<path
style="fill:#000000;fill-opacity:0.77999997;stroke-width:1.28574"
id="path8978"
d="m 6.4345258,3.7531206 c 1.002875,-1.0041608 2.63319,-1.0041608 3.6360652,0 l 8.248004,8.2467184 -8.248004,8.246719 C 9.5691528,20.749281 8.9108558,21 8.2525578,21 c -0.658297,0 -1.316595,-0.250719 -1.818032,-0.753442 -1.004161,-1.004161 -1.004161,-2.631904 0,-3.636065 L 11.043894,11.999839 6.4345258,7.3891855 c -1.004161,-1.0041608 -1.004161,-2.6319041 0,-3.6360649 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8980"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata8986">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8984" />
<path
style="stroke-width:1.28574;fill:#6699cc;fill-opacity:1"
id="path8978"
d="m 17.565474,3.7531206 c -1.002875,-1.0041608 -2.63319,-1.0041608 -3.636065,0 L 5.6814051,11.999839 13.929409,20.246558 C 14.430847,20.749281 15.089144,21 15.747442,21 c 0.658297,0 1.316595,-0.250719 1.818032,-0.753442 1.004161,-1.004161 1.004161,-2.631904 0,-3.636065 l -4.609368,-4.610654 4.609368,-4.6106535 c 1.004161,-1.0041608 1.004161,-2.6319041 0,-3.6360649 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8980"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata8986">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8984" />
<path
style="fill:#6699cc;fill-opacity:1;stroke-width:1.28574"
id="path8978"
d="m 6.4345258,3.7531206 c 1.002875,-1.0041608 2.63319,-1.0041608 3.6360652,0 l 8.248004,8.2467184 -8.248004,8.246719 C 9.5691528,20.749281 8.9108558,21 8.2525578,21 c -0.658297,0 -1.316595,-0.250719 -1.818032,-0.753442 -1.004161,-1.004161 -1.004161,-2.631904 0,-3.636065 L 11.043894,11.999839 6.4345258,7.3891855 c -1.004161,-1.0041608 -1.004161,-2.6319041 0,-3.6360649 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -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
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8980"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata8986">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8984" />
<path
style="fill:#4271ae;fill-opacity:1;stroke-width:1.28574"
id="path8978"
d="m 17.565474,3.7531206 c -1.002875,-1.0041608 -2.63319,-1.0041608 -3.636065,0 L 5.6814051,11.999839 13.929409,20.246558 C 14.430847,20.749281 15.089144,21 15.747442,21 c 0.658297,0 1.316595,-0.250719 1.818032,-0.753442 1.004161,-1.004161 1.004161,-2.631904 0,-3.636065 l -4.609368,-4.610654 4.609368,-4.6106535 c 1.004161,-1.0041608 1.004161,-2.6319041 0,-3.6360649 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8980"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata8986">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8984" />
<path
style="fill:#4271ae;fill-opacity:1;stroke-width:1.28574"
id="path8978"
d="m 6.4345258,3.7531206 c 1.002875,-1.0041608 2.63319,-1.0041608 3.6360652,0 l 8.248004,8.2467184 -8.248004,8.246719 C 9.5691528,20.749281 8.9108558,21 8.2525578,21 c -0.658297,0 -1.316595,-0.250719 -1.818032,-0.753442 -1.004161,-1.004161 -1.004161,-2.631904 0,-3.636065 L 11.043894,11.999839 6.4345258,7.3891855 c -1.004161,-1.0041608 -1.004161,-2.6319041 0,-3.6360649 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -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
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8980"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata8986">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8984" />
<path
style="fill:#aeaeae;fill-opacity:1;stroke-width:1.28574"
id="path8978"
d="m 17.565474,3.7531206 c -1.002875,-1.0041608 -2.63319,-1.0041608 -3.636065,0 L 5.6814051,11.999839 13.929409,20.246558 C 14.430847,20.749281 15.089144,21 15.747442,21 c 0.658297,0 1.316595,-0.250719 1.818032,-0.753442 1.004161,-1.004161 1.004161,-2.631904 0,-3.636065 l -4.609368,-4.610654 4.609368,-4.6106535 c 1.004161,-1.0041608 1.004161,-2.6319041 0,-3.6360649 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8980"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata8986">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8984" />
<path
style="fill:#aeaeae;fill-opacity:1;stroke-width:1.28574"
id="path8978"
d="m 6.4345258,3.7531206 c 1.002875,-1.0041608 2.63319,-1.0041608 3.6360652,0 l 8.248004,8.2467184 -8.248004,8.246719 C 9.5691528,20.749281 8.9108558,21 8.2525578,21 c -0.658297,0 -1.316595,-0.250719 -1.818032,-0.753442 -1.004161,-1.004161 -1.004161,-2.631904 0,-3.636065 L 11.043894,11.999839 6.4345258,7.3891855 c -1.004161,-1.0041608 -1.004161,-2.6319041 0,-3.6360649 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -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
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8980"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata8986">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8984" />
<path
style="fill:#000000;fill-opacity:0.78;stroke-width:1.28574"
id="path8978"
d="m 17.565474,3.7531206 c -1.002875,-1.0041608 -2.63319,-1.0041608 -3.636065,0 L 5.6814051,11.999839 13.929409,20.246558 C 14.430847,20.749281 15.089144,21 15.747442,21 c 0.658297,0 1.316595,-0.250719 1.818032,-0.753442 1.004161,-1.004161 1.004161,-2.631904 0,-3.636065 l -4.609368,-4.610654 4.609368,-4.6106535 c 1.004161,-1.0041608 1.004161,-2.6319041 0,-3.6360649 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8980"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata8986">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8984" />
<path
style="fill:#000000;fill-opacity:0.77999997;stroke-width:1.28574"
id="path8978"
d="m 6.4345258,3.7531206 c 1.002875,-1.0041608 2.63319,-1.0041608 3.6360652,0 l 8.248004,8.2467184 -8.248004,8.246719 C 9.5691528,20.749281 8.9108558,21 8.2525578,21 c -0.658297,0 -1.316595,-0.250719 -1.818032,-0.753442 -1.004161,-1.004161 -1.004161,-2.631904 0,-3.636065 L 11.043894,11.999839 6.4345258,7.3891855 c -1.004161,-1.0041608 -1.004161,-2.6319041 0,-3.6360649 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -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
+1 -1
View File
@@ -189,7 +189,7 @@ class ToHtml(Tokenizer):
hStyle = ""
if self.linkHeaders:
aNm = "<a name='head_%s:T%06d'></a>" % (self.theHandle, tLine)
aNm = "<a name='T%06d'></a>" % tLine
else:
aNm = ""
+238 -18
View File
@@ -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
@@ -63,20 +64,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)
@@ -129,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]
@@ -167,7 +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)
# 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 +211,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 +223,8 @@ 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.
self.theParent.viewDocument(tHandle)
self.navigateTo("#head_%s:%s" % (tHandle, sTitle))
logger.verbose("Tag points to %s#%s" % (tHandle, sTitle))
self.theParent.viewDocument(tHandle, "#%s" % sTitle)
return True
def docAction(self, theAction):
@@ -240,15 +248,34 @@ 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 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 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,
@@ -309,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
##
@@ -379,6 +426,17 @@ 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()
else:
QTextBrowser.mouseReleaseEvent(self, theEvent)
return
##
# Internal Functions
##
@@ -478,6 +536,134 @@ class GuiDocViewer(QTextBrowser):
# END Class GuiDocViewer
class GuiDocViewHistory():
def __init__(self, docViewer):
self.docViewer = docViewer
self._navHistory = []
self._posHistory = []
self._currPos = -1
self._prevPos = -1
return
def clear(self):
"""Clear the view history.
"""
logger.verbose("View history cleared")
self._navHistory = []
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._updateNavButtons()
self._dumpHistory()
logger.verbose("Added %s to view history" % tHandle)
return True
def forward(self):
"""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._updateNavButtons()
self._dumpHistory()
return
def backward(self):
"""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._updateNavButtons()
self._dumpHistory()
return
##
# Internal Functions
##
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 _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 > 19 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):
"""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
# =============================================================================================== #
# The Embedded Document Header
# Only used by DocViewer, and is at a fixed position in the QTextBrowser's viewport
@@ -504,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)
@@ -532,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)
@@ -557,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)
@@ -577,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
@@ -596,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
##
@@ -818,7 +1037,7 @@ class GuiDocViewDetails(QScrollArea):
for tHandle in theRefs:
tItem = self.theProject.projTree[tHandle]
if tItem is not None:
theList.append("<a href='#head_%s:%s' %s>%s</a>" % (
theList.append("<a href='%s#%s' %s>%s</a>" % (
tHandle, theRefs[tHandle], self.linkStyle, tItem.itemName
))
@@ -835,9 +1054,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
+17
View File
@@ -475,6 +475,23 @@ class GuiMainMenu(QMenuBar):
# View > Separator
self.viewMenu.addSeparator()
# 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 > 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)
# 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")
+19 -4
View File
@@ -662,13 +662,28 @@ class GuiProjectTree(QTreeWidget):
def mousePressEvent(self, theEvent):
"""Overload mousePressEvent to clear selection if clicking the
mouse in a blank area of the tree view.
mouse in a blank area of the tree view, and to load a document
for viewing if the suer middle clicked.
"""
QTreeWidget.mousePressEvent(self, theEvent)
selItem = self.indexAt(theEvent.pos())
if not selItem.isValid():
self.clearSelection()
if theEvent.button() == Qt.LeftButton:
selItem = self.indexAt(theEvent.pos())
if not selItem.isValid():
self.clearSelection()
elif theEvent.button() == Qt.MiddleButton:
selItem = self.itemAt(theEvent.pos())
if not isinstance(selItem, QTreeWidgetItem):
return
tHandle = selItem.data(self.C_NAME, Qt.UserRole)
tItem = self.theProject.projTree[tHandle]
if tItem is None:
return
if tItem.itemType == nwItemType.FILE:
self.theParent.viewDocument(tHandle)
return
+2
View File
@@ -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),
+3 -2
View File
@@ -346,6 +346,7 @@ class GuiMain(QMainWindow):
if saveOK:
self.closeDocument()
self.docViewer.clearNavHistory()
self.projView.closeOutline()
self.theProject.closeProject()
self.theIndex.clearIndex()
@@ -525,7 +526,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 +563,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
+16
View File
@@ -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()