Merge pull request #306 from vkbo/tweaks

Minor Tweaks and Fixes
This commit is contained in:
Veronica K. Berglyd Olsen
2020-06-11 18:11:27 +02:00
committed by GitHub
25 changed files with 719 additions and 452 deletions
+3 -1
View File
@@ -216,7 +216,9 @@ def main(sysArgs=None):
logger.addHandler(cHandle)
logger.setLevel(debugLevel)
logger.info("This is %s %s" % (__package__, __version__))
logger.info("Starting %s" % __package__)
logger.info("Version: %s (%s)" % (__version__, __hexversion__))
logger.info("Last Release: %s" % __date__)
# Check Packages and Versions
errorData = []
+6 -6
View File
@@ -5,13 +5,13 @@
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="svg2608"
id="svg1321"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata2614">
id="metadata1327">
<rdf:RDF>
<cc:Work
rdf:about="">
@@ -23,9 +23,9 @@
</rdf:RDF>
</metadata>
<defs
id="defs2612" />
id="defs1325" />
<path
style="stroke-width:1.05081;fill:#aeaeae;fill-opacity:1"
id="path2606"
d="M 16.203226,2 H 7.796774 C 6.05874,2 4.6443545,3.4143855 4.6443545,5.1524195 V 19.86371 c 0,0.540115 0.1092839,0.994063 0.3236484,1.350287 0.5926549,0.982504 1.9072138,1.059213 2.9559187,0.0084 L 11.25708,17.889239 c 0.394052,-0.393002 1.091787,-0.393002 1.485841,0 l 3.333158,3.333158 C 16.592024,21.738349 17.128987,22 17.673304,22 c 0.837492,0 1.682342,-0.660957 1.682342,-2.13629 V 5.1524195 C 19.355646,3.4143855 17.941259,2 16.203226,2 Z M 7.796774,4.101613 h 8.406452 c 0.578994,0 1.050806,0.4718121 1.050806,1.0508065 V 15.560658 l -2.575527,-2.361162 c -1.477434,-1.35449 -3.880628,-1.353439 -5.3580615,0 l -2.574476,2.361162 V 5.1524195 c 0,-0.5789944 0.4718121,-1.0508065 1.0508065,-1.0508065 z m 6.431987,12.301792 C 13.635055,15.809699 12.843798,15.482898 12,15.482898 c -0.843797,0 -1.635054,0.327852 -2.2287605,0.920507 l -3.025272,3.025272 v -2.442075 l 3.2848215,-3.011611 c 1.085483,-0.995114 2.851889,-0.995114 3.937372,0 l 3.285871,3.011611 v 2.442075 z" />
style="stroke-width:1.25;fill:#aeaeae;fill-opacity:1"
id="path1319"
d="M 12,2 C 6.48625,2 2,6.48625 2,12 c 0,5.51375 4.48625,10 10,10 2.02,0 3.965,-0.59875 5.62375,-1.73 0.57,-0.39 0.7175,-1.1675 0.32875,-1.7375 -0.38875,-0.57125 -1.165,-0.715 -1.7375,-0.32875 C 14.9725,19.0525 13.515,19.5 12,19.5 7.86375,19.5 4.5,16.13625 4.5,12 4.5,7.86375 7.86375,4.5 12,4.5 c 4.13625,0 7.5,3.36375 7.5,7.5 v 0.625 c 0,0.69 -0.56,1.25 -1.25,1.25 -0.69,0 -1.25,-0.56 -1.25,-1.25 v -3.75 c 0,-0.69125 -0.55875,-1.25 -1.25,-1.25 -0.55125,0 -1.00625,0.3625 -1.1725,0.86 C 13.8525,7.95125 12.96625,7.625 12,7.625 9.5875,7.625 7.625,9.5875 7.625,12 c 0,2.4125 1.9625,4.375 4.375,4.375 1.30625,0 2.46875,-0.5875 3.27,-1.49875 0.685,0.90375 1.76,1.49875 2.98,1.49875 2.0675,0 3.75,-1.6825 3.75,-3.75 V 12 C 22,6.48625 17.51375,2 12,2 Z m 0,11.875 c -1.03375,0 -1.875,-0.84125 -1.875,-1.875 0,-1.03375 0.84125,-1.875 1.875,-1.875 1.03375,0 1.875,0.84125 1.875,1.875 0,1.03375 -0.84125,1.875 -1.875,1.875 z" />
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

