Merge pull request #278 from vkbo/tweaks

GUI Tweaks
This commit is contained in:
Veronica K. Berglyd Olsen
2020-06-02 20:57:06 +02:00
committed by GitHub
25 changed files with 860 additions and 507 deletions
+3 -3
View File
@@ -172,7 +172,7 @@ def main(sysArgs=None):
debugLevel = logging.INFO
elif inOpt == "--debug":
debugLevel = logging.DEBUG
logFormat = "[{asctime:}] {name:>30}:{lineno:<4d} {levelname:8} {message:}"
logFormat = "[{asctime:}] {name:>20}:{lineno:<4d} {levelname:8} {message:}"
elif inOpt == "--logfile":
logFile = inArg
toFile = True
@@ -180,7 +180,7 @@ def main(sysArgs=None):
toStd = False
elif inOpt == "--verbose":
debugLevel = VERBOSE
logFormat = "[{asctime:}] {name:>30}:{lineno:<4d} {levelname:8} {message:}"
logFormat = "[{asctime:}] {name:>20}:{lineno:<4d} {levelname:8} {message:}"
elif inOpt == "--style":
qtStyle = inArg
elif inOpt == "--config":
@@ -196,7 +196,7 @@ def main(sysArgs=None):
CONFIG.cmdOpen = cmdOpen
# Set Logging
logFmt = logging.Formatter(fmt=logFormat,datefmt="%Y-%m-%d %H:%M:%S",style="{")
logFmt = logging.Formatter(fmt=logFormat, datefmt="%Y-%m-%d %H:%M:%S", style="{")
if not logFile == "" and toFile:
if path.isfile(logFile+".bak"):
+55
View File
@@ -0,0 +1,55 @@
<?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"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="hash-dark.svg"
id="svg5204"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata5210">
<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="defs5208" />
<sodipodi:namedview
inkscape:current-layer="svg5204"
inkscape:window-maximized="0"
inkscape:window-y="27"
inkscape:window-x="48"
inkscape:cy="12"
inkscape:cx="11.895082"
inkscape:zoom="38.125"
showgrid="false"
id="namedview5206"
inkscape:window-height="1376"
inkscape:window-width="2374"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<path
style="fill:#aeaeae;fill-opacity:1;stroke:none;stroke-width:1.7544229;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.75 2 C 6.7805 2 6 2.7805 6 3.75 L 6 5.5 L 4.1621094 5.5 C 3.2410844 5.5 2.5 6.2805 2.5 7.25 C 2.5 8.2195 3.2410844 9 4.1621094 9 L 6 9 L 6 15 L 4.1621094 15 C 3.2410844 15 2.5 15.7805 2.5 16.75 C 2.5 17.7195 3.2410844 18.5 4.1621094 18.5 L 6 18.5 L 6 20.25 C 6 21.2195 6.7805 22 7.75 22 C 8.7195 22 9.5 21.2195 9.5 20.25 L 9.5 18.5 L 14.5 18.5 L 14.5 20.25 C 14.5 21.2195 15.2805 22 16.25 22 C 17.2195 22 18 21.2195 18 20.25 L 18 18.5 L 19.837891 18.5 C 20.758916 18.5 21.5 17.7195 21.5 16.75 C 21.5 15.7805 20.758916 15 19.837891 15 L 18 15 L 18 9 L 19.837891 9 C 20.758916 9 21.5 8.2195 21.5 7.25 C 21.5 6.2805 20.758916 5.5 19.837891 5.5 L 18 5.5 L 18 3.75 C 18 2.7805 17.2195 2 16.25 2 C 15.2805 2 14.5 2.7805 14.5 3.75 L 14.5 5.5 L 9.5 5.5 L 9.5 3.75 C 9.5 2.7805 8.7195 2 7.75 2 z M 9.5 9 L 14.5 9 L 14.5 15 L 9.5 15 L 9.5 9 z "
id="rect928" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

