@@ -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 = []
|
||||
|
||||
@@ -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 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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"):
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -45,7 +45,7 @@ from nw.constants import nwUnicode
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# =============================================================================================== #
|
||||
# Config FOrm Layout
|
||||
# Config Form Layout
|
||||
# =============================================================================================== #
|
||||
|
||||
class QConfigLayout(QGridLayout):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
##
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||