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 debugLevel = logging.INFO
elif inOpt == "--debug": elif inOpt == "--debug":
debugLevel = logging.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": elif inOpt == "--logfile":
logFile = inArg logFile = inArg
toFile = True toFile = True
@@ -180,7 +180,7 @@ def main(sysArgs=None):
toStd = False toStd = False
elif inOpt == "--verbose": elif inOpt == "--verbose":
debugLevel = VERBOSE debugLevel = VERBOSE
logFormat = "[{asctime:}] {name:>30}:{lineno:<4d} {levelname:8} {message:}" logFormat = "[{asctime:}] {name:>20}:{lineno:<4d} {levelname:8} {message:}"
elif inOpt == "--style": elif inOpt == "--style":
qtStyle = inArg qtStyle = inArg
elif inOpt == "--config": elif inOpt == "--config":
@@ -196,7 +196,7 @@ def main(sysArgs=None):
CONFIG.cmdOpen = cmdOpen CONFIG.cmdOpen = cmdOpen
# Set Logging # 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 not logFile == "" and toFile:
if path.isfile(logFile+".bak"): 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 # Icons: Typicons Colour Dark
# Source: https://github.com/stephenhutchings/typicons.font # Source: https://github.com/stephenhutchings/typicons.font
# Credit: Stephen Hutchings # Credit: Stephen Hutchings
# Modified: Veronica Berglyd Olsen # Modified: Veronica Berglyd Olsen
# Additions: hash.svg
## ##
[Main] [Main]
@@ -39,3 +40,4 @@ save = download.svg
edit = pencil.svg edit = pencil.svg
check = tick.svg check = tick.svg
cross = times.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 # Icons: Typicons Colour Light
# Source: https://github.com/stephenhutchings/typicons.font # Source: https://github.com/stephenhutchings/typicons.font
# Credit: Stephen Hutchings # Credit: Stephen Hutchings
# Modified: Veronica Berglyd Olsen # Modified: Veronica Berglyd Olsen
# Additions: hash.svg
## ##
[Main] [Main]
@@ -39,3 +40,4 @@ save = download.svg
edit = pencil.svg edit = pencil.svg
check = tick.svg check = tick.svg
cross = times.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 # Icons: Typicons Grey Dark
# Source: https://github.com/stephenhutchings/typicons.font # Source: https://github.com/stephenhutchings/typicons.font
# Credit: Stephen Hutchings # Credit: Stephen Hutchings
# Modified: Veronica Berglyd Olsen
# Additions: hash.svg
## ##
[Main] [Main]
@@ -38,3 +40,4 @@ save = download.svg
edit = pencil.svg edit = pencil.svg
check = tick.svg check = tick.svg
cross = times.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 # Icons: Typicons Grey Light
# Source: https://github.com/stephenhutchings/typicons.font # Source: https://github.com/stephenhutchings/typicons.font
# Credit: Stephen Hutchings # Credit: Stephen Hutchings
# Modified: Veronica Berglyd Olsen
# Additions: hash.svg
## ##
[Main] [Main]
@@ -38,3 +40,4 @@ save = download.svg
edit = pencil.svg edit = pencil.svg
check = tick.svg check = tick.svg
cross = times.svg cross = times.svg
hash = hash.svg
-1
View File
@@ -136,7 +136,6 @@ class nwLabels():
} }
OUTLINE_COLS = { OUTLINE_COLS = {
nwOutline.TITLE : "Title", nwOutline.TITLE : "Title",
nwOutline.HANDLE : "Handle",
nwOutline.LEVEL : "Level", nwOutline.LEVEL : "Level",
nwOutline.LABEL : "Document", nwOutline.LABEL : "Document",
nwOutline.LINE : "Line", nwOutline.LINE : "Line",
+15 -16
View File
@@ -107,21 +107,20 @@ class nwAlert(Enum):
class nwOutline(Enum): class nwOutline(Enum):
TITLE = 0 TITLE = 0
HANDLE = 1 LEVEL = 1
LEVEL = 2 LABEL = 2
LABEL = 3 LINE = 3
LINE = 4 CCOUNT = 4
CCOUNT = 5 WCOUNT = 5
WCOUNT = 6 PCOUNT = 6
PCOUNT = 7 POV = 7
POV = 8 CHAR = 8
CHAR = 9 PLOT = 9
PLOT = 10 TIME = 10
TIME = 11 WORLD = 11
WORLD = 12 OBJECT = 12
OBJECT = 13 ENTITY = 13
ENTITY = 14 CUSTOM = 14
CUSTOM = 15 SYNOP = 15
SYNOP = 16
# END Enum nwOutline # 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 GuiDocTitleBar
from nw.gui.docbars import GuiNoticeBar from nw.gui.docbars import GuiNoticeBar
from nw.gui.docbars import GuiSearchBar 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.doceditor import GuiDocEditor
from nw.gui.docmerge import GuiDocMerge from nw.gui.docmerge import GuiDocMerge
from nw.gui.docsplit import GuiDocSplit from nw.gui.docsplit import GuiDocSplit
from nw.gui.doctree import GuiDocTree
from nw.gui.docviewer import GuiDocViewer from nw.gui.docviewer import GuiDocViewer
from nw.gui.itemdetails import GuiItemDetails
from nw.gui.itemeditor import GuiItemEditor from nw.gui.itemeditor import GuiItemEditor
from nw.gui.mainmenu import GuiMainMenu from nw.gui.mainmenu import GuiMainMenu
from nw.gui.outline import GuiProjectOutline from nw.gui.outline import GuiProjectOutline
from nw.gui.preferences import GuiPreferences from nw.gui.preferences import GuiPreferences
from nw.gui.projectload import GuiProjectLoad from nw.gui.projload import GuiProjectLoad
from nw.gui.projectsettings import GuiProjectSettings from nw.gui.projsettings import GuiProjectSettings
from nw.gui.projtree import GuiProjectTree
from nw.gui.sessionlog import GuiSessionLogView from nw.gui.sessionlog import GuiSessionLogView
from nw.gui.statusbar import GuiMainStatus from nw.gui.statusbar import GuiMainStatus
from nw.gui.theme import GuiIcons from nw.gui.theme import GuiIcons
from nw.gui.theme import GuiTheme from nw.gui.theme import GuiTheme
from nw.gui.viewdetails import GuiDocViewDetails
__all__ = [ __all__ = [
"GuiAbout", "GuiAbout",
@@ -29,21 +29,21 @@ __all__ = [
"GuiDocTitleBar", "GuiDocTitleBar",
"GuiNoticeBar", "GuiNoticeBar",
"GuiSearchBar", "GuiSearchBar",
"GuiDocDetails", "GuiDocViewDetails",
"GuiDocEditor", "GuiDocEditor",
"GuiDocMerge", "GuiDocMerge",
"GuiDocSplit", "GuiDocSplit",
"GuiDocTree",
"GuiDocViewer", "GuiDocViewer",
"GuiItemDetails",
"GuiItemEditor", "GuiItemEditor",
"GuiMainMenu", "GuiMainMenu",
"GuiProjectOutline", "GuiProjectOutline",
"GuiPreferences", "GuiPreferences",
"GuiProjectLoad", "GuiProjectLoad",
"GuiProjectSettings", "GuiProjectSettings",
"GuiProjectTree",
"GuiSessionLogView", "GuiSessionLogView",
"GuiMainStatus", "GuiMainStatus",
"GuiIcons", "GuiIcons",
"GuiTheme", "GuiTheme",
"GuiDocViewDetails",
] ]
+55 -55
View File
@@ -93,7 +93,7 @@ class GuiBuildNovel(QDialog):
# Title Formats # Title Formats
# ============= # =============
self.titleGroup = QGroupBox("Novel Title Formats", self) self.titleGroup = QGroupBox("Title Formats for Novel Files", self)
self.titleForm = QGridLayout(self) self.titleForm = QGridLayout(self)
self.titleGroup.setLayout(self.titleForm) self.titleGroup.setLayout(self.titleForm)
@@ -169,9 +169,9 @@ class GuiBuildNovel(QDialog):
# Text Options # Text Options
# ============= # =============
self.textGroup = QGroupBox("Text Options", self) self.formatGroup = QGroupBox("Formatting Options", self)
self.textForm = QGridLayout(self) self.formatForm = QGridLayout(self)
self.textGroup.setLayout(self.textForm) self.formatGroup.setLayout(self.formatForm)
## Font Family ## Font Family
self.textFont = QLineEdit() self.textFont = QLineEdit()
@@ -212,29 +212,29 @@ class GuiBuildNovel(QDialog):
self.optState.getBool("GuiBuildNovel", "noStyling", False) self.optState.getBool("GuiBuildNovel", "noStyling", False)
) )
self.textForm.addWidget(QLabel("Font family"), 0, 0, 1, 1, Qt.AlignLeft) self.formatForm.addWidget(QLabel("Font family"), 0, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.textFont, 0, 1, 1, 1, Qt.AlignRight) self.formatForm.addWidget(self.textFont, 0, 1, 1, 1, Qt.AlignRight)
self.textForm.addWidget(self.fontButton, 0, 2, 1, 1, Qt.AlignRight) self.formatForm.addWidget(self.fontButton, 0, 2, 1, 1, Qt.AlignRight)
self.textForm.addWidget(QLabel("Font size"), 1, 0, 1, 1, Qt.AlignLeft) self.formatForm.addWidget(QLabel("Font size"), 1, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.textSize, 1, 1, 1, 2, Qt.AlignRight) self.formatForm.addWidget(self.textSize, 1, 1, 1, 2, Qt.AlignRight)
self.textForm.addWidget(QLabel("Justify text"), 2, 0, 1, 1, Qt.AlignLeft) self.formatForm.addWidget(QLabel("Justify text"), 2, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.justifyText, 2, 1, 1, 2, Qt.AlignRight) self.formatForm.addWidget(self.justifyText, 2, 1, 1, 2, Qt.AlignRight)
self.textForm.addWidget(QLabel("Disable styling"), 3, 0, 1, 1, Qt.AlignLeft) self.formatForm.addWidget(QLabel("Disable styling"), 3, 0, 1, 1, Qt.AlignLeft)
self.textForm.addWidget(self.noStyling, 3, 1, 1, 2, Qt.AlignRight) self.formatForm.addWidget(self.noStyling, 3, 1, 1, 2, Qt.AlignRight)
self.textForm.setColumnStretch(0, 1) self.formatForm.setColumnStretch(0, 1)
self.textForm.setColumnStretch(1, 0) self.formatForm.setColumnStretch(1, 0)
self.textForm.setColumnStretch(2, 0) self.formatForm.setColumnStretch(2, 0)
# Include Switches # Include Switches
# ================ # ================
self.includeGroup = QGroupBox("Include Non-Text Elements", self) self.textGroup = QGroupBox("Text Options", self)
self.includeForm = QGridLayout(self) self.textForm = QGridLayout(self)
self.includeGroup.setLayout(self.includeForm) self.textGroup.setLayout(self.textForm)
self.includeSynopsis = QSwitch() self.includeSynopsis = QSwitch()
self.includeSynopsis.setToolTip( self.includeSynopsis.setToolTip(
"Include synopsis type comments in the output." "Include synopsis comments in the output."
) )
self.includeSynopsis.setChecked(self.theProject.titleFormat["withSynopsis"]) self.includeSynopsis.setChecked(self.theProject.titleFormat["withSynopsis"])
@@ -250,21 +250,31 @@ class GuiBuildNovel(QDialog):
) )
self.includeKeywords.setChecked(self.theProject.titleFormat["withKeywords"]) self.includeKeywords.setChecked(self.theProject.titleFormat["withKeywords"])
self.includeForm.addWidget(QLabel("Include synopsis"), 0, 0, 1, 1, Qt.AlignLeft) self.includeBody = QSwitch()
self.includeForm.addWidget(self.includeSynopsis, 0, 1, 1, 1, Qt.AlignRight) self.includeBody.setToolTip(
self.includeForm.addWidget(QLabel("Include comments"), 1, 0, 1, 1, Qt.AlignLeft) "Include body text in the output."
self.includeForm.addWidget(self.includeComments, 1, 1, 1, 1, Qt.AlignRight) )
self.includeForm.addWidget(QLabel("Include keywords"), 2, 0, 1, 1, Qt.AlignLeft) self.includeBody.setChecked(
self.includeForm.addWidget(self.includeKeywords, 2, 1, 1, 1, Qt.AlignRight) self.optState.getBool("GuiBuildNovel", "includeBody", True)
)
self.includeForm.setColumnStretch(0, 1) self.textForm.addWidget(QLabel("Include synopsis"), 0, 0, 1, 1, Qt.AlignLeft)
self.includeForm.setColumnStretch(1, 0) 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 # Additional Options
# ================== # ==================
self.addsGroup = QGroupBox("Additional Options", self) self.fileGroup = QGroupBox("File Options", self)
self.addsForm = QGridLayout(self) self.fileForm = QGridLayout(self)
self.addsGroup.setLayout(self.addsForm) self.fileGroup.setLayout(self.fileForm)
self.novelFiles = QSwitch() self.novelFiles = QSwitch()
self.novelFiles.setToolTip( self.novelFiles.setToolTip(
@@ -290,26 +300,15 @@ class GuiBuildNovel(QDialog):
self.optState.getBool("GuiBuildNovel", "ignoreFlag", False) self.optState.getBool("GuiBuildNovel", "ignoreFlag", False)
) )
self.excludeBody = QSwitch() self.fileForm.addWidget(QLabel("Include novel files"), 0, 0, 1, 1, Qt.AlignLeft)
self.excludeBody.setToolTip( self.fileForm.addWidget(self.novelFiles, 0, 1, 1, 1, Qt.AlignRight)
"Exclude body text in the output. Combine with 'Include synopsis' " self.fileForm.addWidget(QLabel("Include note files"), 1, 0, 1, 1, Qt.AlignLeft)
"for making outline." 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.excludeBody.setChecked( self.fileForm.addWidget(self.ignoreFlag, 2, 1, 1, 1, Qt.AlignRight)
self.optState.getBool("GuiBuildNovel", "excludeBody", False)
)
self.addsForm.addWidget(QLabel("Include novel files"), 0, 0, 1, 1, Qt.AlignLeft) self.fileForm.setColumnStretch(0, 1)
self.addsForm.addWidget(self.novelFiles, 0, 1, 1, 1, Qt.AlignRight) self.fileForm.setColumnStretch(1, 0)
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)
# Build Button # Build Button
# ============ # ============
@@ -373,9 +372,9 @@ class GuiBuildNovel(QDialog):
# Assemble GUI # Assemble GUI
# ============ # ============
self.toolsBox.addWidget(self.titleGroup) self.toolsBox.addWidget(self.titleGroup)
self.toolsBox.addWidget(self.formatGroup)
self.toolsBox.addWidget(self.textGroup) self.toolsBox.addWidget(self.textGroup)
self.toolsBox.addWidget(self.includeGroup) self.toolsBox.addWidget(self.fileGroup)
self.toolsBox.addWidget(self.addsGroup)
self.toolsBox.addStretch(1) self.toolsBox.addStretch(1)
self.toolsBox.addWidget(self.buildProgress) self.toolsBox.addWidget(self.buildProgress)
self.toolsBox.addWidget(self.buildNovel) self.toolsBox.addWidget(self.buildNovel)
@@ -388,6 +387,7 @@ class GuiBuildNovel(QDialog):
self.outerBox.setStretch(1, 1) self.outerBox.setStretch(1, 1)
self.setLayout(self.outerBox) self.setLayout(self.outerBox)
self.buildNovel.setFocus()
self.show() self.show()
@@ -436,7 +436,7 @@ class GuiBuildNovel(QDialog):
novelFiles = self.novelFiles.isChecked() novelFiles = self.novelFiles.isChecked()
noteFiles = self.noteFiles.isChecked() noteFiles = self.noteFiles.isChecked()
ignoreFlag = self.ignoreFlag.isChecked() ignoreFlag = self.ignoreFlag.isChecked()
excludeBody = self.excludeBody.isChecked() includeBody = self.includeBody.isChecked()
makeHtml = ToHtml(self.theProject, self.theParent) makeHtml = ToHtml(self.theProject, self.theParent)
makeHtml.setTitleFormat(fmtTitle) makeHtml.setTitleFormat(fmtTitle)
@@ -444,7 +444,7 @@ class GuiBuildNovel(QDialog):
makeHtml.setUnNumberedFormat(fmtUnnumbered) makeHtml.setUnNumberedFormat(fmtUnnumbered)
makeHtml.setSceneFormat(fmtScene, fmtScene == "") makeHtml.setSceneFormat(fmtScene, fmtScene == "")
makeHtml.setSectionFormat(fmtSection, fmtSection == "") makeHtml.setSectionFormat(fmtSection, fmtSection == "")
makeHtml.setBodyText(not excludeBody) makeHtml.setBodyText(includeBody)
makeHtml.setSynopsis(incSynopsis) makeHtml.setSynopsis(incSynopsis)
makeHtml.setComments(incComments) makeHtml.setComments(incComments)
makeHtml.setKeywords(incKeywords) makeHtml.setKeywords(incKeywords)
@@ -867,7 +867,7 @@ class GuiBuildNovel(QDialog):
self.optState.setValue("GuiBuildNovel", "addNovel", self.novelFiles.isChecked()) self.optState.setValue("GuiBuildNovel", "addNovel", self.novelFiles.isChecked())
self.optState.setValue("GuiBuildNovel", "addNotes", self.noteFiles.isChecked()) self.optState.setValue("GuiBuildNovel", "addNotes", self.noteFiles.isChecked())
self.optState.setValue("GuiBuildNovel", "ignoreFlag", self.ignoreFlag.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() self.optState.saveSettings()
return return
+94 -208
View File
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""novelWriter GUI Document Details """novelWriter GUI DocView Details
novelWriter GUI Document Details novelWriter GUI DocView Details
==================================== ===================================
Class holding the left side document details panel Class holding the document view details panel
File History: File History:
Created: 2019-04-24 [0.0.1] Created: 2019-10-31 [0.3.2]
This file is a part of novelWriter This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen Copyright 2020, Veronica Berglyd Olsen
@@ -28,238 +28,124 @@
import logging import logging
import nw import nw
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QFont, QIcon, QPixmap from PyQt5.QtWidgets import (
from PyQt5.QtWidgets import QFrame, QGridLayout, QLabel QWidget, QLabel, QScrollArea, QFrame, QToolButton, QCheckBox, QGridLayout
from nw.constants import (
nwLabels, nwItemClass, nwItemType, nwItemLayout, nwUnicode
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class GuiDocDetails(QFrame): class GuiDocViewDetails(QWidget):
def __init__(self, theParent, theProject): 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.mainConf = nw.CONFIG
self.theParent = theParent self.theParent = theParent
self.theProject = theProject self.theProject = theProject
self.theTheme = theParent.theTheme self.currHandle = None
self.theHandle = None
self.mainBox = QGridLayout(self) self.outerBox = QGridLayout(self)
self.mainBox.setVerticalSpacing(1) self.outerBox.setContentsMargins(0,0,0,0)
self.mainBox.setHorizontalSpacing(6) self.outerBox.setHorizontalSpacing(0)
self.setLayout(self.mainBox) self.outerBox.setVerticalSpacing(4)
self.pS = 0.9*self.theTheme.fontPointSize self.refLabel = QLabel("Referenced By", self)
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.showHide = QToolButton()
self.expCross = self.theTheme.getPixmap("cross", (self.iPx, self.iPx)) 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.isSticky = QCheckBox("Sticky")
self.fntLabel.setBold(True) self.isSticky.setChecked(False)
self.fntLabel.setPointSizeF(self.pS) self.isSticky.toggled.connect(self._doSticky)
self.fntValue = QFont() self.refList = QLabel("None")
self.fntValue.setPointSizeF(self.pS) self.refList.setWordWrap(True)
self.refList.setAlignment(Qt.AlignTop)
self.refList.setScaledContents(True)
self.refList.linkActivated.connect(self._linkClicked)
# Label self.scrollBox = QScrollArea()
self.labelName = QLabel("Label") self.scrollBox.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.labelName.setFont(self.fntLabel) self.scrollBox.setFrameStyle(QFrame.NoFrame)
self.labelName.setAlignment(Qt.AlignLeft | Qt.AlignBaseline) self.scrollBox.setWidgetResizable(True)
self.scrollBox.setFixedHeight(80)
self.scrollBox.setWidget(self.refList)
self.labelFlag = QLabel("") self.outerBox.addWidget(self.showHide, 0, 0)
self.labelFlag.setAlignment(Qt.AlignRight | Qt.AlignBaseline) 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.setLayout(self.outerBox)
self.labelData.setFont(self.fntValue) self.setContentsMargins(0,0,0,0)
self.labelData.setAlignment(Qt.AlignLeft | Qt.AlignBaseline)
self.labelData.setWordWrap(True)
# Status self._doShowHide(self.mainConf.showRefPanel)
self.statusName = QLabel("Status")
self.statusName.setFont(self.fntLabel)
self.statusName.setAlignment(Qt.AlignLeft)
self.statusFlag = QLabel("") logger.debug("DocViewDetails initialisation complete")
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")
return return
### def refreshReferences(self, tHandle):
# Class Methods """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): def _linkClicked(self, theLink):
"""Just update the counts if the handle is the same as the one """Capture the link-click and forward it to the document viewer
we're already showing. class for handling.
""" """
if tHandle == self.theHandle: logger.verbose("Clicked link: '%s'" % theLink)
self.cCountData.setText("{:n}".format(cC)) if len(theLink) == 27:
self.wCountData.setText("{:n}".format(wC)) tHandle = theLink[6:19]
self.pCountData.setText("{:n}".format(pC)) self.theParent.viewDocument(tHandle, theLink)
return return
def updateViewBox(self, tHandle): def _doShowHide(self, chState):
"""Populate the details box from a given handle. """Toggle the expand/collapse of the panel.
""" """
self.theHandle = tHandle self.scrollBox.setVisible(chState)
nwItem = self.theProject.projTree[tHandle] self.mainConf.setShowRefPanel(chState)
if chState:
if nwItem is None: self.showHide.setArrowType(Qt.DownArrow)
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: else:
theLabel = nwItem.itemName self.showHide.setArrowType(Qt.RightArrow)
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 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 time import time
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt, QSize
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QTreeWidget, QTreeWidgetItem, QMenu, QAction, QAbstractItemView QTreeWidget, QTreeWidgetItem, QMenu, QAction, QAbstractItemView
) )
@@ -43,7 +43,6 @@ class GuiProjectOutline(QTreeWidget):
DEF_WIDTH = { DEF_WIDTH = {
nwOutline.TITLE : 200, nwOutline.TITLE : 200,
nwOutline.HANDLE : 0,
nwOutline.LEVEL : 40, nwOutline.LEVEL : 40,
nwOutline.LABEL : 150, nwOutline.LABEL : 150,
nwOutline.LINE : 40, nwOutline.LINE : 40,
@@ -63,7 +62,6 @@ class GuiProjectOutline(QTreeWidget):
DEF_HIDDEN = { DEF_HIDDEN = {
nwOutline.TITLE : False, nwOutline.TITLE : False,
nwOutline.HANDLE : True,
nwOutline.LEVEL : True, nwOutline.LEVEL : True,
nwOutline.LABEL : False, nwOutline.LABEL : False,
nwOutline.LINE : True, nwOutline.LINE : True,
@@ -103,6 +101,10 @@ class GuiProjectOutline(QTreeWidget):
self.setDragEnabled(False) self.setDragEnabled(False)
self.itemDoubleClicked.connect(self._treeDoubleClick) self.itemDoubleClicked.connect(self._treeDoubleClick)
iPx = self.theTheme.textIconSize
self.setIconSize(QSize(iPx, iPx))
self.setIndentation(iPx)
self.treeHead = self.header() self.treeHead = self.header()
self.treeHead.setContextMenuPolicy(Qt.CustomContextMenu) self.treeHead.setContextMenuPolicy(Qt.CustomContextMenu)
self.treeHead.customContextMenuRequested.connect(self._headerRightClick) 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 clicked, and send it to the main gui class for opening in the
document editor. document editor.
""" """
tHandle = tItem.text(self.colIndex[nwOutline.HANDLE]) tHandle = tItem.data(self.colIndex[nwOutline.TITLE], Qt.UserRole)
try: try:
tLine = int(tItem.text(self.colIndex[nwOutline.LINE])) tLine = int(tItem.text(self.colIndex[nwOutline.LINE]))
except: except:
@@ -332,7 +334,6 @@ class GuiProjectOutline(QTreeWidget):
# Make sure title column is always visible, # Make sure title column is always visible,
# and handle column always hidden # and handle column always hidden
self.setColumnHidden(self.colIndex[nwOutline.TITLE], False) self.setColumnHidden(self.colIndex[nwOutline.TITLE], False)
self.setColumnHidden(self.colIndex[nwOutline.HANDLE], True)
headItem = self.headerItem() headItem = self.headerItem()
headItem.setTextAlignment(self.colIndex[nwOutline.CCOUNT], Qt.AlignRight) headItem.setTextAlignment(self.colIndex[nwOutline.CCOUNT], Qt.AlignRight)
@@ -408,9 +409,11 @@ class GuiProjectOutline(QTreeWidget):
newItem = QTreeWidgetItem() newItem = QTreeWidgetItem()
newItem.setText(self.colIndex[nwOutline.TITLE], novIdx["title"]) 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.LEVEL], novIdx["level"])
newItem.setText(self.colIndex[nwOutline.LABEL], nwItem.itemName) 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.LINE], sTitle[1:].lstrip("0"))
newItem.setText(self.colIndex[nwOutline.SYNOP], novIdx["synopsis"]) newItem.setText(self.colIndex[nwOutline.SYNOP], novIdx["synopsis"])
newItem.setText(self.colIndex[nwOutline.CCOUNT], str(novIdx["cCount"])) newItem.setText(self.colIndex[nwOutline.CCOUNT], str(novIdx["cCount"]))
@@ -451,7 +454,7 @@ class GuiOutlineHeaderMenu(QMenu):
self.actionMap = {} self.actionMap = {}
for hItem in nwOutline: for hItem in nwOutline:
if hItem == nwOutline.TITLE or hItem == nwOutline.HANDLE: if hItem == nwOutline.TITLE:
continue continue
self.actionMap[hItem] = QAction(nwLabels.OUTLINE_COLS[hItem], self) self.actionMap[hItem] = QAction(nwLabels.OUTLINE_COLS[hItem], self)
self.actionMap[hItem].setCheckable(True) self.actionMap[hItem].setCheckable(True)
@@ -469,7 +472,7 @@ class GuiOutlineHeaderMenu(QMenu):
self.acceptToggle = False self.acceptToggle = False
for hItem in nwOutline: 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 continue
self.actionMap[hItem].setChecked(not hiddenState[hItem]) 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.QtCore import Qt, QSize
from PyQt5.QtGui import QFont, QColor, QIcon from PyQt5.QtGui import QFont, QColor, QIcon
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
qApp, QTreeWidget, QTreeWidgetItem, QAbstractItemView, QMessageBox qApp, QTreeWidget, QTreeWidgetItem, QAbstractItemView, QMessageBox,
QHeaderView
) )
from nw.core import NWDoc from nw.core import NWDoc
@@ -41,18 +42,17 @@ from nw.constants import (
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class GuiDocTree(QTreeWidget): class GuiProjectTree(QTreeWidget):
C_NAME = 0 C_NAME = 0
C_COUNT = 1 C_COUNT = 1
C_EXPORT = 2 C_EXPORT = 2
C_FLAGS = 3 C_FLAGS = 3
C_HANDLE = 4
def __init__(self, theParent, theProject): def __init__(self, theParent, theProject):
QTreeWidget.__init__(self, theParent) QTreeWidget.__init__(self, theParent)
logger.debug("Initialising GuiDocTree ...") logger.debug("Initialising GuiProjectTree ...")
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.theParent = theParent self.theParent = theParent
self.theTheme = theParent.theTheme self.theTheme = theParent.theTheme
@@ -69,24 +69,30 @@ class GuiDocTree(QTreeWidget):
self.setIconSize(QSize(iPx, iPx)) self.setIconSize(QSize(iPx, iPx))
self.setExpandsOnDoubleClick(True) self.setExpandsOnDoubleClick(True)
self.setIndentation(iPx) self.setIndentation(iPx)
self.setColumnCount(5) self.setColumnCount(4)
self.setHeaderLabels(["Label", "Words", "Inc", "Flags", "Handle"]) self.setHeaderLabels(["Label", "Words", "Inc", "Flags"])
self.hideColumn(self.C_HANDLE)
treeHead = self.headerItem() treeHeadItem = self.headerItem()
treeHead.setTextAlignment(self.C_COUNT, Qt.AlignRight) treeHeadItem.setTextAlignment(self.C_COUNT, Qt.AlignRight)
treeHead.setToolTip(self.C_NAME, "Item label") treeHeadItem.setToolTip(self.C_NAME, "Item label")
treeHead.setToolTip(self.C_COUNT, "Word count") treeHeadItem.setToolTip(self.C_COUNT, "Word count")
treeHead.setToolTip(self.C_EXPORT, "Include in build") treeHeadItem.setToolTip(self.C_EXPORT, "Include in build")
treeHead.setToolTip(self.C_FLAGS, "Status, class, and layout flags") treeHeadItem.setToolTip(self.C_FLAGS, "Status, class, and layout flags")
# Force the font to fix font sizing issues on some platforms # Force the font to fix font sizing issues on some platforms
# like Ubuntu. This must also be set when the rows are added. # like Ubuntu. This must also be set when the rows are added.
self.setFont(self.theTheme.guiFont) self.setFont(self.theTheme.guiFont)
treeHead.setFont(self.C_NAME, self.theTheme.guiFont) treeHeadItem.setFont(self.C_NAME, self.theTheme.guiFont)
treeHead.setFont(self.C_COUNT,self.theTheme.guiFont) treeHeadItem.setFont(self.C_COUNT,self.theTheme.guiFont)
treeHead.setFont(self.C_EXPORT, self.theTheme.guiFont) treeHeadItem.setFont(self.C_EXPORT, self.theTheme.guiFont)
treeHead.setFont(self.C_FLAGS, 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 # Allow Move by Drag & Drop
self.setDragEnabled(True) self.setDragEnabled(True)
@@ -102,13 +108,14 @@ class GuiDocTree(QTreeWidget):
# self.setSelectionBehavior(QAbstractItemView.SelectRows) # self.setSelectionBehavior(QAbstractItemView.SelectRows)
# Get user's column width preferences for NAME and COUNT # Get user's column width preferences for NAME and COUNT
for colN, colW in enumerate(self.mainConf.treeColWidth): if len(self.mainConf.treeColWidth) <= 4:
self.setColumnWidth(colN, colW) 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) self.resizeColumnToContents(self.C_FLAGS)
logger.debug("GuiDocTree initialisation complete") logger.debug("GuiProjectTree initialisation complete")
# Internal Mapping # Internal Mapping
self.makeAlert = self.theParent.makeAlert self.makeAlert = self.theParent.makeAlert
@@ -286,6 +293,7 @@ class GuiDocTree(QTreeWidget):
retVals = [ retVals = [
self.columnWidth(0), self.columnWidth(0),
self.columnWidth(1), self.columnWidth(1),
self.columnWidth(2),
] ]
return retVals return retVals
@@ -479,7 +487,7 @@ class GuiDocTree(QTreeWidget):
pCount = 0 pCount = 0
for i in range(pItem.childCount()): for i in range(pItem.childCount()):
pCount += int(pItem.child(i).text(self.C_COUNT)) 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 != "": if not nDepth > 200 and pHandle != "":
self.propagateCount(pHandle, pCount, nDepth+1) self.propagateCount(pHandle, pCount, nDepth+1)
return return
@@ -521,17 +529,17 @@ class GuiDocTree(QTreeWidget):
if len(selItem) == 0: if len(selItem) == 0:
return None return None
if isinstance(selItem[0], QTreeWidgetItem): if isinstance(selItem[0], QTreeWidgetItem):
return selItem[0].text(self.C_HANDLE) return selItem[0].data(self.C_NAME, Qt.UserRole)
return None return None
def getSelectedHandles(self): def getSelectedHandles(self):
"""Return a list of all currently selected item handles. """Return a list of all currently selected item handles.
""" """
selItems = self.selectedItems() selItems = self.selectedItems()
selHandles = [] selHandles = []
for n in range(len(selItems)): for n in range(len(selItems)):
if isinstance(selItems[n], QTreeWidgetItem): 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 return selHandles
def setSelectedHandle(self, tHandle): def setSelectedHandle(self, tHandle):
@@ -563,8 +571,8 @@ class GuiDocTree(QTreeWidget):
"""This is a recursive function returning all items in a tree """This is a recursive function returning all items in a tree
starting at a given QTreeWidgetItem. starting at a given QTreeWidgetItem.
""" """
tHandle = theItem.text(self.C_HANDLE) tHandle = theItem.data(self.C_NAME, Qt.UserRole)
nwItem = self.theProject.projTree[tHandle] nwItem = self.theProject.projTree[tHandle]
nwItem.setExpanded(theItem.isExpanded()) nwItem.setExpanded(theItem.isExpanded())
nwItem.setOrder(theIndex) nwItem.setOrder(theIndex)
theList.append(tHandle) theList.append(tHandle)
@@ -585,7 +593,6 @@ class GuiDocTree(QTreeWidget):
newItem.setText(self.C_COUNT, "0") newItem.setText(self.C_COUNT, "0")
newItem.setText(self.C_EXPORT, "") newItem.setText(self.C_EXPORT, "")
newItem.setText(self.C_FLAGS, "") newItem.setText(self.C_FLAGS, "")
newItem.setText(self.C_HANDLE, tHandle)
newItem.setTextAlignment(self.C_NAME, Qt.AlignLeft | Qt.AlignVCenter) newItem.setTextAlignment(self.C_NAME, Qt.AlignLeft | Qt.AlignVCenter)
newItem.setTextAlignment(self.C_COUNT, Qt.AlignRight | 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_COUNT, self.theTheme.guiFont)
newItem.setFont(self.C_FLAGS, self.theTheme.guiFont) newItem.setFont(self.C_FLAGS, self.theTheme.guiFont)
newItem.setData(self.C_NAME, Qt.UserRole, tHandle)
self.theMap[tHandle] = newItem self.theMap[tHandle] = newItem
if pHandle is None: if pHandle is None:
if nwItem.itemType == nwItemType.ROOT: if nwItem.itemType == nwItemType.ROOT:
@@ -649,10 +658,10 @@ class GuiDocTree(QTreeWidget):
newItem.setText(self.C_COUNT, "") newItem.setText(self.C_COUNT, "")
newItem.setText(self.C_EXPORT, "") newItem.setText(self.C_EXPORT, "")
newItem.setText(self.C_FLAGS, "") newItem.setText(self.C_FLAGS, "")
newItem.setText(self.C_HANDLE, "")
self.addTopLevelItem(newItem) self.addTopLevelItem(newItem)
self.orphRoot = newItem self.orphRoot = newItem
newItem.setExpanded(True) newItem.setExpanded(True)
newItem.setData(self.C_NAME, "")
newItem.setIcon(self.C_NAME, self.theTheme.getIcon("warning")) newItem.setIcon(self.C_NAME, self.theTheme.getIcon("warning"))
return return
@@ -677,7 +686,7 @@ class GuiDocTree(QTreeWidget):
logger.error("Failed to find new parent item of %s" % tHandle) logger.error("Failed to find new parent item of %s" % tHandle)
return False return False
pHandle = trItemP.text(self.C_HANDLE) pHandle = trItemP.data(self.C_NAME, Qt.UserRole)
wC = int(trItemS.text(self.C_COUNT)) wC = int(trItemS.text(self.C_COUNT))
self.propagateCount(tHandle, -wC) self.propagateCount(tHandle, -wC)
nwItemS.setParent(pHandle) nwItemS.setParent(pHandle)
@@ -702,7 +711,7 @@ class GuiDocTree(QTreeWidget):
if trItemP is None: if trItemP is None:
logger.error("Failed to find new parent item of %s" % tHandle) logger.error("Failed to find new parent item of %s" % tHandle)
return return
pHandle = trItemP.text(self.C_HANDLE) pHandle = trItemP.data(self.C_NAME, Qt.UserRole)
nwItemS.setParent(pHandle) nwItemS.setParent(pHandle)
self.setTreeItemValues(tHandle) self.setTreeItemValues(tHandle)
self.theProject.setProjectChanged(True) self.theProject.setProjectChanged(True)
@@ -737,7 +746,7 @@ class GuiDocTree(QTreeWidget):
return return
dItem = self.itemFromIndex(dIndex) dItem = self.itemFromIndex(dIndex)
dHandle = dItem.text(self.C_HANDLE) dHandle = dItem.data(self.C_NAME, Qt.UserRole)
snItem = self.theProject.projTree[sHandle] snItem = self.theProject.projTree[sHandle]
dnItem = self.theProject.projTree[dHandle] dnItem = self.theProject.projTree[dHandle]
if dnItem is None: if dnItem is None:
@@ -773,4 +782,4 @@ class GuiDocTree(QTreeWidget):
return return
# END Class GuiDocTree # END Class GuiProjectTree
+1
View File
@@ -516,6 +516,7 @@ class GuiIcons:
"edit" : (None, None), "edit" : (None, None),
"check" : (None, None), "check" : (None, None),
"cross" : (None, None), "cross" : (None, None),
"hash" : (None, None),
## Other Icons ## Other Icons
"warning" : (QStyle.SP_MessageBoxWarning, "dialog-warning"), "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 ( from nw.gui import (
GuiMainMenu, GuiMainStatus, GuiTheme, GuiDocTree, GuiDocEditor, GuiMainMenu, GuiMainStatus, GuiTheme, GuiProjectTree, GuiDocEditor,
GuiDocViewer, GuiDocDetails, GuiSearchBar, GuiNoticeBar, GuiDocViewDetails, GuiDocViewer, GuiItemDetails, GuiSearchBar, GuiNoticeBar, GuiDocViewDetails,
GuiPreferences, GuiProjectSettings, GuiItemEditor, GuiProjectOutline, GuiPreferences, GuiProjectSettings, GuiItemEditor, GuiProjectOutline,
GuiSessionLogView, GuiDocMerge, GuiDocSplit, GuiProjectLoad, GuiBuildNovel GuiSessionLogView, GuiDocMerge, GuiDocSplit, GuiProjectLoad, GuiBuildNovel
) )
@@ -91,12 +91,12 @@ class GuiMain(QMainWindow):
# Main GUI Elements # Main GUI Elements
self.statusBar = GuiMainStatus(self) self.statusBar = GuiMainStatus(self)
self.noticeBar = GuiNoticeBar(self) self.noticeBar = GuiNoticeBar(self)
self.treeView = GuiDocTree(self, self.theProject) self.treeView = GuiProjectTree(self, self.theProject)
self.docEditor = GuiDocEditor(self, self.theProject) self.docEditor = GuiDocEditor(self, self.theProject)
self.docViewer = GuiDocViewer(self, self.theProject) self.docViewer = GuiDocViewer(self, self.theProject)
self.viewMeta = GuiDocViewDetails(self, self.theProject) self.viewMeta = GuiDocViewDetails(self, self.theProject)
self.searchBar = GuiSearchBar(self) self.searchBar = GuiSearchBar(self)
self.treeMeta = GuiDocDetails(self, self.theProject) self.treeMeta = GuiItemDetails(self, self.theProject)
self.projView = GuiProjectOutline(self, self.theProject) self.projView = GuiProjectOutline(self, self.theProject)
self.mainMenu = GuiMainMenu(self, self.theProject) self.mainMenu = GuiMainMenu(self, self.theProject)
@@ -466,14 +466,15 @@ class GuiMain(QMainWindow):
self.docEditor.clearEditor() self.docEditor.clearEditor()
return True 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. """Open a specific document, optionally at a given line.
""" """
if self.hasProject: if self.hasProject:
self.closeDocument() self.closeDocument()
self.tabWidget.setCurrentWidget(self.splitView) self.tabWidget.setCurrentWidget(self.splitView)
if self.docEditor.loadText(tHandle, tLine): if self.docEditor.loadText(tHandle, tLine):
self.docEditor.setFocus() if changeFocus:
self.docEditor.setFocus()
self.theProject.setLastEdited(tHandle) self.theProject.setLastEdited(tHandle)
self.treeView.setSelectedHandle(tHandle) self.treeView.setSelectedHandle(tHandle)
else: else:
@@ -1022,7 +1023,7 @@ class GuiMain(QMainWindow):
"""The user double-clicked an item in the tree. If it is a file, """The user double-clicked an item in the tree. If it is a file,
we open it. Otherwise, we do nothing. 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) logger.verbose("User double clicked tree item with handle %s" % tHandle)
nwItem = self.theProject.projTree[tHandle] nwItem = self.theProject.projTree[tHandle]
if nwItem is not None: if nwItem is not None:
@@ -1035,7 +1036,8 @@ class GuiMain(QMainWindow):
def _treeKeyPressReturn(self): def _treeKeyPressReturn(self):
"""The user pressed return an item in the tree. If it is a file, """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() tHandle = self.treeView.getSelectedHandle()
logger.verbose("User pressed return on tree item with handle %s" % tHandle) 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 is not None:
if nwItem.itemType == nwItemType.FILE: if nwItem.itemType == nwItemType.FILE:
logger.verbose("Requested item %s is a file" % tHandle) logger.verbose("Requested item %s is a file" % tHandle)
self.openDocument(tHandle) self.openDocument(tHandle, changeFocus=False)
else: else:
logger.verbose("Requested item %s is a folder" % tHandle) logger.verbose("Requested item %s is a folder" % tHandle)
return return
+1 -1
View File
@@ -485,7 +485,7 @@ def testBuildTool(qtbot, nwTempBuild, nwLipsum, nwRef, nwTemp):
qtbot.wait(stepDelay) qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.ignoreFlag, Qt.LeftButton) qtbot.mouseClick(nwBuild.ignoreFlag, Qt.LeftButton)
qtbot.wait(stepDelay) qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.excludeBody, Qt.LeftButton) qtbot.mouseClick(nwBuild.includeBody, Qt.LeftButton)
qtbot.wait(stepDelay) qtbot.wait(stepDelay)
qtbot.mouseClick(nwBuild.buildNovel, Qt.LeftButton) qtbot.mouseClick(nwBuild.buildNovel, Qt.LeftButton)