+55
View File
@@ -0,0 +1,55 @@
<?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"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="hash.svg"
id="svg5204"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata5210">
<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="defs5208" />
<sodipodi:namedview
inkscape:current-layer="svg5204"
inkscape:window-maximized="0"
inkscape:window-y="27"
inkscape:window-x="48"
inkscape:cy="12"
inkscape:cx="11.895082"
inkscape:zoom="38.125"
showgrid="false"
id="namedview5206"
inkscape:window-height="1376"
inkscape:window-width="2374"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<path
style="fill:#000000;fill-opacity:0.78039216;stroke:none;stroke-width:1.7544229;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.75 2 C 6.7805 2 6 2.7805 6 3.75 L 6 5.5 L 4.1621094 5.5 C 3.2410844 5.5 2.5 6.2805 2.5 7.25 C 2.5 8.2195 3.2410844 9 4.1621094 9 L 6 9 L 6 15 L 4.1621094 15 C 3.2410844 15 2.5 15.7805 2.5 16.75 C 2.5 17.7195 3.2410844 18.5 4.1621094 18.5 L 6 18.5 L 6 20.25 C 6 21.2195 6.7805 22 7.75 22 C 8.7195 22 9.5 21.2195 9.5 20.25 L 9.5 18.5 L 14.5 18.5 L 14.5 20.25 C 14.5 21.2195 15.2805 22 16.25 22 C 17.2195 22 18 21.2195 18 20.25 L 18 18.5 L 19.837891 18.5 C 20.758916 18.5 21.5 17.7195 21.5 16.75 C 21.5 15.7805 20.758916 15 19.837891 15 L 18 15 L 18 9 L 19.837891 9 C 20.758916 9 21.5 8.2195 21.5 7.25 C 21.5 6.2805 20.758916 5.5 19.837891 5.5 L 18 5.5 L 18 3.75 C 18 2.7805 17.2195 2 16.25 2 C 15.2805 2 14.5 2.7805 14.5 3.75 L 14.5 5.5 L 9.5 5.5 L 9.5 3.75 C 9.5 2.7805 8.7195 2 7.75 2 z M 9.5 9 L 14.5 9 L 14.5 15 L 9.5 15 L 9.5 9 z "
id="rect928" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -0,0 +1,55 @@
<?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"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="hash.svg"
id="svg5204"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata5210">
<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="defs5208" />
<sodipodi:namedview
inkscape:current-layer="svg5204"
inkscape:window-maximized="0"
inkscape:window-y="27"
inkscape:window-x="48"
inkscape:cy="12"
inkscape:cx="11.895082"
inkscape:zoom="38.125"
showgrid="false"
id="namedview5206"
inkscape:window-height="1376"
inkscape:window-width="2374"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<path
style="fill:#6699cc;fill-opacity:1;stroke:none;stroke-width:1.7544229;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.75 2 C 6.7805 2 6 2.7805 6 3.75 L 6 5.5 L 4.1621094 5.5 C 3.2410844 5.5 2.5 6.2805 2.5 7.25 C 2.5 8.2195 3.2410844 9 4.1621094 9 L 6 9 L 6 15 L 4.1621094 15 C 3.2410844 15 2.5 15.7805 2.5 16.75 C 2.5 17.7195 3.2410844 18.5 4.1621094 18.5 L 6 18.5 L 6 20.25 C 6 21.2195 6.7805 22 7.75 22 C 8.7195 22 9.5 21.2195 9.5 20.25 L 9.5 18.5 L 14.5 18.5 L 14.5 20.25 C 14.5 21.2195 15.2805 22 16.25 22 C 17.2195 22 18 21.2195 18 20.25 L 18 18.5 L 19.837891 18.5 C 20.758916 18.5 21.5 17.7195 21.5 16.75 C 21.5 15.7805 20.758916 15 19.837891 15 L 18 15 L 18 9 L 19.837891 9 C 20.758916 9 21.5 8.2195 21.5 7.25 C 21.5 6.2805 20.758916 5.5 19.837891 5.5 L 18 5.5 L 18 3.75 C 18 2.7805 17.2195 2 16.25 2 C 15.2805 2 14.5 2.7805 14.5 3.75 L 14.5 5.5 L 9.5 5.5 L 9.5 3.75 C 9.5 2.7805 8.7195 2 7.75 2 z M 9.5 9 L 14.5 9 L 14.5 15 L 9.5 15 L 9.5 9 z "
id="rect928" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -1,8 +1,9 @@
##
# Icons: Typicons Colour Dark
# Source: https://github.com/stephenhutchings/typicons.font
# Credit: Stephen Hutchings
# Modified: Veronica Berglyd Olsen
# Icons: Typicons Colour Dark
# Source: https://github.com/stephenhutchings/typicons.font
# Credit: Stephen Hutchings
# Modified: Veronica Berglyd Olsen
# Additions: hash.svg
##
[Main]
@@ -39,3 +40,4 @@ save = download.svg
edit = pencil.svg
check = tick.svg
cross = times.svg
hash = hash.svg
@@ -0,0 +1,55 @@
<?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"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="hash.svg"
id="svg5204"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata5210">
<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="defs5208" />
<sodipodi:namedview
inkscape:current-layer="svg5204"
inkscape:window-maximized="0"
inkscape:window-y="27"
inkscape:window-x="48"
inkscape:cy="12"
inkscape:cx="11.895082"
inkscape:zoom="38.125"
showgrid="false"
id="namedview5206"
inkscape:window-height="1376"
inkscape:window-width="2374"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<path
style="fill:#4271ae;fill-opacity:1;stroke:none;stroke-width:1.7544229;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.75 2 C 6.7805 2 6 2.7805 6 3.75 L 6 5.5 L 4.1621094 5.5 C 3.2410844 5.5 2.5 6.2805 2.5 7.25 C 2.5 8.2195 3.2410844 9 4.1621094 9 L 6 9 L 6 15 L 4.1621094 15 C 3.2410844 15 2.5 15.7805 2.5 16.75 C 2.5 17.7195 3.2410844 18.5 4.1621094 18.5 L 6 18.5 L 6 20.25 C 6 21.2195 6.7805 22 7.75 22 C 8.7195 22 9.5 21.2195 9.5 20.25 L 9.5 18.5 L 14.5 18.5 L 14.5 20.25 C 14.5 21.2195 15.2805 22 16.25 22 C 17.2195 22 18 21.2195 18 20.25 L 18 18.5 L 19.837891 18.5 C 20.758916 18.5 21.5 17.7195 21.5 16.75 C 21.5 15.7805 20.758916 15 19.837891 15 L 18 15 L 18 9 L 19.837891 9 C 20.758916 9 21.5 8.2195 21.5 7.25 C 21.5 6.2805 20.758916 5.5 19.837891 5.5 L 18 5.5 L 18 3.75 C 18 2.7805 17.2195 2 16.25 2 C 15.2805 2 14.5 2.7805 14.5 3.75 L 14.5 5.5 L 9.5 5.5 L 9.5 3.75 C 9.5 2.7805 8.7195 2 7.75 2 z M 9.5 9 L 14.5 9 L 14.5 15 L 9.5 15 L 9.5 9 z "
id="rect928" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -1,8 +1,9 @@
##
# Icons: Typicons Colour Light
# Source: https://github.com/stephenhutchings/typicons.font
# Credit: Stephen Hutchings
# Modified: Veronica Berglyd Olsen
# Icons: Typicons Colour Light
# Source: https://github.com/stephenhutchings/typicons.font
# Credit: Stephen Hutchings
# Modified: Veronica Berglyd Olsen
# Additions: hash.svg
##
[Main]
@@ -39,3 +40,4 @@ save = download.svg
edit = pencil.svg
check = tick.svg
cross = times.svg
hash = hash.svg
@@ -0,0 +1,55 @@
<?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"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="hash.svg"
id="svg5204"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata5210">
<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="defs5208" />
<sodipodi:namedview
inkscape:current-layer="svg5204"
inkscape:window-maximized="0"
inkscape:window-y="27"
inkscape:window-x="48"
inkscape:cy="12"
inkscape:cx="11.895082"
inkscape:zoom="38.125"
showgrid="false"
id="namedview5206"
inkscape:window-height="1376"
inkscape:window-width="2374"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<path
style="fill:#aeaeae;fill-opacity:1;stroke:none;stroke-width:1.7544229;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.75 2 C 6.7805 2 6 2.7805 6 3.75 L 6 5.5 L 4.1621094 5.5 C 3.2410844 5.5 2.5 6.2805 2.5 7.25 C 2.5 8.2195 3.2410844 9 4.1621094 9 L 6 9 L 6 15 L 4.1621094 15 C 3.2410844 15 2.5 15.7805 2.5 16.75 C 2.5 17.7195 3.2410844 18.5 4.1621094 18.5 L 6 18.5 L 6 20.25 C 6 21.2195 6.7805 22 7.75 22 C 8.7195 22 9.5 21.2195 9.5 20.25 L 9.5 18.5 L 14.5 18.5 L 14.5 20.25 C 14.5 21.2195 15.2805 22 16.25 22 C 17.2195 22 18 21.2195 18 20.25 L 18 18.5 L 19.837891 18.5 C 20.758916 18.5 21.5 17.7195 21.5 16.75 C 21.5 15.7805 20.758916 15 19.837891 15 L 18 15 L 18 9 L 19.837891 9 C 20.758916 9 21.5 8.2195 21.5 7.25 C 21.5 6.2805 20.758916 5.5 19.837891 5.5 L 18 5.5 L 18 3.75 C 18 2.7805 17.2195 2 16.25 2 C 15.2805 2 14.5 2.7805 14.5 3.75 L 14.5 5.5 L 9.5 5.5 L 9.5 3.75 C 9.5 2.7805 8.7195 2 7.75 2 z M 9.5 9 L 14.5 9 L 14.5 15 L 9.5 15 L 9.5 9 z "
id="rect928" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -1,7 +1,9 @@
##
# Icons: Typicons Grey Dark
# Source: https://github.com/stephenhutchings/typicons.font
# Credit: Stephen Hutchings
# Icons: Typicons Grey Dark
# Source: https://github.com/stephenhutchings/typicons.font
# Credit: Stephen Hutchings
# Modified: Veronica Berglyd Olsen
# Additions: hash.svg
##
[Main]
@@ -38,3 +40,4 @@ save = download.svg
edit = pencil.svg
check = tick.svg
cross = times.svg
hash = hash.svg
@@ -0,0 +1,55 @@
<?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"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="hash.svg"
id="svg5204"
viewBox="0 0 24 24"
height="24"
width="24"
version="1.2">
<metadata
id="metadata5210">
<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="defs5208" />
<sodipodi:namedview
inkscape:current-layer="svg5204"
inkscape:window-maximized="0"
inkscape:window-y="27"
inkscape:window-x="48"
inkscape:cy="12"
inkscape:cx="11.895082"
inkscape:zoom="38.125"
showgrid="false"
id="namedview5206"
inkscape:window-height="1376"
inkscape:window-width="2374"
inkscape:pageshadow="2"
inkscape:pageopacity="0"
guidetolerance="10"
gridtolerance="10"
objecttolerance="10"
borderopacity="1"
bordercolor="#666666"
pagecolor="#ffffff" />
<path
style="fill:#000000;fill-opacity:0.78039216;stroke:none;stroke-width:1.7544229;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.75 2 C 6.7805 2 6 2.7805 6 3.75 L 6 5.5 L 4.1621094 5.5 C 3.2410844 5.5 2.5 6.2805 2.5 7.25 C 2.5 8.2195 3.2410844 9 4.1621094 9 L 6 9 L 6 15 L 4.1621094 15 C 3.2410844 15 2.5 15.7805 2.5 16.75 C 2.5 17.7195 3.2410844 18.5 4.1621094 18.5 L 6 18.5 L 6 20.25 C 6 21.2195 6.7805 22 7.75 22 C 8.7195 22 9.5 21.2195 9.5 20.25 L 9.5 18.5 L 14.5 18.5 L 14.5 20.25 C 14.5 21.2195 15.2805 22 16.25 22 C 17.2195 22 18 21.2195 18 20.25 L 18 18.5 L 19.837891 18.5 C 20.758916 18.5 21.5 17.7195 21.5 16.75 C 21.5 15.7805 20.758916 15 19.837891 15 L 18 15 L 18 9 L 19.837891 9 C 20.758916 9 21.5 8.2195 21.5 7.25 C 21.5 6.2805 20.758916 5.5 19.837891 5.5 L 18 5.5 L 18 3.75 C 18 2.7805 17.2195 2 16.25 2 C 15.2805 2 14.5 2.7805 14.5 3.75 L 14.5 5.5 L 9.5 5.5 L 9.5 3.75 C 9.5 2.7805 8.7195 2 7.75 2 z M 9.5 9 L 14.5 9 L 14.5 15 L 9.5 15 L 9.5 9 z "
id="rect928" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -1,7 +1,9 @@
##
# Icons: Typicons Grey Light
# Source: https://github.com/stephenhutchings/typicons.font
# Credit: Stephen Hutchings
# Icons: Typicons Grey Light
# Source: https://github.com/stephenhutchings/typicons.font
# Credit: Stephen Hutchings
# Modified: Veronica Berglyd Olsen
# Additions: hash.svg
##
[Main]
@@ -38,3 +40,4 @@ save = download.svg
edit = pencil.svg
check = tick.svg
cross = times.svg
hash = hash.svg
-1
View File
@@ -136,7 +136,6 @@ class nwLabels():
}
OUTLINE_COLS = {
nwOutline.TITLE : "Title",
nwOutline.HANDLE : "Handle",
nwOutline.LEVEL : "Level",
nwOutline.LABEL : "Document",
nwOutline.LINE : "Line",
+15 -16
View File
@@ -107,21 +107,20 @@ class nwAlert(Enum):
class nwOutline(Enum):
TITLE = 0
HANDLE = 1
LEVEL = 2
LABEL = 3
LINE = 4
CCOUNT = 5
WCOUNT = 6
PCOUNT = 7
POV = 8
CHAR = 9
PLOT = 10
TIME = 11
WORLD = 12
OBJECT = 13
ENTITY = 14
CUSTOM = 15
SYNOP = 16
LEVEL = 1
LABEL = 2
LINE = 3
CCOUNT = 4
WCOUNT = 5
PCOUNT = 6
POV = 7
CHAR = 8
PLOT = 9
TIME = 10
WORLD = 11
OBJECT = 12
ENTITY = 13
CUSTOM = 14
SYNOP = 15
# END Enum nwOutline
+8 -8
View File
@@ -5,23 +5,23 @@ from nw.gui.build import GuiBuildNovel
from nw.gui.docbars import GuiDocTitleBar
from nw.gui.docbars import GuiNoticeBar
from nw.gui.docbars import GuiSearchBar
from nw.gui.docdetails import GuiDocDetails
from nw.gui.docdetails import GuiDocViewDetails
from nw.gui.doceditor import GuiDocEditor
from nw.gui.docmerge import GuiDocMerge
from nw.gui.docsplit import GuiDocSplit
from nw.gui.doctree import GuiDocTree
from nw.gui.docviewer import GuiDocViewer
from nw.gui.itemdetails import GuiItemDetails
from nw.gui.itemeditor import GuiItemEditor
from nw.gui.mainmenu import GuiMainMenu
from nw.gui.outline import GuiProjectOutline
from nw.gui.preferences import GuiPreferences
from nw.gui.projectload import GuiProjectLoad
from nw.gui.projectsettings import GuiProjectSettings
from nw.gui.projload import GuiProjectLoad
from nw.gui.projsettings import GuiProjectSettings
from nw.gui.projtree import GuiProjectTree
from nw.gui.sessionlog import GuiSessionLogView
from nw.gui.statusbar import GuiMainStatus
from nw.gui.theme import GuiIcons
from nw.gui.theme import GuiTheme
from nw.gui.viewdetails import GuiDocViewDetails
__all__ = [
"GuiAbout",
@@ -29,21 +29,21 @@ __all__ = [
"GuiDocTitleBar",
"GuiNoticeBar",
"GuiSearchBar",
"GuiDocDetails",
"GuiDocViewDetails",
"GuiDocEditor",
"GuiDocMerge",
"GuiDocSplit",
"GuiDocTree",
"GuiDocViewer",
"GuiItemDetails",
"GuiItemEditor",
"GuiMainMenu",
"GuiProjectOutline",
"GuiPreferences",
"GuiProjectLoad",
"GuiProjectSettings",
"GuiProjectTree",
"GuiSessionLogView",
"GuiMainStatus",
"GuiIcons",
"GuiTheme",
"GuiDocViewDetails",
]
+55 -55
View File
@@ -93,7 +93,7 @@ class GuiBuildNovel(QDialog):
# Title Formats
# =============
self.titleGroup = QGroupBox("Novel Title Formats", self)
self.titleGroup = QGroupBox("Title Formats for Novel Files", self)
self.titleForm = QGridLayout(self)
self.titleGroup.setLayout(self.titleForm)
@@ -169,9 +169,9 @@ class GuiBuildNovel(QDialog):
# Text Options
# =============
self.textGroup = QGroupBox("Text Options", self)
self.textForm = QGridLayout(self)
self.textGroup.setLayout(self.textForm)
self.formatGroup = QGroupBox("Formatting Options", self)
self.formatForm = QGridLayout(self)
self.formatGroup.setLayout(self.formatForm)
## Font Family
self.textFont = QLineEdit()
@@ -212,29 +212,29 @@ class GuiBuildNovel(QDialog):
self.optState.getBool("GuiBuildNovel", "noStyling", False)
)
self.textForm.addWidget(QLabel("Font family"), 0, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.textFont, 0, 1, 1, 1, Qt.AlignRight)
self.textForm.addWidget(self.fontButton, 0, 2, 1, 1, Qt.AlignRight)
self.textForm.addWidget(QLabel("Font size"), 1, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.textSize, 1, 1, 1, 2, Qt.AlignRight)
self.textForm.addWidget(QLabel("Justify text"), 2, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.justifyText, 2, 1, 1, 2, Qt.AlignRight)
self.textForm.addWidget(QLabel("Disable styling"), 3, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.noStyling, 3, 1, 1, 2, Qt.AlignRight)
self.formatForm.addWidget(QLabel("Font family"), 0, 0, 1, 1, Qt.AlignLeft)
self.formatForm.addWidget(self.textFont, 0, 1, 1, 1, Qt.AlignRight)
self.formatForm.addWidget(self.fontButton, 0, 2, 1, 1, Qt.AlignRight)
self.formatForm.addWidget(QLabel("Font size"), 1, 0, 1, 1, Qt.AlignLeft)
self.formatForm.addWidget(self.textSize, 1, 1, 1, 2, Qt.AlignRight)
self.formatForm.addWidget(QLabel("Justify text"), 2, 0, 1, 1, Qt.AlignLeft)
self.formatForm.addWidget(self.justifyText, 2, 1, 1, 2, Qt.AlignRight)
self.formatForm.addWidget(QLabel("Disable styling"), 3, 0, 1, 1, Qt.AlignLeft)
self.formatForm.addWidget(self.noStyling, 3, 1, 1, 2, Qt.AlignRight)
self.textForm.setColumnStretch(0, 1)
self.textForm.setColumnStretch(1, 0)
self.textForm.setColumnStretch(2, 0)
self.formatForm.setColumnStretch(0, 1)
self.formatForm.setColumnStretch(1, 0)
self.formatForm.setColumnStretch(2, 0)
# Include Switches
# ================
self.includeGroup = QGroupBox("Include Non-Text Elements", self)
self.includeForm = QGridLayout(self)
self.includeGroup.setLayout(self.includeForm)
self.textGroup = QGroupBox("Text Options", self)
self.textForm = QGridLayout(self)
self.textGroup.setLayout(self.textForm)
self.includeSynopsis = QSwitch()
self.includeSynopsis.setToolTip(
"Include synopsis type comments in the output."
"Include synopsis comments in the output."
)
self.includeSynopsis.setChecked(self.theProject.titleFormat["withSynopsis"])
@@ -250,21 +250,31 @@ class GuiBuildNovel(QDialog):
)
self.includeKeywords.setChecked(self.theProject.titleFormat["withKeywords"])
self.includeForm.addWidget(QLabel("Include synopsis"), 0, 0, 1, 1, Qt.AlignLeft)
self.includeForm.addWidget(self.includeSynopsis, 0, 1, 1, 1, Qt.AlignRight)
self.includeForm.addWidget(QLabel("Include comments"), 1, 0, 1, 1, Qt.AlignLeft)
self.includeForm.addWidget(self.includeComments, 1, 1, 1, 1, Qt.AlignRight)
self.includeForm.addWidget(QLabel("Include keywords"), 2, 0, 1, 1, Qt.AlignLeft)
self.includeForm.addWidget(self.includeKeywords, 2, 1, 1, 1, Qt.AlignRight)
self.includeBody = QSwitch()
self.includeBody.setToolTip(
"Include body text in the output."
)
self.includeBody.setChecked(
self.optState.getBool("GuiBuildNovel", "includeBody", True)
)
self.includeForm.setColumnStretch(0, 1)
self.includeForm.setColumnStretch(1, 0)
self.textForm.addWidget(QLabel("Include synopsis"), 0, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.includeSynopsis, 0, 1, 1, 1, Qt.AlignRight)
self.textForm.addWidget(QLabel("Include comments"), 1, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.includeComments, 1, 1, 1, 1, Qt.AlignRight)
self.textForm.addWidget(QLabel("Include keywords"), 2, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.includeKeywords, 2, 1, 1, 1, Qt.AlignRight)
self.textForm.addWidget(QLabel("Include body text"), 3, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.includeBody, 3, 1, 1, 1, Qt.AlignRight)
self.textForm.setColumnStretch(0, 1)
self.textForm.setColumnStretch(1, 0)
# Additional Options
# ==================
self.addsGroup = QGroupBox("Additional Options", self)
self.addsForm = QGridLayout(self)
self.addsGroup.setLayout(self.addsForm)
self.fileGroup = QGroupBox("File Options", self)
self.fileForm = QGridLayout(self)
self.fileGroup.setLayout(self.fileForm)
self.novelFiles = QSwitch()
self.novelFiles.setToolTip(
@@ -290,26 +300,15 @@ class GuiBuildNovel(QDialog):
self.optState.getBool("GuiBuildNovel", "ignoreFlag", False)
)
self.excludeBody = QSwitch()
self.excludeBody.setToolTip(
"Exclude body text in the output. Combine with 'Include synopsis' "
"for making outline."
)
self.excludeBody.setChecked(
self.optState.getBool("GuiBuildNovel", "excludeBody", False)
)
self.fileForm.addWidget(QLabel("Include novel files"), 0, 0, 1, 1, Qt.AlignLeft)
self.fileForm.addWidget(self.novelFiles, 0, 1, 1, 1, Qt.AlignRight)
self.fileForm.addWidget(QLabel("Include note files"), 1, 0, 1, 1, Qt.AlignLeft)
self.fileForm.addWidget(self.noteFiles, 1, 1, 1, 1, Qt.AlignRight)
self.fileForm.addWidget(QLabel("Ignore export flag"), 2, 0, 1, 1, Qt.AlignLeft)
self.fileForm.addWidget(self.ignoreFlag, 2, 1, 1, 1, Qt.AlignRight)
self.addsForm.addWidget(QLabel("Include novel files"), 0, 0, 1, 1, Qt.AlignLeft)
self.addsForm.addWidget(self.novelFiles, 0, 1, 1, 1, Qt.AlignRight)
self.addsForm.addWidget(QLabel("Include note files"), 1, 0, 1, 1, Qt.AlignLeft)
self.addsForm.addWidget(self.noteFiles, 1, 1, 1, 1, Qt.AlignRight)
self.addsForm.addWidget(QLabel("Ignore export flag"), 2, 0, 1, 1, Qt.AlignLeft)
self.addsForm.addWidget(self.ignoreFlag, 2, 1, 1, 1, Qt.AlignRight)
self.addsForm.addWidget(QLabel("Exclude body text"), 3, 0, 1, 1, Qt.AlignLeft)
self.addsForm.addWidget(self.excludeBody, 3, 1, 1, 1, Qt.AlignRight)
self.addsForm.setColumnStretch(0, 1)
self.addsForm.setColumnStretch(1, 0)
self.fileForm.setColumnStretch(0, 1)
self.fileForm.setColumnStretch(1, 0)
# Build Button
# ============
@@ -373,9 +372,9 @@ class GuiBuildNovel(QDialog):
# Assemble GUI
# ============
self.toolsBox.addWidget(self.titleGroup)
self.toolsBox.addWidget(self.formatGroup)
self.toolsBox.addWidget(self.textGroup)
self.toolsBox.addWidget(self.includeGroup)
self.toolsBox.addWidget(self.addsGroup)
self.toolsBox.addWidget(self.fileGroup)
self.toolsBox.addStretch(1)
self.toolsBox.addWidget(self.buildProgress)
self.toolsBox.addWidget(self.buildNovel)
@@ -388,6 +387,7 @@ class GuiBuildNovel(QDialog):
self.outerBox.setStretch(1, 1)
self.setLayout(self.outerBox)
self.buildNovel.setFocus()
self.show()
@@ -436,7 +436,7 @@ class GuiBuildNovel(QDialog):
novelFiles = self.novelFiles.isChecked()
noteFiles = self.noteFiles.isChecked()
ignoreFlag = self.ignoreFlag.isChecked()
excludeBody = self.excludeBody.isChecked()
includeBody = self.includeBody.isChecked()
makeHtml = ToHtml(self.theProject, self.theParent)
makeHtml.setTitleFormat(fmtTitle)
@@ -444,7 +444,7 @@ class GuiBuildNovel(QDialog):
makeHtml.setUnNumberedFormat(fmtUnnumbered)
makeHtml.setSceneFormat(fmtScene, fmtScene == "")
makeHtml.setSectionFormat(fmtSection, fmtSection == "")
makeHtml.setBodyText(not excludeBody)
makeHtml.setBodyText(includeBody)
makeHtml.setSynopsis(incSynopsis)
makeHtml.setComments(incComments)
makeHtml.setKeywords(incKeywords)
@@ -867,7 +867,7 @@ class GuiBuildNovel(QDialog):
self.optState.setValue("GuiBuildNovel", "addNovel", self.novelFiles.isChecked())
self.optState.setValue("GuiBuildNovel", "addNotes", self.noteFiles.isChecked())
self.optState.setValue("GuiBuildNovel", "ignoreFlag", self.ignoreFlag.isChecked())
self.optState.setValue("GuiBuildNovel", "excludeBody", self.excludeBody.isChecked())
self.optState.setValue("GuiBuildNovel", "includeBody", self.includeBody.isChecked())
self.optState.saveSettings()
return
+94 -208
View File
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
"""novelWriter GUI Document Details
"""novelWriter GUI DocView Details
novelWriter GUI Document Details
====================================
Class holding the left side document details panel
novelWriter GUI DocView Details
===================================
Class holding the document view details panel
File History:
Created: 2019-04-24 [0.0.1]
Created: 2019-10-31 [0.3.2]
This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen
@@ -28,238 +28,124 @@
import logging
import nw
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QIcon, QPixmap
from PyQt5.QtWidgets import QFrame, QGridLayout, QLabel
from nw.constants import (
nwLabels, nwItemClass, nwItemType, nwItemLayout, nwUnicode
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtWidgets import (
QWidget, QLabel, QScrollArea, QFrame, QToolButton, QCheckBox, QGridLayout
)
logger = logging.getLogger(__name__)
class GuiDocDetails(QFrame):
class GuiDocViewDetails(QWidget):
def __init__(self, theParent, theProject):
QFrame.__init__(self, theParent)
QWidget.__init__(self, theParent)
logger.debug("Initialising DocDetails ...")
logger.debug("Initialising DocViewDetails ...")
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theProject = theProject
self.theTheme = theParent.theTheme
self.theHandle = None
self.currHandle = None
self.mainBox = QGridLayout(self)
self.mainBox.setVerticalSpacing(1)
self.mainBox.setHorizontalSpacing(6)
self.setLayout(self.mainBox)
self.outerBox = QGridLayout(self)
self.outerBox.setContentsMargins(0,0,0,0)
self.outerBox.setHorizontalSpacing(0)
self.outerBox.setVerticalSpacing(4)
self.pS = 0.9*self.theTheme.fontPointSize
self.iPx = self.theTheme.textIconSize
self.sPx = int(round(0.8*self.theTheme.textIconSize))
self.refLabel = QLabel("Referenced By", self)
self.expCheck = self.theTheme.getPixmap("check", (self.iPx, self.iPx))
self.expCross = self.theTheme.getPixmap("cross", (self.iPx, self.iPx))
self.showHide = QToolButton()
self.showHide.setStyleSheet("QToolButton { border: none; }")
self.showHide.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.showHide.setArrowType(Qt.DownArrow)
self.showHide.setCheckable(True)
self.showHide.setIconSize(QSize(16,16))
self.showHide.toggled.connect(self._doShowHide)
self.fntLabel = QFont()
self.fntLabel.setBold(True)
self.fntLabel.setPointSizeF(self.pS)
self.isSticky = QCheckBox("Sticky")
self.isSticky.setChecked(False)
self.isSticky.toggled.connect(self._doSticky)
self.fntValue = QFont()
self.fntValue.setPointSizeF(self.pS)
self.refList = QLabel("None")
self.refList.setWordWrap(True)
self.refList.setAlignment(Qt.AlignTop)
self.refList.setScaledContents(True)
self.refList.linkActivated.connect(self._linkClicked)
# Label
self.labelName = QLabel("Label")
self.labelName.setFont(self.fntLabel)
self.labelName.setAlignment(Qt.AlignLeft | Qt.AlignBaseline)
self.scrollBox = QScrollArea()
self.scrollBox.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scrollBox.setFrameStyle(QFrame.NoFrame)
self.scrollBox.setWidgetResizable(True)
self.scrollBox.setFixedHeight(80)
self.scrollBox.setWidget(self.refList)
self.labelFlag = QLabel("")
self.labelFlag.setAlignment(Qt.AlignRight | Qt.AlignBaseline)
self.outerBox.addWidget(self.showHide, 0, 0)
self.outerBox.addWidget(self.refLabel, 0, 1)
self.outerBox.addWidget(self.isSticky, 0, 2)
self.outerBox.addWidget(self.scrollBox, 1, 1, 1, 2)
self.outerBox.setColumnStretch(1, 1)
self.labelData = QLabel("")
self.labelData.setFont(self.fntValue)
self.labelData.setAlignment(Qt.AlignLeft | Qt.AlignBaseline)
self.labelData.setWordWrap(True)
self.setLayout(self.outerBox)
self.setContentsMargins(0,0,0,0)
# Status
self.statusName = QLabel("Status")
self.statusName.setFont(self.fntLabel)
self.statusName.setAlignment(Qt.AlignLeft)
self._doShowHide(self.mainConf.showRefPanel)
self.statusFlag = QLabel("")
self.statusFlag.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.statusData = QLabel("")
self.statusData.setFont(self.fntValue)
self.statusData.setAlignment(Qt.AlignLeft)
# Class
self.className = QLabel("Class")
self.className.setFont(self.fntLabel)
self.className.setAlignment(Qt.AlignLeft)
self.classFlag = QLabel("")
self.classFlag.setFont(self.fntValue)
self.classFlag.setAlignment(Qt.AlignRight)
self.classData = QLabel("")
self.classData.setFont(self.fntValue)
self.classData.setAlignment(Qt.AlignLeft)
# Layout
self.layoutName = QLabel("Layout")
self.layoutName.setFont(self.fntLabel)
self.layoutName.setAlignment(Qt.AlignLeft)
self.layoutFlag = QLabel("")
self.layoutFlag.setFont(self.fntValue)
self.layoutFlag.setAlignment(Qt.AlignRight)
self.layoutData = QLabel("")
self.layoutData.setFont(self.fntValue)
self.layoutData.setAlignment(Qt.AlignLeft)
# Character Count
self.cCountName = QLabel(" Characters")
self.cCountName.setFont(self.fntLabel)
self.cCountName.setAlignment(Qt.AlignRight)
self.cCountData = QLabel("")
self.cCountData.setFont(self.fntValue)
self.cCountData.setAlignment(Qt.AlignRight)
# Word Count
self.wCountName = QLabel(" Words")
self.wCountName.setFont(self.fntLabel)
self.wCountName.setAlignment(Qt.AlignRight)
self.wCountData = QLabel("")
self.wCountData.setFont(self.fntValue)
self.wCountData.setAlignment(Qt.AlignRight)
# Paragraph Count
self.pCountName = QLabel(" Paragraphs")
self.pCountName.setFont(self.fntLabel)
self.pCountName.setAlignment(Qt.AlignRight)
self.pCountData = QLabel("")
self.pCountData.setFont(self.fntValue)
self.pCountData.setAlignment(Qt.AlignRight)
# Assemble
self.mainBox.addWidget(self.labelName, 0, 0, 1, 1)
self.mainBox.addWidget(self.labelFlag, 0, 1, 1, 1)
self.mainBox.addWidget(self.labelData, 0, 2, 1, 3)
self.mainBox.addWidget(self.statusName, 1, 0, 1, 1)
self.mainBox.addWidget(self.statusFlag, 1, 1, 1, 1)
self.mainBox.addWidget(self.statusData, 1, 2, 1, 1)
self.mainBox.addWidget(self.cCountName, 1, 3, 1, 1)
self.mainBox.addWidget(self.cCountData, 1, 4, 1, 1)
self.mainBox.addWidget(self.className, 2, 0, 1, 1)
self.mainBox.addWidget(self.classFlag, 2, 1, 1, 1)
self.mainBox.addWidget(self.classData, 2, 2, 1, 1)
self.mainBox.addWidget(self.wCountName, 2, 3, 1, 1)
self.mainBox.addWidget(self.wCountData, 2, 4, 1, 1)
self.mainBox.addWidget(self.layoutName, 3, 0, 1, 1)
self.mainBox.addWidget(self.layoutFlag, 3, 1, 1, 1)
self.mainBox.addWidget(self.layoutData, 3, 2, 1, 1)
self.mainBox.addWidget(self.pCountName, 3, 3, 1, 1)
self.mainBox.addWidget(self.pCountData, 3, 4, 1, 1)
self.mainBox.setColumnStretch(0,0)
self.mainBox.setColumnStretch(1,0)
self.mainBox.setColumnStretch(2,1)
self.mainBox.setColumnStretch(3,0)
self.mainBox.setColumnStretch(4,0)
# Make sure the columns for flags and counts don't resize too often
flagWidth = self.theTheme.getTextWidth("Mm", self.fntValue)
countWidth = self.theTheme.getTextWidth("99,999", self.fntValue)
self.mainBox.setColumnMinimumWidth(1, flagWidth)
self.mainBox.setColumnMinimumWidth(4, countWidth)
logger.debug("DocDetails initialisation complete")
logger.debug("DocViewDetails initialisation complete")
return
###
# Class Methods
def refreshReferences(self, tHandle):
"""Update the current list of document references from the
project index.
"""
self.currHandle = tHandle
if self.isSticky.isChecked():
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</a>" % (
tHandle, theRefs[tHandle], tItem.itemName
))
self.refList.setText(", ".join(theList))
self.refList.adjustSize()
return
##
# Internal Functions
##
def updateCounts(self, tHandle, cC, wC, pC):
"""Just update the counts if the handle is the same as the one
we're already showing.
def _linkClicked(self, theLink):
"""Capture the link-click and forward it to the document viewer
class for handling.
"""
if tHandle == self.theHandle:
self.cCountData.setText("{:n}".format(cC))
self.wCountData.setText("{:n}".format(wC))
self.pCountData.setText("{:n}".format(pC))
logger.verbose("Clicked link: '%s'" % theLink)
if len(theLink) == 27:
tHandle = theLink[6:19]
self.theParent.viewDocument(tHandle, theLink)
return
def updateViewBox(self, tHandle):
"""Populate the details box from a given handle.
def _doShowHide(self, chState):
"""Toggle the expand/collapse of the panel.
"""
self.theHandle = tHandle
nwItem = self.theProject.projTree[tHandle]
if nwItem is None:
self.labelFlag.setText("")
self.labelData.setText("")
self.statusFlag.setText("")
self.statusData.setText("")
self.classFlag.setText("")
self.classData.setText("")
self.layoutFlag.setText("")
self.layoutData.setText("")
self.cCountData.setText("")
self.wCountData.setText("")
self.pCountData.setText("")
self.scrollBox.setVisible(chState)
self.mainConf.setShowRefPanel(chState)
if chState:
self.showHide.setArrowType(Qt.DownArrow)
else:
theLabel = nwItem.itemName
if len(theLabel) > 100:
theLabel = theLabel[:96].rstrip()+" ..."
iStatus = nwItem.itemStatus
if nwItem.itemClass == nwItemClass.NOVEL:
iStatus = self.theProject.statusItems.checkEntry(iStatus) # Make sure it's valid
flagIcon = self.theParent.statusIcons[iStatus]
else:
iStatus = self.theProject.importItems.checkEntry(iStatus) # Make sure it's valid
flagIcon = self.theParent.importIcons[iStatus]
if nwItem.itemType == nwItemType.FILE:
if nwItem.isExported:
self.labelFlag.setPixmap(self.expCheck)
else:
self.labelFlag.setPixmap(self.expCross)
else:
self.labelFlag.setPixmap(QPixmap(1,1))
self.statusFlag.setPixmap(flagIcon.pixmap(self.sPx, self.sPx))
self.classFlag.setText(nwLabels.CLASS_FLAG[nwItem.itemClass])
if nwItem.itemLayout == nwItemLayout.NO_LAYOUT:
self.layoutFlag.setText("-")
else:
self.layoutFlag.setText(nwLabels.LAYOUT_FLAG[nwItem.itemLayout])
self.labelData.setText(theLabel)
self.statusData.setText(nwItem.itemStatus)
self.classData.setText(nwLabels.CLASS_NAME[nwItem.itemClass])
self.layoutData.setText(nwLabels.LAYOUT_NAME[nwItem.itemLayout])
if nwItem.itemType == nwItemType.FILE:
self.cCountData.setText("{:n}".format(nwItem.charCount))
self.wCountData.setText("{:n}".format(nwItem.wordCount))
self.pCountData.setText("{:n}".format(nwItem.paraCount))
else:
self.cCountData.setText("")
self.wCountData.setText("")
self.pCountData.setText("")
self.showHide.setArrowType(Qt.RightArrow)
return
# END Class GuiDocDetails
def _doSticky(self, chState):
"""Toggle the sticky feature of the references.
"""
if not chState and self.currHandle is not None:
self.refreshReferences(self.currHandle)
return
# END Class GuiDocViewDetails
+265
View File
@@ -0,0 +1,265 @@
# -*- coding: utf-8 -*-
"""novelWriter GUI Document Details
novelWriter GUI Document Details
====================================
Class holding the left side document details panel
File History:
Created: 2019-04-24 [0.0.1]
This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import logging
import nw
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QIcon, QPixmap
from PyQt5.QtWidgets import QFrame, QGridLayout, QLabel
from nw.constants import (
nwLabels, nwItemClass, nwItemType, nwItemLayout, nwUnicode
)
logger = logging.getLogger(__name__)
class GuiItemDetails(QFrame):
def __init__(self, theParent, theProject):
QFrame.__init__(self, theParent)
logger.debug("Initialising GuiItemDetails ...")
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theProject = theProject
self.theTheme = theParent.theTheme
self.theHandle = None
self.mainBox = QGridLayout(self)
self.mainBox.setVerticalSpacing(1)
self.mainBox.setHorizontalSpacing(6)
self.setLayout(self.mainBox)
self.pS = 0.9*self.theTheme.fontPointSize
self.iPx = self.theTheme.textIconSize
self.sPx = int(round(0.8*self.theTheme.textIconSize))
self.expCheck = self.theTheme.getPixmap("check", (self.iPx, self.iPx))
self.expCross = self.theTheme.getPixmap("cross", (self.iPx, self.iPx))
self.fntLabel = QFont()
self.fntLabel.setBold(True)
self.fntLabel.setPointSizeF(self.pS)
self.fntValue = QFont()
self.fntValue.setPointSizeF(self.pS)
# Label
self.labelName = QLabel("Label")
self.labelName.setFont(self.fntLabel)
self.labelName.setAlignment(Qt.AlignLeft | Qt.AlignBaseline)
self.labelFlag = QLabel("")
self.labelFlag.setAlignment(Qt.AlignRight | Qt.AlignBaseline)
self.labelData = QLabel("")
self.labelData.setFont(self.fntValue)
self.labelData.setAlignment(Qt.AlignLeft | Qt.AlignBaseline)
self.labelData.setWordWrap(True)
# Status
self.statusName = QLabel("Status")
self.statusName.setFont(self.fntLabel)
self.statusName.setAlignment(Qt.AlignLeft)
self.statusFlag = QLabel("")
self.statusFlag.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.statusData = QLabel("")
self.statusData.setFont(self.fntValue)
self.statusData.setAlignment(Qt.AlignLeft)
# Class
self.className = QLabel("Class")
self.className.setFont(self.fntLabel)
self.className.setAlignment(Qt.AlignLeft)
self.classFlag = QLabel("")
self.classFlag.setFont(self.fntValue)
self.classFlag.setAlignment(Qt.AlignRight)
self.classData = QLabel("")
self.classData.setFont(self.fntValue)
self.classData.setAlignment(Qt.AlignLeft)
# Layout
self.layoutName = QLabel("Layout")
self.layoutName.setFont(self.fntLabel)
self.layoutName.setAlignment(Qt.AlignLeft)
self.layoutFlag = QLabel("")
self.layoutFlag.setFont(self.fntValue)
self.layoutFlag.setAlignment(Qt.AlignRight)
self.layoutData = QLabel("")
self.layoutData.setFont(self.fntValue)
self.layoutData.setAlignment(Qt.AlignLeft)
# Character Count
self.cCountName = QLabel(" Characters")
self.cCountName.setFont(self.fntLabel)
self.cCountName.setAlignment(Qt.AlignRight)
self.cCountData = QLabel("")
self.cCountData.setFont(self.fntValue)
self.cCountData.setAlignment(Qt.AlignRight)
# Word Count
self.wCountName = QLabel(" Words")
self.wCountName.setFont(self.fntLabel)
self.wCountName.setAlignment(Qt.AlignRight)
self.wCountData = QLabel("")
self.wCountData.setFont(self.fntValue)
self.wCountData.setAlignment(Qt.AlignRight)
# Paragraph Count
self.pCountName = QLabel(" Paragraphs")
self.pCountName.setFont(self.fntLabel)
self.pCountName.setAlignment(Qt.AlignRight)
self.pCountData = QLabel("")
self.pCountData.setFont(self.fntValue)
self.pCountData.setAlignment(Qt.AlignRight)
# Assemble
self.mainBox.addWidget(self.labelName, 0, 0, 1, 1)
self.mainBox.addWidget(self.labelFlag, 0, 1, 1, 1)
self.mainBox.addWidget(self.labelData, 0, 2, 1, 3)
self.mainBox.addWidget(self.statusName, 1, 0, 1, 1)
self.mainBox.addWidget(self.statusFlag, 1, 1, 1, 1)
self.mainBox.addWidget(self.statusData, 1, 2, 1, 1)
self.mainBox.addWidget(self.cCountName, 1, 3, 1, 1)
self.mainBox.addWidget(self.cCountData, 1, 4, 1, 1)
self.mainBox.addWidget(self.className, 2, 0, 1, 1)
self.mainBox.addWidget(self.classFlag, 2, 1, 1, 1)
self.mainBox.addWidget(self.classData, 2, 2, 1, 1)
self.mainBox.addWidget(self.wCountName, 2, 3, 1, 1)
self.mainBox.addWidget(self.wCountData, 2, 4, 1, 1)
self.mainBox.addWidget(self.layoutName, 3, 0, 1, 1)
self.mainBox.addWidget(self.layoutFlag, 3, 1, 1, 1)
self.mainBox.addWidget(self.layoutData, 3, 2, 1, 1)
self.mainBox.addWidget(self.pCountName, 3, 3, 1, 1)
self.mainBox.addWidget(self.pCountData, 3, 4, 1, 1)
self.mainBox.setColumnStretch(0,0)
self.mainBox.setColumnStretch(1,0)
self.mainBox.setColumnStretch(2,1)
self.mainBox.setColumnStretch(3,0)
self.mainBox.setColumnStretch(4,0)
# Make sure the columns for flags and counts don't resize too often
flagWidth = self.theTheme.getTextWidth("Mm", self.fntValue)
countWidth = self.theTheme.getTextWidth("99,999", self.fntValue)
self.mainBox.setColumnMinimumWidth(1, flagWidth)
self.mainBox.setColumnMinimumWidth(4, countWidth)
logger.debug("GuiItemDetails initialisation complete")
return
###
# Class Methods
##
def updateCounts(self, tHandle, cC, wC, pC):
"""Just update the counts if the handle is the same as the one
we're already showing.
"""
if tHandle == self.theHandle:
self.cCountData.setText("{:n}".format(cC))
self.wCountData.setText("{:n}".format(wC))
self.pCountData.setText("{:n}".format(pC))
return
def updateViewBox(self, tHandle):
"""Populate the details box from a given handle.
"""
self.theHandle = tHandle
nwItem = self.theProject.projTree[tHandle]
if nwItem is None:
self.labelFlag.setText("")
self.labelData.setText("")
self.statusFlag.setText("")
self.statusData.setText("")
self.classFlag.setText("")
self.classData.setText("")
self.layoutFlag.setText("")
self.layoutData.setText("")
self.cCountData.setText("")
self.wCountData.setText("")
self.pCountData.setText("")
else:
theLabel = nwItem.itemName
if len(theLabel) > 100:
theLabel = theLabel[:96].rstrip()+" ..."
iStatus = nwItem.itemStatus
if nwItem.itemClass == nwItemClass.NOVEL:
iStatus = self.theProject.statusItems.checkEntry(iStatus) # Make sure it's valid
flagIcon = self.theParent.statusIcons[iStatus]
else:
iStatus = self.theProject.importItems.checkEntry(iStatus) # Make sure it's valid
flagIcon = self.theParent.importIcons[iStatus]
if nwItem.itemType == nwItemType.FILE:
if nwItem.isExported:
self.labelFlag.setPixmap(self.expCheck)
else:
self.labelFlag.setPixmap(self.expCross)
else:
self.labelFlag.setPixmap(QPixmap(1,1))
self.statusFlag.setPixmap(flagIcon.pixmap(self.sPx, self.sPx))
self.classFlag.setText(nwLabels.CLASS_FLAG[nwItem.itemClass])
if nwItem.itemLayout == nwItemLayout.NO_LAYOUT:
self.layoutFlag.setText("-")
else:
self.layoutFlag.setText(nwLabels.LAYOUT_FLAG[nwItem.itemLayout])
self.labelData.setText(theLabel)
self.statusData.setText(nwItem.itemStatus)
self.classData.setText(nwLabels.CLASS_NAME[nwItem.itemClass])
self.layoutData.setText(nwLabels.LAYOUT_NAME[nwItem.itemLayout])
if nwItem.itemType == nwItemType.FILE:
self.cCountData.setText("{:n}".format(nwItem.charCount))
self.wCountData.setText("{:n}".format(nwItem.wordCount))
self.pCountData.setText("{:n}".format(nwItem.paraCount))
else:
self.cCountData.setText("")
self.wCountData.setText("")
self.pCountData.setText("")
return
# END Class GuiItemDetails
+11 -8
View File
@@ -30,7 +30,7 @@ import nw
from time import time
from PyQt5.QtCore import Qt
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtWidgets import (
QTreeWidget, QTreeWidgetItem, QMenu, QAction, QAbstractItemView
)
@@ -43,7 +43,6 @@ class GuiProjectOutline(QTreeWidget):
DEF_WIDTH = {
nwOutline.TITLE : 200,
nwOutline.HANDLE : 0,
nwOutline.LEVEL : 40,
nwOutline.LABEL : 150,
nwOutline.LINE : 40,
@@ -63,7 +62,6 @@ class GuiProjectOutline(QTreeWidget):
DEF_HIDDEN = {
nwOutline.TITLE : False,
nwOutline.HANDLE : True,
nwOutline.LEVEL : True,
nwOutline.LABEL : False,
nwOutline.LINE : True,
@@ -103,6 +101,10 @@ class GuiProjectOutline(QTreeWidget):
self.setDragEnabled(False)
self.itemDoubleClicked.connect(self._treeDoubleClick)
iPx = self.theTheme.textIconSize
self.setIconSize(QSize(iPx, iPx))
self.setIndentation(iPx)
self.treeHead = self.header()
self.treeHead.setContextMenuPolicy(Qt.CustomContextMenu)
self.treeHead.customContextMenuRequested.connect(self._headerRightClick)
@@ -187,7 +189,7 @@ class GuiProjectOutline(QTreeWidget):
clicked, and send it to the main gui class for opening in the
document editor.
"""
tHandle = tItem.text(self.colIndex[nwOutline.HANDLE])
tHandle = tItem.data(self.colIndex[nwOutline.TITLE], Qt.UserRole)
try:
tLine = int(tItem.text(self.colIndex[nwOutline.LINE]))
except:
@@ -332,7 +334,6 @@ class GuiProjectOutline(QTreeWidget):
# Make sure title column is always visible,
# and handle column always hidden
self.setColumnHidden(self.colIndex[nwOutline.TITLE], False)
self.setColumnHidden(self.colIndex[nwOutline.HANDLE], True)
headItem = self.headerItem()
headItem.setTextAlignment(self.colIndex[nwOutline.CCOUNT], Qt.AlignRight)
@@ -408,9 +409,11 @@ class GuiProjectOutline(QTreeWidget):
newItem = QTreeWidgetItem()
newItem.setText(self.colIndex[nwOutline.TITLE], novIdx["title"])
newItem.setText(self.colIndex[nwOutline.HANDLE], tHandle)
newItem.setData(self.colIndex[nwOutline.TITLE], Qt.UserRole, tHandle)
newItem.setIcon(self.colIndex[nwOutline.TITLE], self.theTheme.getIcon("hash"))
newItem.setText(self.colIndex[nwOutline.LEVEL], novIdx["level"])
newItem.setText(self.colIndex[nwOutline.LABEL], nwItem.itemName)
newItem.setIcon(self.colIndex[nwOutline.LABEL], self.theTheme.getIcon("proj_document"))
newItem.setText(self.colIndex[nwOutline.LINE], sTitle[1:].lstrip("0"))
newItem.setText(self.colIndex[nwOutline.SYNOP], novIdx["synopsis"])
newItem.setText(self.colIndex[nwOutline.CCOUNT], str(novIdx["cCount"]))
@@ -451,7 +454,7 @@ class GuiOutlineHeaderMenu(QMenu):
self.actionMap = {}
for hItem in nwOutline:
if hItem == nwOutline.TITLE or hItem == nwOutline.HANDLE:
if hItem == nwOutline.TITLE:
continue
self.actionMap[hItem] = QAction(nwLabels.OUTLINE_COLS[hItem], self)
self.actionMap[hItem].setCheckable(True)
@@ -469,7 +472,7 @@ class GuiOutlineHeaderMenu(QMenu):
self.acceptToggle = False
for hItem in nwOutline:
if hItem == nwOutline.TITLE or hItem == nwOutline.HANDLE or hItem not in hiddenState:
if hItem == nwOutline.TITLE or hItem not in hiddenState:
continue
self.actionMap[hItem].setChecked(not hiddenState[hItem])
+42 -33
View File
@@ -31,7 +31,8 @@ import nw
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QFont, QColor, QIcon
from PyQt5.QtWidgets import (
qApp, QTreeWidget, QTreeWidgetItem, QAbstractItemView, QMessageBox
qApp, QTreeWidget, QTreeWidgetItem, QAbstractItemView, QMessageBox,
QHeaderView
)
from nw.core import NWDoc
@@ -41,18 +42,17 @@ from nw.constants import (
logger = logging.getLogger(__name__)
class GuiDocTree(QTreeWidget):
class GuiProjectTree(QTreeWidget):
C_NAME = 0
C_COUNT = 1
C_EXPORT = 2
C_FLAGS = 3
C_HANDLE = 4
def __init__(self, theParent, theProject):
QTreeWidget.__init__(self, theParent)
logger.debug("Initialising GuiDocTree ...")
logger.debug("Initialising GuiProjectTree ...")
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theTheme = theParent.theTheme
@@ -69,24 +69,30 @@ class GuiDocTree(QTreeWidget):
self.setIconSize(QSize(iPx, iPx))
self.setExpandsOnDoubleClick(True)
self.setIndentation(iPx)
self.setColumnCount(5)
self.setHeaderLabels(["Label", "Words", "Inc", "Flags", "Handle"])
self.hideColumn(self.C_HANDLE)
self.setColumnCount(4)
self.setHeaderLabels(["Label", "Words", "Inc", "Flags"])
treeHead = self.headerItem()
treeHead.setTextAlignment(self.C_COUNT, Qt.AlignRight)
treeHead.setToolTip(self.C_NAME, "Item label")
treeHead.setToolTip(self.C_COUNT, "Word count")
treeHead.setToolTip(self.C_EXPORT, "Include in build")
treeHead.setToolTip(self.C_FLAGS, "Status, class, and layout flags")
treeHeadItem = self.headerItem()
treeHeadItem.setTextAlignment(self.C_COUNT, Qt.AlignRight)
treeHeadItem.setToolTip(self.C_NAME, "Item label")
treeHeadItem.setToolTip(self.C_COUNT, "Word count")
treeHeadItem.setToolTip(self.C_EXPORT, "Include in build")
treeHeadItem.setToolTip(self.C_FLAGS, "Status, class, and layout flags")
# Force the font to fix font sizing issues on some platforms
# like Ubuntu. This must also be set when the rows are added.
self.setFont(self.theTheme.guiFont)
treeHead.setFont(self.C_NAME, self.theTheme.guiFont)
treeHead.setFont(self.C_COUNT,self.theTheme.guiFont)
treeHead.setFont(self.C_EXPORT, self.theTheme.guiFont)
treeHead.setFont(self.C_FLAGS, self.theTheme.guiFont)
treeHeadItem.setFont(self.C_NAME, self.theTheme.guiFont)
treeHeadItem.setFont(self.C_COUNT,self.theTheme.guiFont)
treeHeadItem.setFont(self.C_EXPORT, self.theTheme.guiFont)
treeHeadItem.setFont(self.C_FLAGS, self.theTheme.guiFont)
# Let the last column stretch, and set the minimum size to the
# size of the icon as the default Qt font metrics approach fails
# for some fonts like the Ubuntu font.
treeHeader = self.header()
treeHeader.setStretchLastSection(True)
treeHeader.setMinimumSectionSize(iPx+6)
# Allow Move by Drag & Drop
self.setDragEnabled(True)
@@ -102,13 +108,14 @@ class GuiDocTree(QTreeWidget):
# self.setSelectionBehavior(QAbstractItemView.SelectRows)
# Get user's column width preferences for NAME and COUNT
for colN, colW in enumerate(self.mainConf.treeColWidth):
self.setColumnWidth(colN, colW)
if len(self.mainConf.treeColWidth) <= 4:
for colN, colW in enumerate(self.mainConf.treeColWidth):
self.setColumnWidth(colN, colW)
self.resizeColumnToContents(self.C_EXPORT)
# The last column should just auto-scale
self.resizeColumnToContents(self.C_FLAGS)
logger.debug("GuiDocTree initialisation complete")
logger.debug("GuiProjectTree initialisation complete")
# Internal Mapping
self.makeAlert = self.theParent.makeAlert
@@ -286,6 +293,7 @@ class GuiDocTree(QTreeWidget):
retVals = [
self.columnWidth(0),
self.columnWidth(1),
self.columnWidth(2),
]
return retVals
@@ -479,7 +487,7 @@ class GuiDocTree(QTreeWidget):
pCount = 0
for i in range(pItem.childCount()):
pCount += int(pItem.child(i).text(self.C_COUNT))
pHandle = pItem.text(self.C_HANDLE)
pHandle = pItem.data(self.C_NAME, Qt.UserRole)
if not nDepth > 200 and pHandle != "":
self.propagateCount(pHandle, pCount, nDepth+1)
return
@@ -521,17 +529,17 @@ class GuiDocTree(QTreeWidget):
if len(selItem) == 0:
return None
if isinstance(selItem[0], QTreeWidgetItem):
return selItem[0].text(self.C_HANDLE)
return selItem[0].data(self.C_NAME, Qt.UserRole)
return None
def getSelectedHandles(self):
"""Return a list of all currently selected item handles.
"""
selItems = self.selectedItems()
selItems = self.selectedItems()
selHandles = []
for n in range(len(selItems)):
if isinstance(selItems[n], QTreeWidgetItem):
selHandles.append(selItems[n].text(self.C_HANDLE))
selHandles.append(selItems[n].data(self.C_NAME, Qt.UserRole))
return selHandles
def setSelectedHandle(self, tHandle):
@@ -563,8 +571,8 @@ class GuiDocTree(QTreeWidget):
"""This is a recursive function returning all items in a tree
starting at a given QTreeWidgetItem.
"""
tHandle = theItem.text(self.C_HANDLE)
nwItem = self.theProject.projTree[tHandle]
tHandle = theItem.data(self.C_NAME, Qt.UserRole)
nwItem = self.theProject.projTree[tHandle]
nwItem.setExpanded(theItem.isExpanded())
nwItem.setOrder(theIndex)
theList.append(tHandle)
@@ -585,7 +593,6 @@ class GuiDocTree(QTreeWidget):
newItem.setText(self.C_COUNT, "0")
newItem.setText(self.C_EXPORT, "")
newItem.setText(self.C_FLAGS, "")
newItem.setText(self.C_HANDLE, tHandle)
newItem.setTextAlignment(self.C_NAME, Qt.AlignLeft | Qt.AlignVCenter)
newItem.setTextAlignment(self.C_COUNT, Qt.AlignRight | Qt.AlignVCenter)
@@ -596,6 +603,8 @@ class GuiDocTree(QTreeWidget):
newItem.setFont(self.C_COUNT, self.theTheme.guiFont)
newItem.setFont(self.C_FLAGS, self.theTheme.guiFont)
newItem.setData(self.C_NAME, Qt.UserRole, tHandle)
self.theMap[tHandle] = newItem
if pHandle is None:
if nwItem.itemType == nwItemType.ROOT:
@@ -649,10 +658,10 @@ class GuiDocTree(QTreeWidget):
newItem.setText(self.C_COUNT, "")
newItem.setText(self.C_EXPORT, "")
newItem.setText(self.C_FLAGS, "")
newItem.setText(self.C_HANDLE, "")
self.addTopLevelItem(newItem)
self.orphRoot = newItem
newItem.setExpanded(True)
newItem.setData(self.C_NAME, "")
newItem.setIcon(self.C_NAME, self.theTheme.getIcon("warning"))
return
@@ -677,7 +686,7 @@ class GuiDocTree(QTreeWidget):
logger.error("Failed to find new parent item of %s" % tHandle)
return False
pHandle = trItemP.text(self.C_HANDLE)
pHandle = trItemP.data(self.C_NAME, Qt.UserRole)
wC = int(trItemS.text(self.C_COUNT))
self.propagateCount(tHandle, -wC)
nwItemS.setParent(pHandle)
@@ -702,7 +711,7 @@ class GuiDocTree(QTreeWidget):
if trItemP is None:
logger.error("Failed to find new parent item of %s" % tHandle)
return
pHandle = trItemP.text(self.C_HANDLE)
pHandle = trItemP.data(self.C_NAME, Qt.UserRole)
nwItemS.setParent(pHandle)
self.setTreeItemValues(tHandle)
self.theProject.setProjectChanged(True)
@@ -737,7 +746,7 @@ class GuiDocTree(QTreeWidget):
return
dItem = self.itemFromIndex(dIndex)
dHandle = dItem.text(self.C_HANDLE)
dHandle = dItem.data(self.C_NAME, Qt.UserRole)
snItem = self.theProject.projTree[sHandle]
dnItem = self.theProject.projTree[dHandle]
if dnItem is None:
@@ -773,4 +782,4 @@ class GuiDocTree(QTreeWidget):
return
# END Class GuiDocTree
# END Class GuiProjectTree
+1
View File
@@ -516,6 +516,7 @@ class GuiIcons:
"edit" : (None, None),
"check" : (None, None),
"cross" : (None, None),
"hash" : (None, None),
## Other Icons
"warning" : (QStyle.SP_MessageBoxWarning, "dialog-warning"),
-151
View File
@@ -1,151 +0,0 @@
# -*- coding: utf-8 -*-
"""novelWriter GUI DocView Details
novelWriter GUI DocView Details
===================================
Class holding the document view details panel
File History:
Created: 2019-10-31 [0.3.2]
This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import logging
import nw
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtWidgets import (
QWidget, QLabel, QScrollArea, QFrame, QToolButton, QCheckBox, QGridLayout
)
logger = logging.getLogger(__name__)
class GuiDocViewDetails(QWidget):
def __init__(self, theParent, theProject):
QWidget.__init__(self, theParent)
logger.debug("Initialising DocViewDetails ...")
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theProject = theProject
self.currHandle = None
self.outerBox = QGridLayout(self)
self.outerBox.setContentsMargins(0,0,0,0)
self.outerBox.setHorizontalSpacing(0)
self.outerBox.setVerticalSpacing(4)
self.refLabel = QLabel("Referenced By", self)
self.showHide = QToolButton()
self.showHide.setStyleSheet("QToolButton { border: none; }")
self.showHide.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.showHide.setArrowType(Qt.DownArrow)
self.showHide.setCheckable(True)
self.showHide.setIconSize(QSize(16,16))
self.showHide.toggled.connect(self._doShowHide)
self.isSticky = QCheckBox("Sticky")
self.isSticky.setChecked(False)
self.isSticky.toggled.connect(self._doSticky)
self.refList = QLabel("None")
self.refList.setWordWrap(True)
self.refList.setAlignment(Qt.AlignTop)
self.refList.setScaledContents(True)
self.refList.linkActivated.connect(self._linkClicked)
self.scrollBox = QScrollArea()
self.scrollBox.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scrollBox.setFrameStyle(QFrame.NoFrame)
self.scrollBox.setWidgetResizable(True)
self.scrollBox.setFixedHeight(80)
self.scrollBox.setWidget(self.refList)
self.outerBox.addWidget(self.showHide, 0, 0)
self.outerBox.addWidget(self.refLabel, 0, 1)
self.outerBox.addWidget(self.isSticky, 0, 2)
self.outerBox.addWidget(self.scrollBox, 1, 1, 1, 2)
self.outerBox.setColumnStretch(1, 1)
self.setLayout(self.outerBox)
self.setContentsMargins(0,0,0,0)
self._doShowHide(self.mainConf.showRefPanel)
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.isSticky.isChecked():
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</a>" % (
tHandle, theRefs[tHandle], tItem.itemName
))
self.refList.setText(", ".join(theList))
self.refList.adjustSize()
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
def _doShowHide(self, chState):
"""Toggle the expand/collapse of the panel.
"""
self.scrollBox.setVisible(chState)
self.mainConf.setShowRefPanel(chState)
if chState:
self.showHide.setArrowType(Qt.DownArrow)
else:
self.showHide.setArrowType(Qt.RightArrow)
return
def _doSticky(self, chState):
"""Toggle the sticky feature of the references.
"""
if not chState and self.currHandle is not None:
self.refreshReferences(self.currHandle)
return
# END Class GuiDocViewDetails
+11 -9
View File
@@ -40,8 +40,8 @@ from PyQt5.QtWidgets import (
)
from nw.gui import (
GuiMainMenu, GuiMainStatus, GuiTheme, GuiDocTree, GuiDocEditor,
GuiDocViewer, GuiDocDetails, GuiSearchBar, GuiNoticeBar, GuiDocViewDetails,
GuiMainMenu, GuiMainStatus, GuiTheme, GuiProjectTree, GuiDocEditor,
GuiDocViewer, GuiItemDetails, GuiSearchBar, GuiNoticeBar, GuiDocViewDetails,
GuiPreferences, GuiProjectSettings, GuiItemEditor, GuiProjectOutline,
GuiSessionLogView, GuiDocMerge, GuiDocSplit, GuiProjectLoad, GuiBuildNovel
)
@@ -91,12 +91,12 @@ class GuiMain(QMainWindow):
# Main GUI Elements
self.statusBar = GuiMainStatus(self)
self.noticeBar = GuiNoticeBar(self)
self.treeView = GuiDocTree(self, self.theProject)
self.treeView = GuiProjectTree(self, self.theProject)
self.docEditor = GuiDocEditor(self, self.theProject)
self.docViewer = GuiDocViewer(self, self.theProject)
self.viewMeta = GuiDocViewDetails(self, self.theProject)
self.searchBar = GuiSearchBar(self)
self.treeMeta = GuiDocDetails(self, self.theProject)
self.treeMeta = GuiItemDetails(self, self.theProject)
self.projView = GuiProjectOutline(self, self.theProject)
self.mainMenu = GuiMainMenu(self, self.theProject)
@@ -466,14 +466,15 @@ class GuiMain(QMainWindow):
self.docEditor.clearEditor()
return True
def openDocument(self, tHandle, tLine=None):
def openDocument(self, tHandle, tLine=None, changeFocus=True):
"""Open a specific document, optionally at a given line.
"""
if self.hasProject:
self.closeDocument()
self.tabWidget.setCurrentWidget(self.splitView)
if self.docEditor.loadText(tHandle, tLine):
self.docEditor.setFocus()
if changeFocus:
self.docEditor.setFocus()
self.theProject.setLastEdited(tHandle)
self.treeView.setSelectedHandle(tHandle)
else:
@@ -1022,7 +1023,7 @@ class GuiMain(QMainWindow):
"""The user double-clicked an item in the tree. If it is a file,
we open it. Otherwise, we do nothing.
"""
tHandle = tItem.text(self.treeView.C_HANDLE)
tHandle = tItem.data(self.treeView.C_NAME, Qt.UserRole)
logger.verbose("User double clicked tree item with handle %s" % tHandle)
nwItem = self.theProject.projTree[tHandle]
if nwItem is not None:
@@ -1035,7 +1036,8 @@ class GuiMain(QMainWindow):
def _treeKeyPressReturn(self):
"""The user pressed return an item in the tree. If it is a file,
we open it. Otherwise, we do nothing.
we open it. Otherwise, we do nothing. Pressing return does not
change focus to the editor as double click does.
"""
tHandle = self.treeView.getSelectedHandle()
logger.verbose("User pressed return on tree item with handle %s" % tHandle)
@@ -1043,7 +1045,7 @@ class GuiMain(QMainWindow):
if nwItem is not None:
if nwItem.itemType == nwItemType.FILE:
logger.verbose("Requested item %s is a file" % tHandle)
self.openDocument(tHandle)
self.openDocument(tHandle, changeFocus=False)
else:
logger.verbose("Requested item %s is a folder" % tHandle)
return
+1 -1
View File
@@ -485,7 +485,7 @@ def testBuildTool(qtbot, nwTempBuild, nwLipsum, nwRef, nwTemp):
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.ignoreFlag, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.excludeBody, Qt.LeftButton)
qtbot.mouseClick(nwBuild.includeBody, Qt.LeftButton)
qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.buildNovel, Qt.LeftButton)