+9 -9
View File
@@ -5,13 +5,13 @@
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"
version="1.2"
width="24"
height="24"
id="svg1321"
viewBox="0 0 24 24"
id="svg2608">
height="24"
width="24"
version="1.2">
<metadata
id="metadata2614">
id="metadata1327">
<rdf:RDF>
<cc:Work
rdf:about="">
@@ -23,9 +23,9 @@
</rdf:RDF>
</metadata>
<defs
id="defs2612" />
id="defs1325" />
<path
d="M 16.203226,2 H 7.796774 C 6.05874,2 4.6443545,3.4143855 4.6443545,5.1524195 V 19.86371 c 0,0.540115 0.1092839,0.994063 0.3236484,1.350287 0.5926549,0.982504 1.9072138,1.059213 2.9559187,0.0084 L 11.25708,17.889239 c 0.394052,-0.393002 1.091787,-0.393002 1.485841,0 l 3.333158,3.333158 C 16.592024,21.738349 17.128987,22 17.673304,22 c 0.837492,0 1.682342,-0.660957 1.682342,-2.13629 V 5.1524195 C 19.355646,3.4143855 17.941259,2 16.203226,2 Z M 7.796774,4.101613 h 8.406452 c 0.578994,0 1.050806,0.4718121 1.050806,1.0508065 V 15.560658 l -2.575527,-2.361162 c -1.477434,-1.35449 -3.880628,-1.353439 -5.3580615,0 l -2.574476,2.361162 V 5.1524195 c 0,-0.5789944 0.4718121,-1.0508065 1.0508065,-1.0508065 z m 6.431987,12.301792 C 13.635055,15.809699 12.843798,15.482898 12,15.482898 c -0.843797,0 -1.635054,0.327852 -2.2287605,0.920507 l -3.025272,3.025272 v -2.442075 l 3.2848215,-3.011611 c 1.085483,-0.995114 2.851889,-0.995114 3.937372,0 l 3.285871,3.011611 v 2.442075 z"
id="path2606"
style="stroke-width:1.05081;fill:#000000;fill-opacity:0.78039217" />
style="stroke-width:1.25;fill:#000000;fill-opacity:0.78039217"
id="path1319"
d="M 12,2 C 6.48625,2 2,6.48625 2,12 c 0,5.51375 4.48625,10 10,10 2.02,0 3.965,-0.59875 5.62375,-1.73 0.57,-0.39 0.7175,-1.1675 0.32875,-1.7375 -0.38875,-0.57125 -1.165,-0.715 -1.7375,-0.32875 C 14.9725,19.0525 13.515,19.5 12,19.5 7.86375,19.5 4.5,16.13625 4.5,12 4.5,7.86375 7.86375,4.5 12,4.5 c 4.13625,0 7.5,3.36375 7.5,7.5 v 0.625 c 0,0.69 -0.56,1.25 -1.25,1.25 -0.69,0 -1.25,-0.56 -1.25,-1.25 v -3.75 c 0,-0.69125 -0.55875,-1.25 -1.25,-1.25 -0.55125,0 -1.00625,0.3625 -1.1725,0.86 C 13.8525,7.95125 12.96625,7.625 12,7.625 9.5875,7.625 7.625,9.5875 7.625,12 c 0,2.4125 1.9625,4.375 4.375,4.375 1.30625,0 2.46875,-0.5875 3.27,-1.49875 0.685,0.90375 1.76,1.49875 2.98,1.49875 2.0675,0 3.75,-1.6825 3.75,-3.75 V 12 C 22,6.48625 17.51375,2 12,2 Z m 0,11.875 c -1.03375,0 -1.875,-0.84125 -1.875,-1.875 0,-1.03375 0.84125,-1.875 1.875,-1.875 1.03375,0 1.875,0.84125 1.875,1.875 0,1.03375 -0.84125,1.875 -1.875,1.875 z" />
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 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="svg1321"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata1327">
<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="defs1325" />
<path
style="stroke-width:1.25;fill:#6699cc;fill-opacity:1"
id="path1319"
d="M 12,2 C 6.48625,2 2,6.48625 2,12 c 0,5.51375 4.48625,10 10,10 2.02,0 3.965,-0.59875 5.62375,-1.73 0.57,-0.39 0.7175,-1.1675 0.32875,-1.7375 -0.38875,-0.57125 -1.165,-0.715 -1.7375,-0.32875 C 14.9725,19.0525 13.515,19.5 12,19.5 7.86375,19.5 4.5,16.13625 4.5,12 4.5,7.86375 7.86375,4.5 12,4.5 c 4.13625,0 7.5,3.36375 7.5,7.5 v 0.625 c 0,0.69 -0.56,1.25 -1.25,1.25 -0.69,0 -1.25,-0.56 -1.25,-1.25 v -3.75 c 0,-0.69125 -0.55875,-1.25 -1.25,-1.25 -0.55125,0 -1.00625,0.3625 -1.1725,0.86 C 13.8525,7.95125 12.96625,7.625 12,7.625 9.5875,7.625 7.625,9.5875 7.625,12 c 0,2.4125 1.9625,4.375 4.375,4.375 1.30625,0 2.46875,-0.5875 3.27,-1.49875 0.685,0.90375 1.76,1.49875 2.98,1.49875 2.0675,0 3.75,-1.6825 3.75,-3.75 V 12 C 22,6.48625 17.51375,2 12,2 Z m 0,11.875 c -1.03375,0 -1.875,-0.84125 -1.875,-1.875 0,-1.03375 0.84125,-1.875 1.875,-1.875 1.03375,0 1.875,0.84125 1.875,1.875 0,1.03375 -0.84125,1.875 -1.875,1.875 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -49,6 +49,6 @@ edit = pencil.svg
check = tick.svg
cross = times.svg
hash = hash.svg
reference = bookmark.svg
reference = at.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="svg1321"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata1327">
<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="defs1325" />
<path
style="stroke-width:1.25;fill:#4271ae;fill-opacity:1"
id="path1319"
d="M 12,2 C 6.48625,2 2,6.48625 2,12 c 0,5.51375 4.48625,10 10,10 2.02,0 3.965,-0.59875 5.62375,-1.73 0.57,-0.39 0.7175,-1.1675 0.32875,-1.7375 -0.38875,-0.57125 -1.165,-0.715 -1.7375,-0.32875 C 14.9725,19.0525 13.515,19.5 12,19.5 7.86375,19.5 4.5,16.13625 4.5,12 4.5,7.86375 7.86375,4.5 12,4.5 c 4.13625,0 7.5,3.36375 7.5,7.5 v 0.625 c 0,0.69 -0.56,1.25 -1.25,1.25 -0.69,0 -1.25,-0.56 -1.25,-1.25 v -3.75 c 0,-0.69125 -0.55875,-1.25 -1.25,-1.25 -0.55125,0 -1.00625,0.3625 -1.1725,0.86 C 13.8525,7.95125 12.96625,7.625 12,7.625 9.5875,7.625 7.625,9.5875 7.625,12 c 0,2.4125 1.9625,4.375 4.375,4.375 1.30625,0 2.46875,-0.5875 3.27,-1.49875 0.685,0.90375 1.76,1.49875 2.98,1.49875 2.0675,0 3.75,-1.6825 3.75,-3.75 V 12 C 22,6.48625 17.51375,2 12,2 Z m 0,11.875 c -1.03375,0 -1.875,-0.84125 -1.875,-1.875 0,-1.03375 0.84125,-1.875 1.875,-1.875 1.03375,0 1.875,0.84125 1.875,1.875 0,1.03375 -0.84125,1.875 -1.875,1.875 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -49,6 +49,6 @@ edit = pencil.svg
check = tick.svg
cross = times.svg
hash = hash.svg
reference = bookmark.svg
reference = at.svg
sticky-on = pin.svg
sticky-off = pin-outline.svg
+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="svg1321"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata1327">
<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="defs1325" />
<path
style="stroke-width:1.25;fill:#aeaeae;fill-opacity:1"
id="path1319"
d="M 12,2 C 6.48625,2 2,6.48625 2,12 c 0,5.51375 4.48625,10 10,10 2.02,0 3.965,-0.59875 5.62375,-1.73 0.57,-0.39 0.7175,-1.1675 0.32875,-1.7375 -0.38875,-0.57125 -1.165,-0.715 -1.7375,-0.32875 C 14.9725,19.0525 13.515,19.5 12,19.5 7.86375,19.5 4.5,16.13625 4.5,12 4.5,7.86375 7.86375,4.5 12,4.5 c 4.13625,0 7.5,3.36375 7.5,7.5 v 0.625 c 0,0.69 -0.56,1.25 -1.25,1.25 -0.69,0 -1.25,-0.56 -1.25,-1.25 v -3.75 c 0,-0.69125 -0.55875,-1.25 -1.25,-1.25 -0.55125,0 -1.00625,0.3625 -1.1725,0.86 C 13.8525,7.95125 12.96625,7.625 12,7.625 9.5875,7.625 7.625,9.5875 7.625,12 c 0,2.4125 1.9625,4.375 4.375,4.375 1.30625,0 2.46875,-0.5875 3.27,-1.49875 0.685,0.90375 1.76,1.49875 2.98,1.49875 2.0675,0 3.75,-1.6825 3.75,-3.75 V 12 C 22,6.48625 17.51375,2 12,2 Z m 0,11.875 c -1.03375,0 -1.875,-0.84125 -1.875,-1.875 0,-1.03375 0.84125,-1.875 1.875,-1.875 1.03375,0 1.875,0.84125 1.875,1.875 0,1.03375 -0.84125,1.875 -1.875,1.875 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -49,6 +49,6 @@ edit = pencil.svg
check = tick.svg
cross = times.svg
hash = hash.svg
reference = bookmark.svg
reference = at.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="svg1321"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata1327">
<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="defs1325" />
<path
style="stroke-width:1.25;fill:#000000;fill-opacity:0.78039217"
id="path1319"
d="M 12,2 C 6.48625,2 2,6.48625 2,12 c 0,5.51375 4.48625,10 10,10 2.02,0 3.965,-0.59875 5.62375,-1.73 0.57,-0.39 0.7175,-1.1675 0.32875,-1.7375 -0.38875,-0.57125 -1.165,-0.715 -1.7375,-0.32875 C 14.9725,19.0525 13.515,19.5 12,19.5 7.86375,19.5 4.5,16.13625 4.5,12 4.5,7.86375 7.86375,4.5 12,4.5 c 4.13625,0 7.5,3.36375 7.5,7.5 v 0.625 c 0,0.69 -0.56,1.25 -1.25,1.25 -0.69,0 -1.25,-0.56 -1.25,-1.25 v -3.75 c 0,-0.69125 -0.55875,-1.25 -1.25,-1.25 -0.55125,0 -1.00625,0.3625 -1.1725,0.86 C 13.8525,7.95125 12.96625,7.625 12,7.625 9.5875,7.625 7.625,9.5875 7.625,12 c 0,2.4125 1.9625,4.375 4.375,4.375 1.30625,0 2.46875,-0.5875 3.27,-1.49875 0.685,0.90375 1.76,1.49875 2.98,1.49875 2.0675,0 3.75,-1.6825 3.75,-3.75 V 12 C 22,6.48625 17.51375,2 12,2 Z m 0,11.875 c -1.03375,0 -1.875,-0.84125 -1.875,-1.875 0,-1.03375 0.84125,-1.875 1.875,-1.875 1.03375,0 1.875,0.84125 1.875,1.875 0,1.03375 -0.84125,1.875 -1.875,1.875 z" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -49,6 +49,6 @@ edit = pencil.svg
check = tick.svg
cross = times.svg
hash = hash.svg
reference = bookmark.svg
reference = at.svg
sticky-on = pin.svg
sticky-off = pin-outline.svg
+3
View File
@@ -222,6 +222,7 @@ class Config:
"""Initialise the config class. The manual setting of confPath
and dataPath is mainly intended for the test suite.
"""
logger.debug("Initialising Config ...")
if confPath is None:
confRoot = QStandardPaths.writableLocation(QStandardPaths.ConfigLocation)
self.confPath = path.join(path.abspath(confRoot), self.appHandle)
@@ -304,6 +305,8 @@ class Config:
if self.spellLanguage is None:
self.spellLanguage = "en"
logger.debug("Config initialisation complete")
return True
def loadConfig(self):
+1
View File
@@ -1041,6 +1041,7 @@ class NWProject():
return
# Then check the files in the data folder
logger.debug("Checking files in project content folder")
orphanFiles = []
for fileItem in listdir(self.projContent):
if not fileItem.endswith(".nwd"):
+2 -2
View File
@@ -115,12 +115,12 @@ class NWSpellCheck():
if not path.isfile(projectDict):
return
try:
with open(projectDict,mode="r",encoding="utf-8") as wordsFile:
logger.debug("Loading project word list")
with open(projectDict, mode="r", encoding="utf-8") as wordsFile:
for theLine in wordsFile:
theLine = theLine.strip()
if len(theLine) > 0 and theLine not in self.PROJW:
self.PROJW.append(theLine)
logger.debug("Project word list")
logger.debug("Project word list contains %d words" % len(self.PROJW))
except Exception as e:
logger.error("Failed to load project word list")
+3 -4
View File
@@ -2,11 +2,11 @@
from nw.gui.about import GuiAbout
from nw.gui.build import GuiBuildNovel
from nw.gui.docbars import GuiDocTitleBar, GuiSearchBar, GuiDocViewDetails
from nw.gui.docbars import GuiSearchBar
from nw.gui.doceditor import GuiDocEditor
from nw.gui.docmerge import GuiDocMerge
from nw.gui.docsplit import GuiDocSplit
from nw.gui.docviewer import GuiDocViewer
from nw.gui.docviewer import GuiDocViewer, GuiDocViewDetails
from nw.gui.itemdetails import GuiItemDetails
from nw.gui.itemeditor import GuiItemEditor
from nw.gui.mainmenu import GuiMainMenu
@@ -23,13 +23,12 @@ from nw.gui.theme import GuiIcons, GuiTheme
__all__ = [
"GuiAbout",
"GuiBuildNovel",
"GuiDocTitleBar",
"GuiSearchBar",
"GuiDocViewDetails",
"GuiDocEditor",
"GuiDocMerge",
"GuiDocSplit",
"GuiDocViewer",
"GuiDocViewDetails",
"GuiItemDetails",
"GuiItemEditor",
"GuiMainMenu",
+1 -1
View File
@@ -45,7 +45,7 @@ from nw.constants import nwUnicode
logger = logging.getLogger(__name__)
# =============================================================================================== #
# Config FOrm Layout
# Config Form Layout
# =============================================================================================== #
class QConfigLayout(QGridLayout):
-382
View File
@@ -7,9 +7,6 @@
File History:
Created: 2019-09-29 [0.2.1] GuiSearchBar
Created: 2019-10-31 [0.3.2] GuiDocViewDetails
Created: 2020-04-25 [0.4.5] GuiDocTitleBar
Created: 2020-06-09 [0.8.0] GuiDocViewFooter
This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen
@@ -169,382 +166,3 @@ class GuiSearchBar(QWidget):
return True
# END Class GuiSearchBar
class GuiDocTitleBar(QWidget):
def __init__(self, theParent, isEditor):
QWidget.__init__(self, theParent)
logger.debug("Initialising GuiDocTitleBar ...")
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theProject = theParent.theProject
self.theTheme = theParent.theTheme
self.theHandle = None
self.isEditor = isEditor
# Make a QPalette that matches the Syntax Theme
self.thePalette = QPalette()
self.thePalette.setColor(QPalette.Window, QColor(*self.theTheme.colBack))
self.thePalette.setColor(QPalette.Text, QColor(*self.theTheme.colText))
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)
# Title Label
self.theTitle = QLabel()
self.theTitle.setText("")
self.theTitle.setIndent(0)
self.theTitle.setMargin(0)
self.theTitle.setContentsMargins(0, 0, 0, 0)
self.theTitle.setAutoFillBackground(True)
self.theTitle.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
self.theTitle.setFixedHeight(fPx)
self.theTitle.setFrameShape(QFrame.NoFrame)
self.theTitle.setLineWidth(0)
self.theTitle.setPalette(self.thePalette)
lblFont = self.theTitle.font()
lblFont.setPointSizeF(0.9*self.theTheme.fontPointSize)
self.theTitle.setFont(lblFont)
buttonStyle = (
"QToolButton {{border: none; background: transparent;}} "
"QToolButton:hover {{border: none; background: rgba({0},{1},{2},0.2);}}"
).format(*self.theTheme.colText)
# Buttons
self.closeButton = QToolButton(self)
self.closeButton.setIcon(self.theTheme.getIcon("close"))
self.closeButton.setContentsMargins(0, 0, 0, 0)
self.closeButton.setIconSize(QSize(fPx, fPx))
self.closeButton.setFixedSize(fPx, fPx)
self.closeButton.setStyleSheet(buttonStyle)
self.closeButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.closeButton.setVisible(False)
self.closeButton.clicked.connect(self._closeDocument)
if self.isEditor:
self.minmaxButton = QToolButton(self)
self.minmaxButton.setIcon(self.theTheme.getIcon("maximise"))
self.minmaxButton.setContentsMargins(0, 0, 0, 0)
self.minmaxButton.setIconSize(QSize(fPx, fPx))
self.minmaxButton.setFixedSize(fPx, fPx)
self.minmaxButton.setStyleSheet(buttonStyle)
self.minmaxButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.minmaxButton.setVisible(False)
self.minmaxButton.clicked.connect(self._minmaxDocument)
else:
self.refreshButton = QToolButton(self)
self.refreshButton.setIcon(self.theTheme.getIcon("refresh"))
self.refreshButton.setContentsMargins(0, 0, 0, 0)
self.refreshButton.setIconSize(QSize(fPx, fPx))
self.refreshButton.setFixedSize(fPx, fPx)
self.refreshButton.setStyleSheet(buttonStyle)
self.refreshButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.refreshButton.setVisible(False)
self.refreshButton.clicked.connect(self._refreshDocument)
# Assemble Layout
self.outerBox = QHBoxLayout()
self.outerBox.setSpacing(hSp)
self.outerBox.addWidget(self.theTitle, 1)
if self.isEditor:
self.outerBox.addWidget(self.minmaxButton, 0)
else:
self.outerBox.addWidget(self.refreshButton, 0)
self.outerBox.addWidget(self.closeButton, 0)
self.setLayout(self.outerBox)
logger.debug("GuiDocTitleBar initialisation complete")
return
##
# Setters
##
def setTitleFromHandle(self, tHandle):
"""Sets the document title from the handle, or alternatively,
set the whole document path.
"""
self.theTitle.setText("")
self.theHandle = tHandle
if tHandle is None:
self.closeButton.setVisible(False)
if self.isEditor:
self.minmaxButton.setVisible(False)
else:
self.refreshButton.setVisible(False)
return False
if self.mainConf.showFullPath:
tTitle = []
tTree = self.theProject.projTree.getItemPath(tHandle)
for aHandle in reversed(tTree):
nwItem = self.theProject.projTree[aHandle]
if nwItem is not None:
tTitle.append(nwItem.itemName)
sSep = " %s " % nwUnicode.U_RSAQUO
self.theTitle.setText(sSep.join(tTitle))
else:
nwItem = self.theProject.projTree[tHandle]
if nwItem is None:
return False
self.theTitle.setText(nwItem.itemName)
self.closeButton.setVisible(True)
if self.isEditor:
self.minmaxButton.setVisible(True)
else:
self.refreshButton.setVisible(True)
return True
##
# Slots
##
def _closeDocument(self):
"""Trigger the close editor/viewer on the main window.
"""
if self.isEditor:
self.theParent.theParent.closeDocEditor()
else:
self.theParent.theParent.closeDocViewer()
return
def _minmaxDocument(self):
"""Switch on or off zen mode.
"""
self.theParent.theParent.toggleZenMode()
if self.theParent.theParent.isZenMode:
self.minmaxButton.setIcon(self.theTheme.getIcon("minimise"))
self.setContentsMargins(self.buttonSize, 0, 0, 0)
self.closeButton.setVisible(False)
else:
self.minmaxButton.setIcon(self.theTheme.getIcon("maximise"))
self.setContentsMargins(2*self.buttonSize, 0, 0, 0)
self.closeButton.setVisible(True)
return
def _refreshDocument(self):
"""Reload the content of the document.
"""
self.theParent.reloadText()
return
##
# Events
##
def mousePressEvent(self, theEvent):
"""Capture a click on the title and ensure that the item is
selected in the project tree.
"""
self.theParent.setSelectedHandle(self.theHandle)
return
# END Class GuiDocTitleBar
class GuiDocViewFooter(QWidget):
def __init__(self, theParent):
QWidget.__init__(self, theParent)
logger.debug("Initialising GuiDocViewFooter ...")
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theTheme = theParent.theTheme
self.optState = theParent.theProject.optState
self.viewMeta = theParent.theParent.viewMeta
self.theHandle = None
# Make a QPalette that matches the Syntax Theme
self.thePalette = QPalette()
self.thePalette.setColor(QPalette.Window, QColor(*self.theTheme.colBack))
self.thePalette.setColor(QPalette.Text, QColor(*self.theTheme.colText))
fPx = int(0.9*self.theTheme.fontPixelSize)
hSp = self.mainConf.pxInt(6)
# Main Widget Settings
self.setContentsMargins(0, 0, 0, 0)
self.setAutoFillBackground(True)
self.setPalette(self.thePalette)
buttonStyle = (
"QToolButton {{border: none; background: transparent;}} "
"QToolButton:hover {{border: none; background: rgba({0},{1},{2},0.2);}}"
).format(*self.theTheme.colText)
# Show/Hide Details
self.showHide = QToolButton(self)
self.showHide.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.showHide.setStyleSheet(buttonStyle)
self.showHide.setIcon(self.theTheme.getIcon("reference"))
self.showHide.setIconSize(QSize(fPx, fPx))
self.showHide.setFixedSize(QSize(fPx, fPx))
self.showHide.clicked.connect(self._doShowHide)
# Sticky Button
stickyOn = self.theTheme.getPixmap("sticky-on", (fPx, fPx))
stickyOff = self.theTheme.getPixmap("sticky-off", (fPx, fPx))
stickyIcon = QIcon()
stickyIcon.addPixmap(stickyOn, QIcon.Normal, QIcon.On)
stickyIcon.addPixmap(stickyOff, QIcon.Normal, QIcon.Off)
self.stickyRefs = QToolButton(self)
self.stickyRefs.setCheckable(True)
self.stickyRefs.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.stickyRefs.setStyleSheet(buttonStyle)
self.stickyRefs.setIcon(stickyIcon)
self.stickyRefs.setIconSize(QSize(fPx, fPx))
self.stickyRefs.setFixedSize(QSize(fPx, fPx))
self.stickyRefs.toggled.connect(self._doToggleSticky)
# Labels
self.lblRefs = QLabel("References")
self.lblRefs.setBuddy(self.showHide)
self.lblRefs.setIndent(0)
self.lblRefs.setMargin(0)
self.lblRefs.setContentsMargins(0, 0, 0, 0)
self.lblRefs.setAutoFillBackground(True)
self.lblRefs.setFixedHeight(fPx)
self.lblRefs.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.lblRefs.setPalette(self.thePalette)
self.lblSticky = QLabel("Sticky")
self.lblSticky.setBuddy(self.stickyRefs)
self.lblSticky.setIndent(0)
self.lblSticky.setMargin(0)
self.lblSticky.setContentsMargins(0, 0, 0, 0)
self.lblSticky.setAutoFillBackground(True)
self.lblSticky.setFixedHeight(fPx)
self.lblSticky.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.lblSticky.setPalette(self.thePalette)
lblFont = self.font()
lblFont.setPointSizeF(0.9*self.theTheme.fontPointSize)
self.lblRefs.setFont(lblFont)
self.lblSticky.setFont(lblFont)
# Assemble Layout
self.outerBox = QHBoxLayout()
self.outerBox.setSpacing(hSp)
self.outerBox.addWidget(self.showHide, 0)
self.outerBox.addWidget(self.lblRefs, 0)
self.outerBox.addWidget(self.stickyRefs, 0)
self.outerBox.addWidget(self.lblSticky, 0)
self.outerBox.addStretch(1)
self.setLayout(self.outerBox)
logger.debug("GuiDocViewFooter initialisation complete")
return
##
# Slots
##
def _doShowHide(self):
"""Toggle the expand/collapse of the panel.
"""
isVisible = self.viewMeta.isVisible()
self.viewMeta.setVisible(not isVisible)
return
def _doToggleSticky(self, theState):
"""Toggle the sticky flag for the reference panel.
"""
logger.verbose("Reference sticky is %s" % str(theState))
self.theParent.stickyRef = theState
if not theState and self.theParent.theHandle is not None:
self.viewMeta.refreshReferences(self.theParent.theHandle)
return
# END Class GuiDocViewFooter
class GuiDocViewDetails(QScrollArea):
def __init__(self, theParent):
QScrollArea.__init__(self, theParent)
logger.debug("Initialising DocViewDetails ...")
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theProject = theParent.theProject
self.theTheme = theParent.theTheme
self.currHandle = None
self.refList = QLabel("None")
self.refList.setWordWrap(True)
self.refList.setAlignment(Qt.AlignTop)
self.refList.setScaledContents(True)
self.refList.linkActivated.connect(self._linkClicked)
hCol = self.palette().highlight().color()
self.linkStyle = "style='color: rgb({0},{1},{2})'".format(
*self.theTheme.colLink
)
# Assemble
self.outerWidget = QWidget()
self.outerBox = QHBoxLayout()
self.outerBox.addWidget(self.refList, 1)
self.outerWidget.setLayout(self.outerBox)
self.setWidget(self.outerWidget)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setWidgetResizable(True)
self.setMinimumHeight(self.mainConf.pxInt(50))
logger.debug("DocViewDetails initialisation complete")
return
def refreshReferences(self, tHandle):
"""Update the current list of document references from the
project index.
"""
self.currHandle = tHandle
if self.theParent.docViewer.stickyRef:
return
theRefs = self.theParent.theIndex.getBackReferenceList(tHandle)
theList = []
for tHandle in theRefs:
tItem = self.theProject.projTree[tHandle]
if tItem is not None:
theList.append("<a href='#head_%s:%s' %s>%s</a>" % (
tHandle, theRefs[tHandle], self.linkStyle, tItem.itemName
))
self.refList.setText(", ".join(theList))
return
##
# Internal Functions
##
def _linkClicked(self, theLink):
"""Capture the link-click and forward it to the document viewer
class for handling.
"""
logger.verbose("Clicked link: '%s'" % theLink)
if len(theLink) == 27:
tHandle = theLink[6:19]
self.theParent.viewDocument(tHandle, theLink)
return
# END Class GuiDocViewDetails
+168 -17
View File
@@ -8,6 +8,7 @@
File History:
Created: 2018-09-29 [0.0.1] GuiDocEditor
Created: 2019-04-22 [0.0.1] WordCounter
Created: 2020-04-25 [0.4.5] GuiDocEditHeader
This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen
@@ -31,18 +32,18 @@ import nw
from time import time
from PyQt5.QtCore import Qt, QThread, QTimer, pyqtSlot
from PyQt5.QtWidgets import (
qApp, QTextEdit, QAction, QMenu, QShortcut, QMessageBox
)
from PyQt5.QtCore import Qt, QSize, QThread, QTimer, pyqtSlot
from PyQt5.QtGui import (
QTextCursor, QTextOption, QKeySequence, QFont, QColor, QPalette,
QTextDocument, QCursor
)
from PyQt5.QtWidgets import (
qApp, QTextEdit, QAction, QMenu, QShortcut, QMessageBox, QWidget, QLabel,
QToolButton, QHBoxLayout
)
from nw.core import NWDoc
from nw.gui.dochighlight import GuiDocHighlighter
from nw.gui.docbars import GuiDocTitleBar
from nw.core import NWSpellSimple, countWords
from nw.constants import nwUnicode, nwDocAction
@@ -85,9 +86,7 @@ class GuiDocEditor(QTextEdit):
self.qDocument.contentsChange.connect(self._docChange)
# Document Title
self.docTitle = GuiDocTitleBar(self, isEditor=True)
self.docTitle.setGeometry(0, 0, self.docTitle.width(), self.docTitle.height())
self.setViewportMargins(0, self.docTitle.height(), 0, 0)
self.docHeader = GuiDocEditHeader(self)
# Syntax
self.hLight = GuiDocHighlighter(self.qDocument, self.theParent)
@@ -134,9 +133,6 @@ class GuiDocEditor(QTextEdit):
logger.debug("GuiDocEditor initialisation complete")
# Connect Functions
self.setSelectedHandle = self.theParent.treeView.setSelectedHandle
return
def clearEditor(self):
@@ -158,7 +154,7 @@ class GuiDocEditor(QTextEdit):
self.hasSelection = False
self.setDocumentChanged(False)
self.docTitle.setTitleFromHandle(self.theHandle)
self.docHeader.setTitleFromHandle(self.theHandle)
return True
@@ -270,7 +266,7 @@ class GuiDocEditor(QTextEdit):
self.theHandle = tHandle
self.setReadOnly(False)
self.docTitle.setTitleFromHandle(self.theHandle)
self.docHeader.setTitleFromHandle(self.theHandle)
self.updateDocMargins()
self.hLight.spellCheck = spTemp
qApp.restoreOverrideCursor()
@@ -333,11 +329,11 @@ class GuiDocEditor(QTextEdit):
else:
tM = cM
tB = self.lineWidth()
tB = self.frameWidth()
tW = self.width() - 2*tB - sW
tH = self.docTitle.height()
tH = self.docHeader.height()
tT = cM - tH
self.docTitle.setGeometry(tB, tB, tW, tH)
self.docHeader.setGeometry(tB, tB, tW, tH)
self.setViewportMargins(0, tH, 0, 0)
docFormat = self.qDocument.rootFrame().frameFormat()
@@ -368,7 +364,7 @@ class GuiDocEditor(QTextEdit):
title bar needs updating,
"""
if tHandle == self.theHandle:
self.docTitle.setTitleFromHandle(self.theHandle)
self.docHeader.setTitleFromHandle(self.theHandle)
self.updateDocMargins()
return
@@ -1105,3 +1101,158 @@ class WordCounter(QThread):
return
## END Class WordCounter
class GuiDocEditHeader(QWidget):
def __init__(self, docEditor):
QWidget.__init__(self, docEditor)
logger.debug("Initialising GuiDocEditHeader ...")
self.mainConf = nw.CONFIG
self.docEditor = docEditor
self.theParent = docEditor.theParent
self.theProject = docEditor.theProject
self.theTheme = docEditor.theTheme
self.theHandle = None
# Make a QPalette that matches the Syntax Theme
self.thePalette = QPalette()
self.thePalette.setColor(QPalette.Window, QColor(*self.theTheme.colBack))
self.thePalette.setColor(QPalette.Text, QColor(*self.theTheme.colText))
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)
# Title Label
self.theTitle = QLabel()
self.theTitle.setText("")
self.theTitle.setIndent(0)
self.theTitle.setMargin(0)
self.theTitle.setContentsMargins(0, 0, 0, 0)
self.theTitle.setAutoFillBackground(True)
self.theTitle.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
self.theTitle.setFixedHeight(fPx)
self.theTitle.setPalette(self.thePalette)
lblFont = self.theTitle.font()
lblFont.setPointSizeF(0.9*self.theTheme.fontPointSize)
self.theTitle.setFont(lblFont)
buttonStyle = (
"QToolButton {{border: none; background: transparent;}} "
"QToolButton:hover {{border: none; background: rgba({0},{1},{2},0.2);}}"
).format(*self.theTheme.colText)
# Buttons
self.minmaxButton = QToolButton(self)
self.minmaxButton.setIcon(self.theTheme.getIcon("maximise"))
self.minmaxButton.setContentsMargins(0, 0, 0, 0)
self.minmaxButton.setIconSize(QSize(fPx, fPx))
self.minmaxButton.setFixedSize(fPx, fPx)
self.minmaxButton.setStyleSheet(buttonStyle)
self.minmaxButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.minmaxButton.setVisible(False)
self.minmaxButton.clicked.connect(self._minmaxDocument)
self.closeButton = QToolButton(self)
self.closeButton.setIcon(self.theTheme.getIcon("close"))
self.closeButton.setContentsMargins(0, 0, 0, 0)
self.closeButton.setIconSize(QSize(fPx, fPx))
self.closeButton.setFixedSize(fPx, fPx)
self.closeButton.setStyleSheet(buttonStyle)
self.closeButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.closeButton.setVisible(False)
self.closeButton.clicked.connect(self._closeDocument)
# Assemble Layout
self.outerBox = QHBoxLayout()
self.outerBox.setSpacing(hSp)
self.outerBox.addWidget(self.theTitle, 1)
self.outerBox.addWidget(self.minmaxButton, 0)
self.outerBox.addWidget(self.closeButton, 0)
self.setLayout(self.outerBox)
logger.debug("GuiDocEditHeader initialisation complete")
return
##
# Setters
##
def setTitleFromHandle(self, tHandle):
"""Sets the document title from the handle, or alternatively,
set the whole document path.
"""
self.theHandle = tHandle
if tHandle is None:
self.theTitle.setText("")
self.closeButton.setVisible(False)
self.minmaxButton.setVisible(False)
return True
if self.mainConf.showFullPath:
tTitle = []
tTree = self.theProject.projTree.getItemPath(tHandle)
for aHandle in reversed(tTree):
nwItem = self.theProject.projTree[aHandle]
if nwItem is not None:
tTitle.append(nwItem.itemName)
sSep = " %s " % nwUnicode.U_RSAQUO
self.theTitle.setText(sSep.join(tTitle))
else:
nwItem = self.theProject.projTree[tHandle]
if nwItem is None:
return False
self.theTitle.setText(nwItem.itemName)
self.closeButton.setVisible(True)
self.minmaxButton.setVisible(True)
return True
##
# Slots
##
def _closeDocument(self):
"""Trigger the close editor/viewer on the main window.
"""
self.theParent.closeDocEditor()
self.closeButton.setVisible(False)
self.minmaxButton.setVisible(False)
return
def _minmaxDocument(self):
"""Switch on or off zen mode.
"""
self.theParent.toggleZenMode()
if self.theParent.isZenMode:
self.minmaxButton.setIcon(self.theTheme.getIcon("minimise"))
self.setContentsMargins(self.buttonSize, 0, 0, 0)
self.closeButton.setVisible(False)
else:
self.minmaxButton.setIcon(self.theTheme.getIcon("maximise"))
self.setContentsMargins(2*self.buttonSize, 0, 0, 0)
self.closeButton.setVisible(True)
return
##
# Events
##
def mousePressEvent(self, theEvent):
"""Capture a click on the title and ensure that the item is
selected in the project tree.
"""
self.theParent.treeView.setSelectedHandle(self.theHandle)
return
# END Class GuiDocEditHeader
+2 -2
View File
@@ -42,7 +42,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
def __init__(self, theDoc, theParent):
QSyntaxHighlighter.__init__(self, theDoc)
logger.debug("Initialising DocHighlighter ...")
logger.debug("Initialising GuiDocHighlighter ...")
self.mainConf = nw.CONFIG
self.theDoc = theDoc
self.theParent = theParent
@@ -70,7 +70,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
self.initHighlighter()
logger.debug("DocHighlighter initialisation complete")
logger.debug("GuiDocHighlighter initialisation complete")
return
+381 -18
View File
@@ -6,7 +6,10 @@
Class holding the document html viewer
File History:
Created: 2019-05-10 [0.0.1]
Created: 2019-05-10 [0.0.1] GuiDocViewer
Created: 2019-10-31 [0.3.2] GuiDocViewDetails
Created: 2020-04-25 [0.4.5] GuiDocViewHeader
Created: 2020-06-09 [0.8.0] GuiDocViewFooter
This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen
@@ -28,13 +31,16 @@
import logging
import nw
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtWidgets import QTextBrowser
from PyQt5.QtGui import QTextOption, QFont, QPalette, QColor, QTextCursor
from PyQt5.QtCore import Qt, QUrl, QSize
from PyQt5.QtGui import (
QTextOption, QFont, QPalette, QColor, QTextCursor, QIcon
)
from PyQt5.QtWidgets import (
QTextBrowser, QWidget, QScrollArea, QLabel, QHBoxLayout, QToolButton
)
from nw.core import ToHtml
from nw.constants import nwAlert, nwItemType, nwDocAction
from nw.gui.docbars import GuiDocTitleBar, GuiDocViewFooter
from nw.constants import nwAlert, nwItemType, nwDocAction, nwUnicode
logger = logging.getLogger(__name__)
@@ -57,8 +63,8 @@ class GuiDocViewer(QTextBrowser):
self.setOpenExternalLinks(False)
self.initViewer()
# Document Title and Footer
self.docTitle = GuiDocTitleBar(self, isEditor=False)
# Document Header and Footer
self.docHeader = GuiDocViewHeader(self)
self.docFooter = GuiDocViewFooter(self)
self.stickyRef = False
@@ -72,9 +78,6 @@ class GuiDocViewer(QTextBrowser):
logger.debug("GuiDocViewer initialisation complete")
# Connect Functions
self.setSelectedHandle = self.theParent.treeView.setSelectedHandle
return
def clearViewer(self):
@@ -83,7 +86,7 @@ class GuiDocViewer(QTextBrowser):
self.clear()
self.setSearchPaths([""])
self.theHandle = None
self.docTitle.setTitleFromHandle(self.theHandle)
self.docHeader.setTitleFromHandle(self.theHandle)
return True
def initViewer(self):
@@ -156,7 +159,7 @@ class GuiDocViewer(QTextBrowser):
self.verticalScrollBar().setValue(sPos)
self.theHandle = tHandle
self.theProject.setLastViewed(tHandle)
self.docTitle.setTitleFromHandle(self.theHandle)
self.docHeader.setTitleFromHandle(self.theHandle)
self.updateDocMargins()
# Make sure the main GUI knows we changed the content
@@ -185,7 +188,10 @@ class GuiDocViewer(QTextBrowser):
) % theTag, nwAlert.ERROR)
return
else:
self.loadText(tHandle)
# 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))
return True
@@ -230,14 +236,14 @@ class GuiDocViewer(QTextBrowser):
else:
sW = 0
tB = self.lineWidth()
tB = self.frameWidth()
tW = self.width() - 2*tB - sW
tH = self.docTitle.height()
tH = self.docHeader.height()
fH = self.docFooter.height()
fY = self.height() - fH - tB
tT = self.mainConf.getTextMargin() - tH
bT = self.mainConf.getTextMargin() - fH
self.docTitle.setGeometry(tB, tB, tW, tH)
self.docHeader.setGeometry(tB, tB, tW, tH)
self.docFooter.setGeometry(tB, fY, tW, fH)
self.setViewportMargins(0, tH, 0, fH)
@@ -256,7 +262,7 @@ class GuiDocViewer(QTextBrowser):
title bar needs updating,
"""
if tHandle == self.theHandle:
self.docTitle.setTitleFromHandle(self.theHandle)
self.docHeader.setTitleFromHandle(self.theHandle)
self.updateDocMargins()
return
@@ -387,3 +393,360 @@ class GuiDocViewer(QTextBrowser):
return True
# END Class GuiDocViewer
# =============================================================================================== #
# The Embedded Document Header
# Only used by DocViewer, and is at a fixed position in the QTextBrowser's viewport
# =============================================================================================== #
class GuiDocViewHeader(QWidget):
def __init__(self, docViewer):
QWidget.__init__(self, docViewer)
logger.debug("Initialising GuiDocViewHeader ...")
self.mainConf = nw.CONFIG
self.docViewer = docViewer
self.theParent = docViewer.theParent
self.theProject = docViewer.theProject
self.theTheme = docViewer.theTheme
self.theHandle = None
# Make a QPalette that matches the Syntax Theme
self.thePalette = QPalette()
self.thePalette.setColor(QPalette.Window, QColor(*self.theTheme.colBack))
self.thePalette.setColor(QPalette.Text, QColor(*self.theTheme.colText))
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)
# Title Label
self.theTitle = QLabel()
self.theTitle.setText("")
self.theTitle.setIndent(0)
self.theTitle.setMargin(0)
self.theTitle.setContentsMargins(0, 0, 0, 0)
self.theTitle.setAutoFillBackground(True)
self.theTitle.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
self.theTitle.setFixedHeight(fPx)
self.theTitle.setPalette(self.thePalette)
lblFont = self.theTitle.font()
lblFont.setPointSizeF(0.9*self.theTheme.fontPointSize)
self.theTitle.setFont(lblFont)
buttonStyle = (
"QToolButton {{border: none; background: transparent;}} "
"QToolButton:hover {{border: none; background: rgba({0},{1},{2},0.2);}}"
).format(*self.theTheme.colText)
# Buttons
self.closeButton = QToolButton(self)
self.closeButton.setIcon(self.theTheme.getIcon("close"))
self.closeButton.setContentsMargins(0, 0, 0, 0)
self.closeButton.setIconSize(QSize(fPx, fPx))
self.closeButton.setFixedSize(fPx, fPx)
self.closeButton.setStyleSheet(buttonStyle)
self.closeButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.closeButton.setVisible(False)
self.closeButton.clicked.connect(self._closeDocument)
self.refreshButton = QToolButton(self)
self.refreshButton.setIcon(self.theTheme.getIcon("refresh"))
self.refreshButton.setContentsMargins(0, 0, 0, 0)
self.refreshButton.setIconSize(QSize(fPx, fPx))
self.refreshButton.setFixedSize(fPx, fPx)
self.refreshButton.setStyleSheet(buttonStyle)
self.refreshButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.refreshButton.setVisible(False)
self.refreshButton.clicked.connect(self._refreshDocument)
# Assemble Layout
self.outerBox = QHBoxLayout()
self.outerBox.setSpacing(hSp)
self.outerBox.addWidget(self.theTitle, 1)
self.outerBox.addWidget(self.refreshButton, 0)
self.outerBox.addWidget(self.closeButton, 0)
self.setLayout(self.outerBox)
logger.debug("GuiDocViewHeader initialisation complete")
return
##
# Setters
##
def setTitleFromHandle(self, tHandle):
"""Sets the document title from the handle, or alternatively,
set the whole document path.
"""
self.theHandle = tHandle
if tHandle is None:
self.theTitle.setText("")
self.closeButton.setVisible(False)
self.refreshButton.setVisible(False)
return True
if self.mainConf.showFullPath:
tTitle = []
tTree = self.theProject.projTree.getItemPath(tHandle)
for aHandle in reversed(tTree):
nwItem = self.theProject.projTree[aHandle]
if nwItem is not None:
tTitle.append(nwItem.itemName)
sSep = " %s " % nwUnicode.U_RSAQUO
self.theTitle.setText(sSep.join(tTitle))
else:
nwItem = self.theProject.projTree[tHandle]
if nwItem is None:
return False
self.theTitle.setText(nwItem.itemName)
self.closeButton.setVisible(True)
self.refreshButton.setVisible(True)
return True
##
# Slots
##
def _closeDocument(self):
"""Trigger the close editor/viewer on the main window.
"""
self.theParent.closeDocViewer()
return
def _refreshDocument(self):
"""Reload the content of the document.
"""
self.docViewer.reloadText()
return
##
# Events
##
def mousePressEvent(self, theEvent):
"""Capture a click on the title and ensure that the item is
selected in the project tree.
"""
self.theParent.treeView.setSelectedHandle(self.theHandle)
return
# END Class GuiDocViewHeader
# =============================================================================================== #
# The Embedded Document Footer
# Only used by DocViewer, and is at a fixed position in the QTextBrowser's viewport
# =============================================================================================== #
class GuiDocViewFooter(QWidget):
def __init__(self, theParent):
QWidget.__init__(self, theParent)
logger.debug("Initialising GuiDocViewFooter ...")
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theTheme = theParent.theTheme
self.optState = theParent.theProject.optState
self.viewMeta = theParent.theParent.viewMeta
self.theHandle = None
# Make a QPalette that matches the Syntax Theme
self.thePalette = QPalette()
self.thePalette.setColor(QPalette.Window, QColor(*self.theTheme.colBack))
self.thePalette.setColor(QPalette.Text, QColor(*self.theTheme.colText))
fPx = int(0.9*self.theTheme.fontPixelSize)
bSp = self.mainConf.pxInt(2)
hSp = self.mainConf.pxInt(8)
# Main Widget Settings
self.setContentsMargins(0, 0, 0, 0)
self.setAutoFillBackground(True)
self.setPalette(self.thePalette)
buttonStyle = (
"QToolButton {{border: none; background: transparent;}} "
"QToolButton:hover {{border: none; background: rgba({0},{1},{2},0.2);}}"
).format(*self.theTheme.colText)
# Show/Hide Details
self.showHide = QToolButton(self)
self.showHide.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.showHide.setStyleSheet(buttonStyle)
self.showHide.setIcon(self.theTheme.getIcon("reference"))
self.showHide.setIconSize(QSize(fPx, fPx))
self.showHide.setFixedSize(QSize(fPx, fPx))
self.showHide.clicked.connect(self._doShowHide)
# Sticky Button
stickyOn = self.theTheme.getPixmap("sticky-on", (fPx, fPx))
stickyOff = self.theTheme.getPixmap("sticky-off", (fPx, fPx))
stickyIcon = QIcon()
stickyIcon.addPixmap(stickyOn, QIcon.Normal, QIcon.On)
stickyIcon.addPixmap(stickyOff, QIcon.Normal, QIcon.Off)
self.stickyRefs = QToolButton(self)
self.stickyRefs.setCheckable(True)
self.stickyRefs.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.stickyRefs.setStyleSheet(buttonStyle)
self.stickyRefs.setIcon(stickyIcon)
self.stickyRefs.setIconSize(QSize(fPx, fPx))
self.stickyRefs.setFixedSize(QSize(fPx, fPx))
self.stickyRefs.toggled.connect(self._doToggleSticky)
# Labels
self.lblRefs = QLabel("References")
self.lblRefs.setBuddy(self.showHide)
self.lblRefs.setIndent(0)
self.lblRefs.setMargin(0)
self.lblRefs.setContentsMargins(0, 0, 0, 0)
self.lblRefs.setAutoFillBackground(True)
self.lblRefs.setFixedHeight(fPx)
self.lblRefs.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.lblRefs.setPalette(self.thePalette)
self.lblSticky = QLabel("Sticky")
self.lblSticky.setBuddy(self.stickyRefs)
self.lblSticky.setIndent(0)
self.lblSticky.setMargin(0)
self.lblSticky.setContentsMargins(0, 0, 0, 0)
self.lblSticky.setAutoFillBackground(True)
self.lblSticky.setFixedHeight(fPx)
self.lblSticky.setAlignment(Qt.AlignLeft | Qt.AlignTop)
self.lblSticky.setPalette(self.thePalette)
lblFont = self.font()
lblFont.setPointSizeF(0.9*self.theTheme.fontPointSize)
self.lblRefs.setFont(lblFont)
self.lblSticky.setFont(lblFont)
# Assemble Layout
self.outerBox = QHBoxLayout()
self.outerBox.setSpacing(bSp)
self.outerBox.addWidget(self.showHide, 0)
self.outerBox.addWidget(self.lblRefs, 0)
self.outerBox.addSpacing(hSp)
self.outerBox.addWidget(self.stickyRefs, 0)
self.outerBox.addWidget(self.lblSticky, 0)
self.outerBox.addStretch(1)
self.setLayout(self.outerBox)
logger.debug("GuiDocViewFooter initialisation complete")
return
##
# Slots
##
def _doShowHide(self):
"""Toggle the expand/collapse of the panel.
"""
isVisible = self.viewMeta.isVisible()
self.viewMeta.setVisible(not isVisible)
return
def _doToggleSticky(self, theState):
"""Toggle the sticky flag for the reference panel.
"""
logger.verbose("Reference sticky is %s" % str(theState))
self.theParent.stickyRef = theState
if not theState and self.theParent.theHandle is not None:
self.viewMeta.refreshReferences(self.theParent.theHandle)
return
# END Class GuiDocViewFooter
# =============================================================================================== #
# The Document Back-Reference Panel
# Placed in a separate QSplitter position in the main GUI window
# =============================================================================================== #
class GuiDocViewDetails(QScrollArea):
def __init__(self, theParent):
QScrollArea.__init__(self, theParent)
logger.debug("Initialising GuiDocViewDetails ...")
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theProject = theParent.theProject
self.theTheme = theParent.theTheme
self.currHandle = None
self.refList = QLabel("")
self.refList.setWordWrap(True)
self.refList.setAlignment(Qt.AlignTop)
self.refList.setScaledContents(True)
self.refList.linkActivated.connect(self._linkClicked)
hCol = self.palette().highlight().color()
self.linkStyle = "style='color: rgb({0},{1},{2})'".format(
*self.theTheme.colLink
)
# Assemble
self.outerWidget = QWidget()
self.outerBox = QHBoxLayout()
self.outerBox.addWidget(self.refList, 1)
self.outerWidget.setLayout(self.outerBox)
self.setWidget(self.outerWidget)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setWidgetResizable(True)
self.setMinimumHeight(self.mainConf.pxInt(50))
logger.debug("GuiDocViewDetails initialisation complete")
return
def refreshReferences(self, tHandle):
"""Update the current list of document references from the
project index.
"""
self.currHandle = tHandle
if self.theParent.docViewer.stickyRef:
return
theRefs = self.theParent.theIndex.getBackReferenceList(tHandle)
theList = []
for tHandle in theRefs:
tItem = self.theProject.projTree[tHandle]
if tItem is not None:
theList.append("<a href='#head_%s:%s' %s>%s</a>" % (
tHandle, theRefs[tHandle], self.linkStyle, tItem.itemName
))
self.refList.setText(", ".join(theList))
return
##
# Internal Functions
##
def _linkClicked(self, theLink):
"""Capture the link-click and forward it to the document viewer
class for handling.
"""
logger.verbose("Clicked link: '%s'" % theLink)
if len(theLink) == 27:
tHandle = theLink[6:19]
self.theParent.viewDocument(tHandle, theLink)
return
# END Class GuiDocViewDetails
-1
View File
@@ -277,7 +277,6 @@ class GuiOutlineDetails(QScrollArea):
theBits = theLink.split("=")
if len(theBits) == 2:
self.theParent.docViewer.loadFromTag(theBits[1])
self.theParent.tabWidget.setCurrentWidget(self.theParent.splitView)
return
##
+4
View File
@@ -525,9 +525,13 @@ class GuiProjectTree(QTreeWidget):
always make sure items with a parent have had their parent item
sent first.
"""
logger.debug("Building project tree ...")
self.clear()
iCount = 0
for nwItem in self.theProject.getProjectItems():
iCount += 1
self._addTreeItem(nwItem)
logger.debug("%d items added to project tree" % iCount)
return True
def getSelectedHandle(self):
+2 -2
View File
@@ -44,7 +44,7 @@ class GuiMainStatus(QStatusBar):
def __init__(self, theParent):
QStatusBar.__init__(self, theParent)
logger.debug("Initialising MainStatus ...")
logger.debug("Initialising GuiMainStatus ...")
self.mainConf = nw.CONFIG
self.theParent = theParent
@@ -123,7 +123,7 @@ class GuiMainStatus(QStatusBar):
self.sessionTimer.timeout.connect(self._updateTime)
self.sessionTimer.start()
logger.debug("MainStatus initialisation complete")
logger.debug("GuiMainStatus initialisation complete")
self.clearStatus()
+2 -2
View File
@@ -750,11 +750,11 @@ class GuiIcons:
self.mainConf.iconPath, self.fbackName, "%s-dark.svg" % iconKey
)
if path.isfile(fbackIcon):
logger.verbose("Loading icon '%s' from fallback theme" % iconKey)
logger.verbose("Loading icon '%s' from fallback theme (dark mode)" % iconKey)
return QIcon(fbackIcon)
fbackIcon = path.join(self.mainConf.iconPath, self.fbackName, "%s.svg" % iconKey)
if path.isfile(fbackIcon):
logger.verbose("Loading icon '%s' from fallback theme" % iconKey)
logger.verbose("Loading icon '%s' from fallback theme (light mode)" % iconKey)
return QIcon(fbackIcon)
# Give up and return an empty icon
+4 -1
View File
@@ -55,7 +55,6 @@ class GuiMain(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
logger.info("Starting %s" % nw.__package__)
logger.debug("Initialising GUI ...")
self.mainConf = nw.CONFIG
@@ -232,6 +231,8 @@ class GuiMain(QMainWindow):
else:
self.manageProjects()
logger.debug("%s is ready ..." % nw.__package__)
return
def clearGUI(self):
@@ -435,6 +436,8 @@ class GuiMain(QMainWindow):
if self.theIndex.indexBroken:
self.rebuildIndex()
logger.debug("Project load complete")
return True
def saveProject(self, autoSave=False):