Merge pull request #314 from vkbo/update_search_replace
Update Search Replace
@@ -18,7 +18,7 @@ install:
|
||||
- pip install --upgrade pip
|
||||
- pip install -r requirements.txt
|
||||
# - pip install pytest-faulthandler
|
||||
- pip install PyVirtualDisplay==0.2.5
|
||||
- pip install PyVirtualDisplay
|
||||
- pip install pytest-xvfb
|
||||
- pip install pytest-cov
|
||||
- pip install pytest-qt
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.2"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
id="svg7731">
|
||||
<metadata
|
||||
id="metadata7737">
|
||||
<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="defs7735" />
|
||||
<path
|
||||
d="m 20.121169,3.8786433 c -1.170024,-1.1715244 -3.072064,-1.1715244 -4.242088,0 L 12,7.7577241 8.1209195,3.8786433 c -1.1700247,-1.1715244 -3.0720643,-1.1715244 -4.2420887,0 -1.1715244,1.1715244 -1.1715244,3.070564 0,4.2420884 l 3.8775807,3.8790803 -3.8775807,3.879081 c -1.1715244,1.171525 -1.1715244,3.070564 0,4.242089 C 4.463843,20.707494 5.231859,21 5.999875,21 6.767891,21 7.5359065,20.707494 8.1209195,20.120982 L 12,16.241901 15.879081,20.120982 C 16.464093,20.707494 17.232109,21 18.000125,21 c 0.768015,0 1.536031,-0.292506 2.121044,-0.879018 1.171525,-1.171525 1.171525,-3.070564 0,-4.242089 l -3.87758,-3.879081 3.87758,-3.8790803 c 1.171525,-1.1715244 1.171525,-3.070564 0,-4.2420884 z"
|
||||
id="path7729"
|
||||
style="stroke-width:1.50003123;fill:#aeaeae;fill-opacity:1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg7731"
|
||||
viewBox="0 0 24 24"
|
||||
height="24"
|
||||
width="24"
|
||||
version="1.2">
|
||||
<metadata
|
||||
id="metadata7737">
|
||||
<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="defs7735" />
|
||||
<path
|
||||
style="stroke-width:1.50003123;fill:#000000;fill-opacity:0.78039217"
|
||||
id="path7729"
|
||||
d="m 20.121169,3.8786433 c -1.170024,-1.1715244 -3.072064,-1.1715244 -4.242088,0 L 12,7.7577241 8.1209195,3.8786433 c -1.1700247,-1.1715244 -3.0720643,-1.1715244 -4.2420887,0 -1.1715244,1.1715244 -1.1715244,3.070564 0,4.2420884 l 3.8775807,3.8790803 -3.8775807,3.879081 c -1.1715244,1.171525 -1.1715244,3.070564 0,4.242089 C 4.463843,20.707494 5.231859,21 5.999875,21 6.767891,21 7.5359065,20.707494 8.1209195,20.120982 L 12,16.241901 15.879081,20.120982 C 16.464093,20.707494 17.232109,21 18.000125,21 c 0.768015,0 1.536031,-0.292506 2.121044,-0.879018 1.171525,-1.171525 1.171525,-3.070564 0,-4.242089 l -3.87758,-3.879081 3.87758,-3.8790803 c 1.171525,-1.1715244 1.171525,-3.070564 0,-4.2420884 z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,49 @@
|
||||
<?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"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 6.3499999 6.3500002"
|
||||
version="1.1"
|
||||
id="svg8">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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>
|
||||
<g
|
||||
style="fill:#aeaeae;fill-opacity:1"
|
||||
id="layer1"
|
||||
transform="translate(0,-290.64999)">
|
||||
<g
|
||||
aria-label="Aa"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;letter-spacing:0px;word-spacing:0px;fill:#aeaeae;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
id="text817">
|
||||
<g
|
||||
id="g968"
|
||||
style="fill:#aeaeae;fill-opacity:1">
|
||||
<path
|
||||
id="path961"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#aeaeae;fill-opacity:1;stroke-width:0.264583"
|
||||
d="M 0.35983601,295.49539 H 1.0364638 l 0.2815167,-0.85936 H 2.631725 l 0.2815166,0.85936 H 3.6195028 L 2.4292305,292.0678 H 1.6143138 Z m 1.14582229,-1.42734 0.4741333,-1.45203 0.4691945,1.45203 z" />
|
||||
<path
|
||||
id="path963"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#aeaeae;fill-opacity:1;stroke-width:0.264583"
|
||||
d="m 4.701114,295.54478 c 0.3062111,0 0.5679722,-0.10372 0.7507111,-0.29139 l 0.0889,0.242 H 5.990164 v -1.44215 c 0,-0.65194 -0.3704167,-1.00754 -1.0766778,-1.00754 -0.3457222,0 -0.7112,0.084 -0.9927167,0.23213 l 0.1481667,0.43956 c 0.2469444,-0.0988 0.48895,-0.14816 0.7112,-0.14816 0.3852334,0 0.5926667,0.14816 0.5926667,0.43462 v 0.0642 c -1.0421056,0.0148 -1.5014223,0.25189 -1.5014223,0.76059 0,0.43462 0.3259667,0.71614 0.8297334,0.71614 z m -0.1975556,-0.8001 c 0,-0.21731 0.2518834,-0.31609 0.8692445,-0.32597 v 0.45438 c -0.1185333,0.1136 -0.2815167,0.1778 -0.4642556,0.1778 -0.2420055,0 -0.4049889,-0.12347 -0.4049889,-0.30621 z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 6.3499999 6.3500002"
|
||||
height="24"
|
||||
width="24">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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>
|
||||
<g
|
||||
transform="translate(0,-290.64999)"
|
||||
id="layer1">
|
||||
<g
|
||||
id="text817"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444494px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458335"
|
||||
aria-label="Aa">
|
||||
<g
|
||||
style="fill:#000000;fill-opacity:0.78039217"
|
||||
id="g968">
|
||||
<path
|
||||
d="M 0.35983601,295.49539 H 1.0364638 l 0.2815167,-0.85936 H 2.631725 l 0.2815166,0.85936 H 3.6195028 L 2.4292305,292.0678 H 1.6143138 Z m 1.14582229,-1.42734 0.4741333,-1.45203 0.4691945,1.45203 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93888903px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458335;fill:#000000;fill-opacity:0.78039217"
|
||||
id="path961" />
|
||||
<path
|
||||
d="m 4.701114,295.54478 c 0.3062111,0 0.5679722,-0.10372 0.7507111,-0.29139 l 0.0889,0.242 H 5.990164 v -1.44215 c 0,-0.65194 -0.3704167,-1.00754 -1.0766778,-1.00754 -0.3457222,0 -0.7112,0.084 -0.9927167,0.23213 l 0.1481667,0.43956 c 0.2469444,-0.0988 0.48895,-0.14816 0.7112,-0.14816 0.3852334,0 0.5926667,0.14816 0.5926667,0.43462 v 0.0642 c -1.0421056,0.0148 -1.5014223,0.25189 -1.5014223,0.76059 0,0.43462 0.3259667,0.71614 0.8297334,0.71614 z m -0.1975556,-0.8001 c 0,-0.21731 0.2518834,-0.31609 0.8692445,-0.32597 v 0.45438 c -0.1185333,0.1136 -0.2815167,0.1778 -0.4642556,0.1778 -0.2420055,0 -0.4049889,-0.12347 -0.4049889,-0.30621 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93888903px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458335;fill:#000000;fill-opacity:0.78039217"
|
||||
id="path963" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.2"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
id="svg2150">
|
||||
<metadata
|
||||
id="metadata2156">
|
||||
<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="defs2154" />
|
||||
<path
|
||||
d="m 17,6.4445834 h -2.317778 l 1.436667,-1.4366667 c 0.434444,-0.4344445 0.434444,-1.1366667 0,-1.5711111 -0.434445,-0.4344445 -1.136667,-0.4344445 -1.571111,0 l -4.118889,4.1188889 4.118889,4.1188895 c 0.216666,0.216666 0.501111,0.325555 0.785555,0.325555 0.284445,0 0.568889,-0.108889 0.785556,-0.325555 0.434444,-0.434445 0.434444,-1.136667 0,-1.571112 L 14.682222,8.6668056 H 17 c 1.532222,0 2.777778,1.4955554 2.777778,3.3333334 0,1.837778 -1.495556,3.333333 -3.333334,3.333333 -0.614444,0 -1.111111,0.497778 -1.111111,1.111112 0,0.613333 0.496667,1.111111 1.111111,1.111111 C 19.507778,17.555695 22,15.063472 22,12.000139 22,8.9368056 19.756667,6.4445834 17,6.4445834 Z M 7.8811111,12.325695 c -0.4344444,0.434444 -0.4344444,1.136666 0,1.571111 L 9.317778,15.333472 H 7 c -1.5322222,0 -2.7777778,-1.495555 -2.7777778,-3.333333 0,-1.837778 1.4955556,-3.3333334 3.3333334,-3.3333334 0.6144444,0 1.1111111,-0.4977778 1.1111111,-1.1111111 C 8.6666667,6.9423611 8.17,6.4445834 7.5555556,6.4445834 4.4922222,6.4445834 2,8.9368056 2,12.000139 c 0,3.063333 2.2433333,5.555556 5,5.555556 h 2.317778 l -1.4366669,1.436666 c -0.4344444,0.434445 -0.4344444,1.136667 0,1.571111 0.2166667,0.216667 0.5011111,0.325556 0.7855556,0.325556 0.2844444,0 0.5688893,-0.108889 0.7855553,-0.325556 l 4.118889,-4.118888 -4.118889,-4.118889 c -0.434444,-0.434445 -1.1366664,-0.434445 -1.5711109,0 z"
|
||||
id="path2148"
|
||||
style="stroke-width:1.11111116;fill:#aeaeae;fill-opacity:1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg2150"
|
||||
viewBox="0 0 24 24"
|
||||
height="24"
|
||||
width="24"
|
||||
version="1.2">
|
||||
<metadata
|
||||
id="metadata2156">
|
||||
<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="defs2154" />
|
||||
<path
|
||||
style="stroke-width:1.11111116;fill:#000000;fill-opacity:0.78039217"
|
||||
id="path2148"
|
||||
d="m 17,6.4445834 h -2.317778 l 1.436667,-1.4366667 c 0.434444,-0.4344445 0.434444,-1.1366667 0,-1.5711111 -0.434445,-0.4344445 -1.136667,-0.4344445 -1.571111,0 l -4.118889,4.1188889 4.118889,4.1188895 c 0.216666,0.216666 0.501111,0.325555 0.785555,0.325555 0.284445,0 0.568889,-0.108889 0.785556,-0.325555 0.434444,-0.434445 0.434444,-1.136667 0,-1.571112 L 14.682222,8.6668056 H 17 c 1.532222,0 2.777778,1.4955554 2.777778,3.3333334 0,1.837778 -1.495556,3.333333 -3.333334,3.333333 -0.614444,0 -1.111111,0.497778 -1.111111,1.111112 0,0.613333 0.496667,1.111111 1.111111,1.111111 C 19.507778,17.555695 22,15.063472 22,12.000139 22,8.9368056 19.756667,6.4445834 17,6.4445834 Z M 7.8811111,12.325695 c -0.4344444,0.434444 -0.4344444,1.136666 0,1.571111 L 9.317778,15.333472 H 7 c -1.5322222,0 -2.7777778,-1.495555 -2.7777778,-3.333333 0,-1.837778 1.4955556,-3.3333334 3.3333334,-3.3333334 0.6144444,0 1.1111111,-0.4977778 1.1111111,-1.1111111 C 8.6666667,6.9423611 8.17,6.4445834 7.5555556,6.4445834 4.4922222,6.4445834 2,8.9368056 2,12.000139 c 0,3.063333 2.2433333,5.555556 5,5.555556 h 2.317778 l -1.4366669,1.436666 c -0.4344444,0.434445 -0.4344444,1.136667 0,1.571111 0.2166667,0.216667 0.5011111,0.325556 0.7855556,0.325556 0.2844444,0 0.5688893,-0.108889 0.7855553,-0.325556 l 4.118889,-4.118888 -4.118889,-4.118889 c -0.434444,-0.434445 -1.1366664,-0.434445 -1.5711109,0 z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 6.3499999 6.3500002"
|
||||
height="24"
|
||||
width="24">
|
||||
<g
|
||||
style="font-size:5.64444px;line-height:1.25;font-family:'Fira Sans';-inkscape-font-specification:'Fira Sans, Normal';letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
id="text1549"
|
||||
aria-label="AB">
|
||||
<path
|
||||
id="path1551"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.251875;fill:#aeaeae;fill-opacity:1"
|
||||
d="M 0.52916667,4.8827979 H 1.1423606 L 1.397485,4.023431 H 2.588066 L 2.8431905,4.8827979 H 3.4832396 L 2.4045554,1.4552083 H 1.6660372 Z M 1.5675681,3.4554587 1.9972514,2.003425 2.4224589,3.4554587 Z" />
|
||||
<path
|
||||
id="path1553"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.25188;fill:#aeaeae;fill-opacity:1"
|
||||
d="m 3.4395834,4.8827979 h 1.1592928 c 0.7519737,0 1.2219572,-0.4099279 1.2219572,-1.0618613 0,-0.4296835 -0.2058975,-0.7408335 -0.5639802,-0.8840614 0.1969454,-0.1432278 0.3177984,-0.3951112 0.3177984,-0.6667501 0,-0.5284612 -0.389415,-0.8149168 -1.1055804,-0.8149168 H 3.4395834 Z M 4.0125157,1.9688528 h 0.4117952 c 0.3625587,0 0.5639802,0.1679223 0.5639802,0.4642557 0,0.1778 -0.076092,0.3160889 -0.2506578,0.4247445 H 4.0125157 Z m 0,2.4003005 V 3.3566809 h 0.6714051 c 0.3357025,0 0.5416002,0.2173112 0.5416002,0.5482168 0,0.3160889 -0.1745654,0.4642556 -0.5505523,0.4642556 z" />
|
||||
</g>
|
||||
<defs
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 6.3499999 6.3500002"
|
||||
height="24"
|
||||
width="24">
|
||||
<g
|
||||
style="font-size:5.64444px;line-height:1.25;font-family:'Fira Sans';-inkscape-font-specification:'Fira Sans, Normal';letter-spacing:0px;word-spacing:0px;stroke-width:0.264583"
|
||||
id="text1549"
|
||||
aria-label="AB">
|
||||
<path
|
||||
id="path1551"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.251875;fill:#000000;fill-opacity:0.78039217"
|
||||
d="M 0.52916667,4.8827979 H 1.1423606 L 1.397485,4.023431 H 2.588066 L 2.8431905,4.8827979 H 3.4832396 L 2.4045554,1.4552083 H 1.6660372 Z M 1.5675681,3.4554587 1.9972514,2.003425 2.4224589,3.4554587 Z" />
|
||||
<path
|
||||
id="path1553"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.25188;fill:#000000;fill-opacity:0.78039217"
|
||||
d="m 3.4395834,4.8827979 h 1.1592928 c 0.7519737,0 1.2219572,-0.4099279 1.2219572,-1.0618613 0,-0.4296835 -0.2058975,-0.7408335 -0.5639802,-0.8840614 0.1969454,-0.1432278 0.3177984,-0.3951112 0.3177984,-0.6667501 0,-0.5284612 -0.389415,-0.8149168 -1.1055804,-0.8149168 H 3.4395834 Z M 4.0125157,1.9688528 h 0.4117952 c 0.3625587,0 0.5639802,0.1679223 0.5639802,0.4642557 0,0.1778 -0.076092,0.3160889 -0.2506578,0.4247445 H 4.0125157 Z m 0,2.4003005 V 3.3566809 h 0.6714051 c 0.3357025,0 0.5416002,0.2173112 0.5416002,0.5482168 0,0.3160889 -0.1745654,0.4642556 -0.5505523,0.4642556 z" />
|
||||
</g>
|
||||
<defs
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg8301"
|
||||
viewBox="0 0 24 24"
|
||||
height="24"
|
||||
width="24"
|
||||
version="1.2">
|
||||
<metadata
|
||||
id="metadata8307">
|
||||
<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="defs8305" />
|
||||
<path
|
||||
style="stroke-width:1.18357;fill:#aeaeae;fill-opacity:1"
|
||||
id="path8299"
|
||||
d="m 19.591431,11.061428 c -0.92437,-0.92437 -2.422771,-0.92437 -3.347141,0 l -1.877146,1.877144 V 4.367144 C 14.367144,3.059297 13.306664,2 12,2 10.692153,2 9.6328557,3.059297 9.6328557,4.367144 v 8.571428 l -1.877145,-1.877144 c -0.9243698,-0.92437 -2.4227719,-0.92437 -3.3471417,0 -0.9243697,0.924369 -0.9243697,2.422771 0,3.347141 L 12,22 19.591431,14.408569 c 0.92437,-0.92437 0.92437,-2.421588 0,-3.347141 z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg8301"
|
||||
viewBox="0 0 24 24"
|
||||
height="24"
|
||||
width="24"
|
||||
version="1.2">
|
||||
<metadata
|
||||
id="metadata8307">
|
||||
<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="defs8305" />
|
||||
<path
|
||||
style="stroke-width:1.18357;fill:#000000;fill-opacity:0.77999997"
|
||||
id="path8299"
|
||||
d="m 19.591431,11.061428 c -0.92437,-0.92437 -2.422771,-0.92437 -3.347141,0 l -1.877146,1.877144 V 4.367144 C 14.367144,3.059297 13.306664,2 12,2 10.692153,2 9.6328557,3.059297 9.6328557,4.367144 v 8.571428 l -1.877145,-1.877144 c -0.9243698,-0.92437 -2.4227719,-0.92437 -3.3471417,0 -0.9243697,0.924369 -0.9243697,2.422771 0,3.347141 L 12,22 19.591431,14.408569 c 0.92437,-0.92437 0.92437,-2.421588 0,-3.347141 z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,49 @@
|
||||
<?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"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 6.3499999 6.3500002"
|
||||
version="1.1"
|
||||
id="svg8">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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>
|
||||
<g
|
||||
style="fill:#aeaeae;fill-opacity:1"
|
||||
id="layer1"
|
||||
transform="translate(0,-290.64999)">
|
||||
<g
|
||||
aria-label=".*"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;letter-spacing:0px;word-spacing:0px;fill:#aeaeae;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
id="text817">
|
||||
<g
|
||||
id="g1606"
|
||||
style="fill:#aeaeae;fill-opacity:1">
|
||||
<path
|
||||
id="path1599"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#aeaeae;fill-opacity:1;stroke-width:0.264583"
|
||||
d="m 1.9550981,295.54478 c 0.2518833,0 0.4198055,-0.18274 0.4198055,-0.4198 0,-0.25189 -0.1679222,-0.43463 -0.4198055,-0.43463 -0.2568223,0 -0.4247445,0.18274 -0.4247445,0.43463 0,0.23706 0.1679222,0.4198 0.4247445,0.4198 z" />
|
||||
<path
|
||||
id="path1601"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93889px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#aeaeae;fill-opacity:1;stroke-width:0.264583"
|
||||
d="m 3.5108408,294.12732 h 0.5482167 l -0.1234722,-0.77541 0.6124222,0.49883 0.2568223,-0.43956 -0.7655278,-0.32103 0.7803444,-0.29139 -0.2518833,-0.43956 -0.6371167,0.48401 0.1284111,-0.8001 H 3.5108408 l 0.1382889,0.79516 -0.6223,-0.50377 -0.2518833,0.43956 0.7704667,0.31609 -0.7754056,0.30621 0.2469444,0.4445 0.6321778,-0.50376 z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 6.3499999 6.3500002"
|
||||
height="24"
|
||||
width="24">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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>
|
||||
<g
|
||||
transform="translate(0,-290.64999)"
|
||||
id="layer1">
|
||||
<g
|
||||
id="text817"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444494px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458335"
|
||||
aria-label=".*">
|
||||
<g
|
||||
style="fill:#000000;fill-opacity:0.78039217"
|
||||
id="g1606">
|
||||
<path
|
||||
d="m 1.9550981,295.54478 c 0.2518833,0 0.4198055,-0.18274 0.4198055,-0.4198 0,-0.25189 -0.1679222,-0.43463 -0.4198055,-0.43463 -0.2568223,0 -0.4247445,0.18274 -0.4247445,0.43463 0,0.23706 0.1679222,0.4198 0.4247445,0.4198 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93888903px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458335;fill:#000000;fill-opacity:0.78039217"
|
||||
id="path1599" />
|
||||
<path
|
||||
d="m 3.5108408,294.12732 h 0.5482167 l -0.1234722,-0.77541 0.6124222,0.49883 0.2568223,-0.43956 -0.7655278,-0.32103 0.7803444,-0.29139 -0.2518833,-0.43956 -0.6371167,0.48401 0.1284111,-0.8001 H 3.5108408 l 0.1382889,0.79516 -0.6223,-0.50377 -0.2518833,0.43956 0.7704667,0.31609 -0.7754056,0.30621 0.2469444,0.4445 0.6321778,-0.50376 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.93888903px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458335;fill:#000000;fill-opacity:0.78039217"
|
||||
id="path1601" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 6.3499999 6.3500002"
|
||||
height="24"
|
||||
width="24">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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>
|
||||
<g
|
||||
transform="translate(0,-290.64999)"
|
||||
id="layer1">
|
||||
<g
|
||||
id="text817"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
aria-label=".*">
|
||||
<g
|
||||
style="fill:#000000;fill-opacity:0.780392"
|
||||
id="g1606">
|
||||
<path
|
||||
id="rect1629"
|
||||
transform="matrix(0.26458334,0,0,0.26458334,0,290.64999)"
|
||||
d="m 2,11.5 v 4 1 2 h 20 v -3 -4 h -3 v 4 H 5 v -4 z"
|
||||
style="fill:#aeaeae;fill-opacity:1;stroke:none;stroke-width:1.76363;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 6.3499999 6.3500002"
|
||||
height="24"
|
||||
width="24">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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>
|
||||
<g
|
||||
transform="translate(0,-290.64999)"
|
||||
id="layer1">
|
||||
<g
|
||||
id="text817"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.64444px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
aria-label=".*">
|
||||
<g
|
||||
style="fill:#000000;fill-opacity:0.780392"
|
||||
id="g1606">
|
||||
<path
|
||||
id="rect1629"
|
||||
transform="matrix(0.26458334,0,0,0.26458334,0,290.64999)"
|
||||
d="m 2,11.5 v 4 1 2 h 20 v -3 -4 h -3 v 4 H 5 v -4 z"
|
||||
style="fill:#000000;fill-opacity:0.780392;stroke:none;stroke-width:1.76363;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -172,3 +172,24 @@ def splitVersionNumber(vString):
|
||||
vInt = vMajor*10000 + vMinor*100 + vPatch
|
||||
|
||||
return [vMajor, vMinor, vPatch, vInt]
|
||||
|
||||
def transferCase(theSource, theTarget):
|
||||
"""Transfers the case of the source word to the target word. This
|
||||
will consider all upper or lower, and first char capitalisation.
|
||||
"""
|
||||
theResult = theTarget
|
||||
|
||||
if not isinstance(theSource, str) or not isinstance(theTarget, str):
|
||||
return theResult
|
||||
if len(theTarget) < 1 or len(theSource) < 1:
|
||||
return theResult
|
||||
|
||||
if theSource[0] == theSource[0].upper():
|
||||
theResult = theTarget[0].upper() + theTarget[1:]
|
||||
|
||||
if theSource == theSource.upper():
|
||||
theResult = theTarget.upper()
|
||||
elif theSource == theSource.lower():
|
||||
theResult = theTarget.lower()
|
||||
|
||||
return theResult
|
||||
|
||||
@@ -133,6 +133,13 @@ class Config:
|
||||
self.spellTool = None
|
||||
self.spellLanguage = None
|
||||
|
||||
self.searchCase = False
|
||||
self.searchWord = False
|
||||
self.searchRegEx = False
|
||||
self.searchLoop = False
|
||||
self.searchNextFile = False
|
||||
self.searchMatchCap = False
|
||||
|
||||
## Backup
|
||||
self.backupPath = ""
|
||||
self.backupOnClose = False
|
||||
@@ -482,6 +489,24 @@ class Config:
|
||||
self.viewSynopsis = self._parseLine(
|
||||
cnfParse, cnfSec, "viewsynopsis", self.CNF_BOOL, self.viewSynopsis
|
||||
)
|
||||
self.searchCase = self._parseLine(
|
||||
cnfParse, cnfSec, "searchcase", self.CNF_BOOL, self.searchCase
|
||||
)
|
||||
self.searchWord = self._parseLine(
|
||||
cnfParse, cnfSec, "searchword", self.CNF_BOOL, self.searchWord
|
||||
)
|
||||
self.searchRegEx = self._parseLine(
|
||||
cnfParse, cnfSec, "searchregex", self.CNF_BOOL, self.searchRegEx
|
||||
)
|
||||
self.searchLoop = self._parseLine(
|
||||
cnfParse, cnfSec, "searchloop", self.CNF_BOOL, self.searchLoop
|
||||
)
|
||||
self.searchNextFile = self._parseLine(
|
||||
cnfParse, cnfSec, "searchnextfile", self.CNF_BOOL, self.searchNextFile
|
||||
)
|
||||
self.searchMatchCap = self._parseLine(
|
||||
cnfParse, cnfSec, "searchmatchcap", self.CNF_BOOL, self.searchMatchCap
|
||||
)
|
||||
|
||||
## Path
|
||||
cnfSec = "Path"
|
||||
@@ -571,9 +596,15 @@ class Config:
|
||||
## State
|
||||
cnfSec = "State"
|
||||
cnfParse.add_section(cnfSec)
|
||||
cnfParse.set(cnfSec,"showrefpanel",str(self.showRefPanel))
|
||||
cnfParse.set(cnfSec,"viewcomments",str(self.viewComments))
|
||||
cnfParse.set(cnfSec,"viewsynopsis",str(self.viewSynopsis))
|
||||
cnfParse.set(cnfSec,"showrefpanel", str(self.showRefPanel))
|
||||
cnfParse.set(cnfSec,"viewcomments", str(self.viewComments))
|
||||
cnfParse.set(cnfSec,"viewsynopsis", str(self.viewSynopsis))
|
||||
cnfParse.set(cnfSec,"searchcase", str(self.searchCase))
|
||||
cnfParse.set(cnfSec,"searchword", str(self.searchWord))
|
||||
cnfParse.set(cnfSec,"searchregex", str(self.searchRegEx))
|
||||
cnfParse.set(cnfSec,"searchloop", str(self.searchLoop))
|
||||
cnfParse.set(cnfSec,"searchnextfile", str(self.searchNextFile))
|
||||
cnfParse.set(cnfSec,"searchmatchcap", str(self.searchMatchCap))
|
||||
|
||||
## Path
|
||||
cnfSec = "Path"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from nw.gui.about import GuiAbout
|
||||
from nw.gui.build import GuiBuildNovel
|
||||
from nw.gui.docbars import GuiSearchBar
|
||||
from nw.gui.doceditor import GuiDocEditor
|
||||
from nw.gui.docmerge import GuiDocMerge
|
||||
from nw.gui.docsplit import GuiDocSplit
|
||||
@@ -23,7 +22,6 @@ from nw.gui.theme import GuiIcons, GuiTheme
|
||||
__all__ = [
|
||||
"GuiAbout",
|
||||
"GuiBuildNovel",
|
||||
"GuiSearchBar",
|
||||
"GuiDocEditor",
|
||||
"GuiDocMerge",
|
||||
"GuiDocSplit",
|
||||
|
||||
@@ -459,7 +459,7 @@ class GuiBuildNovel(QDialog):
|
||||
makeHtml.setStyles(not noStyling)
|
||||
|
||||
# Make sure the tree order is correct
|
||||
self.theParent.treeView.saveTreeOrder()
|
||||
self.theParent.treeView.flushTreeOrder()
|
||||
|
||||
self.buildProgress.setMaximum(len(self.theProject.projTree))
|
||||
self.buildProgress.setValue(0)
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""novelWriter GUI Main Window SearchBar
|
||||
|
||||
novelWriter – GUI Main Window SearchBar
|
||||
=========================================
|
||||
Class holding the main window search bar
|
||||
|
||||
File History:
|
||||
Created: 2019-09-29 [0.2.1] GuiSearchBar
|
||||
|
||||
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.QtGui import QPalette, QColor, QIcon
|
||||
from PyQt5.QtWidgets import (
|
||||
qApp, QWidget, QFrame, QGridLayout, QLabel, QLineEdit, QPushButton,
|
||||
QHBoxLayout, QToolButton, QScrollArea
|
||||
)
|
||||
|
||||
from nw.constants import nwDocAction, nwUnicode
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class GuiSearchBar(QWidget):
|
||||
|
||||
def __init__(self, theParent):
|
||||
QWidget.__init__(self, theParent)
|
||||
|
||||
logger.debug("Initialising GuiSearchBar ...")
|
||||
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theParent = theParent
|
||||
self.theTheme = theParent.theTheme
|
||||
self.repVisible = False
|
||||
|
||||
self.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.mainBox = QGridLayout(self)
|
||||
self.setLayout(self.mainBox)
|
||||
|
||||
self.searchBox = QLineEdit()
|
||||
self.replaceBox = QLineEdit()
|
||||
self.searchLabel = QLabel("Search")
|
||||
self.replaceLabel = QLabel("Replace")
|
||||
self.closeButton = QPushButton(self.theTheme.getIcon("close"),"")
|
||||
self.searchButton = QPushButton(self.theTheme.getIcon("search"),"")
|
||||
self.replaceButton = QPushButton(self.theTheme.getIcon("search-replace"),"")
|
||||
|
||||
self.closeButton.clicked.connect(self._doClose)
|
||||
self.searchButton.clicked.connect(self._doSearch)
|
||||
self.replaceButton.clicked.connect(self._doReplace)
|
||||
self.searchBox.returnPressed.connect(self._doSearch)
|
||||
self.replaceBox.returnPressed.connect(self._doSearch)
|
||||
|
||||
self.mainBox.addWidget(QLabel(""), 0, 0)
|
||||
self.mainBox.addWidget(self.searchLabel, 0, 1)
|
||||
self.mainBox.addWidget(self.searchBox, 0, 2)
|
||||
self.mainBox.addWidget(self.searchButton, 0, 3)
|
||||
self.mainBox.addWidget(self.closeButton, 0, 4)
|
||||
self.mainBox.addWidget(self.replaceLabel, 1, 1)
|
||||
self.mainBox.addWidget(self.replaceBox, 1, 2)
|
||||
self.mainBox.addWidget(self.replaceButton, 1, 3)
|
||||
|
||||
self.mainBox.setColumnStretch(0, 1)
|
||||
self.mainBox.setColumnStretch(1, 0)
|
||||
self.mainBox.setColumnStretch(2, 0)
|
||||
self.mainBox.setColumnStretch(3, 0)
|
||||
self.mainBox.setColumnStretch(4, 0)
|
||||
self.mainBox.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
boxWidth = 16*self.theTheme.textNWidth
|
||||
self.searchBox.setMinimumWidth(boxWidth)
|
||||
self.replaceBox.setMinimumWidth(boxWidth)
|
||||
|
||||
self._replaceVisible(False)
|
||||
|
||||
logger.debug("GuiSearchBar initialisation complete")
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
# Get and Set Functions
|
||||
##
|
||||
|
||||
def setSearchText(self, theText):
|
||||
"""Open the search bar and set the search text to the text
|
||||
provided, if any.
|
||||
"""
|
||||
if not self.isVisible():
|
||||
self.setVisible(True)
|
||||
self.searchBox.setText(theText)
|
||||
self.searchBox.setFocus()
|
||||
logger.verbose("Setting search text to '%s'" % theText)
|
||||
return True
|
||||
|
||||
def setReplaceText(self, theText):
|
||||
"""Set the replace text.
|
||||
"""
|
||||
self._replaceVisible(True)
|
||||
self.replaceBox.setFocus()
|
||||
self.replaceBox.setText(theText)
|
||||
return True
|
||||
|
||||
def getSearchText(self):
|
||||
"""Return the current search text.
|
||||
"""
|
||||
return self.searchBox.text()
|
||||
|
||||
def getReplaceText(self):
|
||||
"""Return the current replace text.
|
||||
"""
|
||||
return self.replaceBox.text()
|
||||
|
||||
##
|
||||
# Internal Functions
|
||||
##
|
||||
|
||||
def _doClose(self):
|
||||
"""Hide the search/replace bar.
|
||||
"""
|
||||
self._replaceVisible(False)
|
||||
self.setVisible(False)
|
||||
return
|
||||
|
||||
def _doSearch(self):
|
||||
"""Call the search action function for the document editor.
|
||||
"""
|
||||
modKey = qApp.keyboardModifiers()
|
||||
if modKey == Qt.ShiftModifier:
|
||||
self.theParent.docEditor.docAction(nwDocAction.GO_PREV)
|
||||
else:
|
||||
self.theParent.docEditor.docAction(nwDocAction.GO_NEXT)
|
||||
return
|
||||
|
||||
def _doReplace(self):
|
||||
"""Call the replace action function for the document editor.
|
||||
"""
|
||||
self.theParent.docEditor.docAction(nwDocAction.REPL_NEXT)
|
||||
return
|
||||
|
||||
def _replaceVisible(self, isVisible):
|
||||
"""Set the visibility of all the replace widgets.
|
||||
"""
|
||||
self.replaceLabel.setVisible(isVisible)
|
||||
self.replaceBox.setVisible(isVisible)
|
||||
self.replaceButton.setVisible(isVisible)
|
||||
self.repVisible = isVisible
|
||||
return True
|
||||
|
||||
# END Class GuiSearchBar
|
||||
@@ -6,9 +6,11 @@
|
||||
Class holding the document editor
|
||||
|
||||
File History:
|
||||
Created: 2018-09-29 [0.0.1] GuiDocEditor
|
||||
Created: 2019-04-22 [0.0.1] WordCounter
|
||||
Created: 2020-04-25 [0.4.5] GuiDocEditHeader
|
||||
Created: 2018-09-29 [0.0.1] GuiDocEditor
|
||||
Created: 2019-04-22 [0.0.1] BackgroundWordCounter
|
||||
Created: 2019-09-29 [0.2.1] GuiDocEditSearch
|
||||
Created: 2020-04-25 [0.4.5] GuiDocEditHeader
|
||||
Rewritten: 2020-06-15 [0.9.0] GuiDocEditSearch
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2020, Veronica Berglyd Olsen
|
||||
@@ -32,20 +34,22 @@ import nw
|
||||
|
||||
from time import time
|
||||
|
||||
from PyQt5.QtCore import Qt, QSize, QThread, QTimer, pyqtSlot
|
||||
from PyQt5.QtCore import Qt, QSize, QThread, QTimer, pyqtSlot, QRegExp
|
||||
from PyQt5.QtGui import (
|
||||
QTextCursor, QTextOption, QKeySequence, QFont, QColor, QPalette,
|
||||
QTextDocument, QCursor
|
||||
)
|
||||
from PyQt5.QtWidgets import (
|
||||
qApp, QTextEdit, QAction, QMenu, QShortcut, QMessageBox, QWidget, QLabel,
|
||||
QToolButton, QHBoxLayout
|
||||
QToolBar, QToolButton, QHBoxLayout, QGridLayout, QLineEdit, QPushButton,
|
||||
QFrame
|
||||
)
|
||||
|
||||
from nw.core import NWDoc
|
||||
from nw.gui.dochighlight import GuiDocHighlighter
|
||||
from nw.core import NWSpellSimple, countWords
|
||||
from nw.constants import nwUnicode, nwDocAction
|
||||
from nw.common import transferCase
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -87,6 +91,7 @@ class GuiDocEditor(QTextEdit):
|
||||
|
||||
# Document Title
|
||||
self.docHeader = GuiDocEditHeader(self)
|
||||
self.docSearch = GuiDocEditSearch(self)
|
||||
|
||||
# Syntax
|
||||
self.hLight = GuiDocHighlighter(self.qDocument, self.theParent)
|
||||
@@ -98,6 +103,7 @@ class GuiDocEditor(QTextEdit):
|
||||
# Editor State
|
||||
self.hasSelection = False
|
||||
self.setMinimumWidth(self.mainConf.pxInt(300))
|
||||
self.setAutoFillBackground(True)
|
||||
self.setAcceptRichText(False)
|
||||
|
||||
# Custom Shortcuts
|
||||
@@ -126,7 +132,7 @@ class GuiDocEditor(QTextEdit):
|
||||
self.wcTimer.setInterval(int(self.wcInterval*1000))
|
||||
self.wcTimer.timeout.connect(self._runCounter)
|
||||
|
||||
self.wCounter = WordCounter(self)
|
||||
self.wCounter = BackgroundWordCounter(self)
|
||||
self.wCounter.finished.connect(self._updateCounts)
|
||||
|
||||
self.initEditor()
|
||||
@@ -182,12 +188,15 @@ class GuiDocEditor(QTextEdit):
|
||||
self.setFont(theFont)
|
||||
|
||||
docPalette = self.palette()
|
||||
docPalette.setColor(QPalette.Window, QColor(*self.theTheme.colBack))
|
||||
docPalette.setColor(QPalette.Base, QColor(*self.theTheme.colBack))
|
||||
docPalette.setColor(QPalette.Text, QColor(*self.theTheme.colText))
|
||||
self.setPalette(docPalette)
|
||||
|
||||
# Set default text margins
|
||||
self.qDocument.setDocumentMargin(self.mainConf.getTextMargin())
|
||||
cM = self.mainConf.getTextMargin()
|
||||
self.qDocument.setDocumentMargin(0)
|
||||
self.setViewportMargins(cM, cM, cM, cM)
|
||||
|
||||
# Also set the document text options for the document text flow
|
||||
theOpt = QTextOption()
|
||||
@@ -309,6 +318,7 @@ class GuiDocEditor(QTextEdit):
|
||||
Config.textFixedW is enabled or we're in Zen mode. Otherwise,
|
||||
just ensure the margins are set correctly.
|
||||
"""
|
||||
wW = self.width()
|
||||
cM = self.mainConf.getTextMargin()
|
||||
|
||||
vBar = self.verticalScrollBar()
|
||||
@@ -322,40 +332,27 @@ class GuiDocEditor(QTextEdit):
|
||||
tW = self.mainConf.getZenWidth()
|
||||
else:
|
||||
tW = self.mainConf.getTextWidth()
|
||||
wW = self.width()
|
||||
tM = int((wW - sW - tW)/2)
|
||||
tM = (wW - sW - tW)//2
|
||||
if tM < cM:
|
||||
tM = cM
|
||||
else:
|
||||
tM = cM
|
||||
|
||||
tB = self.frameWidth()
|
||||
tW = self.width() - 2*tB - sW
|
||||
tW = wW - 2*tB - sW
|
||||
tH = self.docHeader.height()
|
||||
tT = cM - tH
|
||||
self.docHeader.setGeometry(tB, tB, tW, tH)
|
||||
self.setViewportMargins(0, tH, 0, 0)
|
||||
|
||||
docFormat = self.qDocument.rootFrame().frameFormat()
|
||||
docFormat.setLeftMargin(tM)
|
||||
docFormat.setRightMargin(tM)
|
||||
if tT > 0:
|
||||
docFormat.setTopMargin(tT)
|
||||
if self.docSearch.isVisible():
|
||||
rH = self.docSearch.height()
|
||||
rW = self.docSearch.width()
|
||||
rL = wW - sW - rW - 2*tB
|
||||
self.docSearch.move(rL, 2*tB)
|
||||
else:
|
||||
docFormat.setTopMargin(0)
|
||||
rH = 0
|
||||
|
||||
# Updating root frame triggers a QTextDocument->contentsChange
|
||||
# signal, which we do not want as it re-runs the syntax
|
||||
# highlighter and spell checker, so we block it briefly.
|
||||
# We then emit a signal that does not trigger re-highlighting.
|
||||
self.qDocument.blockSignals(True)
|
||||
self.qDocument.rootFrame().setFrameFormat(docFormat)
|
||||
self.qDocument.blockSignals(False)
|
||||
|
||||
# The line below causes issues with large documents as it
|
||||
# triggers an early repaint that seems to only render a part of
|
||||
# the document. Leaving it here as a warning for now.
|
||||
# self.qDocument.contentsChange.emit(0, 0, 0)
|
||||
# print(tM, tH, rH, max(tM, tH, rH))
|
||||
self.setViewportMargins(tM, max(cM, tH, rH), tM, cM)
|
||||
|
||||
return
|
||||
|
||||
@@ -532,7 +529,7 @@ class GuiDocEditor(QTextEdit):
|
||||
elif theAction == nwDocAction.GO_NEXT:
|
||||
self._findNext()
|
||||
elif theAction == nwDocAction.GO_PREV:
|
||||
self._findPrev()
|
||||
self._findNext(isBackward=True)
|
||||
elif theAction == nwDocAction.REPL_NEXT:
|
||||
self._replaceNext()
|
||||
elif theAction == nwDocAction.BLOCK_H1:
|
||||
@@ -573,6 +570,12 @@ class GuiDocEditor(QTextEdit):
|
||||
))
|
||||
return
|
||||
|
||||
def closeSearch(self):
|
||||
"""Close the search box.
|
||||
"""
|
||||
self.docSearch.closeSearch()
|
||||
return self.docSearch.isVisible()
|
||||
|
||||
##
|
||||
# Document Events and Maintenance
|
||||
##
|
||||
@@ -590,6 +593,9 @@ class GuiDocEditor(QTextEdit):
|
||||
as it is triggered on every keypress when typing.
|
||||
"""
|
||||
self.hasSelection = self.textCursor().hasSelection()
|
||||
if self.docSearch.searchBox.hasFocus():
|
||||
# Block the event when the focus is on the search bar.
|
||||
return
|
||||
|
||||
if keyEvent.modifiers() == Qt.ShiftModifier:
|
||||
theKey = keyEvent.key()
|
||||
@@ -1131,7 +1137,8 @@ class GuiDocEditor(QTextEdit):
|
||||
selText = theCursor.selectedText()
|
||||
else:
|
||||
selText = ""
|
||||
self.theParent.searchBar.setSearchText(selText)
|
||||
self.docSearch.setSearchText(selText)
|
||||
self.updateDocMargins()
|
||||
return
|
||||
|
||||
def _beginReplace(self):
|
||||
@@ -1139,54 +1146,82 @@ class GuiDocEditor(QTextEdit):
|
||||
text.
|
||||
"""
|
||||
self._beginSearch()
|
||||
self.theParent.searchBar.setReplaceText("")
|
||||
self.docSearch.setReplaceText("")
|
||||
return
|
||||
|
||||
def _findNext(self):
|
||||
"""Searches for the next occurrence of the search bar text in
|
||||
the document. Wraps back to the top if not found.
|
||||
def _findNext(self, isBackward=False):
|
||||
"""Searches for the next or previous occurrence of the search
|
||||
bar text in the document. Wraps around if not found and loop is
|
||||
enabled, or continues to next file if next file is enabled.
|
||||
"""
|
||||
searchFor = self.theParent.searchBar.getSearchText()
|
||||
wasFound = self.find(searchFor)
|
||||
if not wasFound:
|
||||
theCursor = self.textCursor()
|
||||
theCursor.movePosition(QTextCursor.Start)
|
||||
self.setTextCursor(theCursor)
|
||||
return
|
||||
if not self.docSearch.isVisible():
|
||||
self._beginSearch()
|
||||
return
|
||||
|
||||
def _findPrev(self):
|
||||
"""Searches for the previous occurrence of the search bar text
|
||||
in the document. Wraps back to the end if not found.
|
||||
"""
|
||||
searchFor = self.theParent.searchBar.getSearchText()
|
||||
wasFound = self.find(searchFor, QTextDocument.FindBackward)
|
||||
findOpt = QTextDocument.FindFlag(0)
|
||||
if isBackward:
|
||||
findOpt |= QTextDocument.FindBackward
|
||||
if self.docSearch.isCaseSense:
|
||||
findOpt |= QTextDocument.FindCaseSensitively
|
||||
if self.docSearch.isWholeWord:
|
||||
findOpt |= QTextDocument.FindWholeWords
|
||||
|
||||
searchFor = self.docSearch.getSearchText()
|
||||
wasFound = self.find(searchFor, findOpt)
|
||||
if not wasFound:
|
||||
theCursor = self.textCursor()
|
||||
theCursor.movePosition(QTextCursor.End)
|
||||
self.setTextCursor(theCursor)
|
||||
if self.docSearch.doNextFile and not isBackward:
|
||||
self.theParent.openNextDocument(
|
||||
self.theHandle, wrapAround=self.docSearch.doLoop
|
||||
)
|
||||
elif self.docSearch.doLoop:
|
||||
theCursor = self.textCursor()
|
||||
theCursor.movePosition(
|
||||
QTextCursor.End if isBackward else QTextCursor.Start
|
||||
)
|
||||
self.setTextCursor(theCursor)
|
||||
self.find(searchFor, findOpt)
|
||||
|
||||
return
|
||||
|
||||
def _replaceNext(self):
|
||||
"""Searches for the next occurrence of the search bar text in
|
||||
the document and replaces it with the replace text. Wraps back
|
||||
to the top if not found.
|
||||
the document and replaces it with the replace text. Calls search
|
||||
next automatically when done.
|
||||
"""
|
||||
if not self.docSearch.isVisible():
|
||||
self._beginSearch()
|
||||
return
|
||||
|
||||
if not theCursor.hasSelection():
|
||||
return
|
||||
|
||||
theCursor = self.textCursor()
|
||||
searchFor = self.theParent.searchBar.getSearchText()
|
||||
replWith = self.theParent.searchBar.getReplaceText()
|
||||
if theCursor.hasSelection() and theCursor.selectedText() == searchFor:
|
||||
xPos = theCursor.selectionStart()
|
||||
searchFor = self.docSearch.getSearchText()
|
||||
replWith = self.docSearch.getReplaceText()
|
||||
selText = theCursor.selectedText()
|
||||
|
||||
if self.docSearch.doMatchCap:
|
||||
replWith = transferCase(selText, replWith)
|
||||
|
||||
if not self.docSearch.isCaseSense:
|
||||
isMatch = searchFor.lower() == selText.lower()
|
||||
else:
|
||||
isMatch = searchFor == selText
|
||||
|
||||
if isMatch:
|
||||
theCursor.beginEditBlock()
|
||||
theCursor.removeSelectedText()
|
||||
theCursor.insertText(replWith)
|
||||
theCursor.endEditBlock()
|
||||
theCursor.setPosition(xPos)
|
||||
theCursor.setPosition(theCursor.selectionEnd())
|
||||
self.setTextCursor(theCursor)
|
||||
logger.verbose("Replaced occurrence of '%s' with '%s' on line %d" % (
|
||||
searchFor, replWith, theCursor.blockNumber()
|
||||
))
|
||||
if searchFor != "":
|
||||
|
||||
if searchFor:
|
||||
self._findNext()
|
||||
|
||||
return
|
||||
|
||||
def _setupSpellChecking(self):
|
||||
@@ -1205,11 +1240,16 @@ class GuiDocEditor(QTextEdit):
|
||||
|
||||
# END Class GuiDocEditor
|
||||
|
||||
class WordCounter(QThread):
|
||||
# =============================================================================================== #
|
||||
# The Off GUI Thread Word Counter
|
||||
# Runs the word counter in the background for the DocEditor
|
||||
# =============================================================================================== #
|
||||
|
||||
def __init__(self, theParent):
|
||||
QThread.__init__(self, theParent)
|
||||
self.theParent = theParent
|
||||
class BackgroundWordCounter(QThread):
|
||||
|
||||
def __init__(self, docEditor):
|
||||
QThread.__init__(self, docEditor)
|
||||
self.docEditor = docEditor
|
||||
self.charCount = 0
|
||||
self.wordCount = 0
|
||||
self.paraCount = 0
|
||||
@@ -1219,16 +1259,357 @@ class WordCounter(QThread):
|
||||
"""Overloaded run function for the word counter, forwarding the
|
||||
call to the function that does the actual counting.
|
||||
"""
|
||||
theText = self.theParent.getText()
|
||||
theText = self.docEditor.getText()
|
||||
cC, wC, pC = countWords(theText)
|
||||
|
||||
self.charCount = cC
|
||||
self.wordCount = wC
|
||||
self.paraCount = pC
|
||||
return
|
||||
|
||||
## END Class BackgroundWordCounter
|
||||
|
||||
# =============================================================================================== #
|
||||
# The Embedded Document Search/Replace Feature
|
||||
# Only used by DocEditor, and is at a fixed position in the QTextEdit's viewport
|
||||
# =============================================================================================== #
|
||||
|
||||
class GuiDocEditSearch(QFrame):
|
||||
|
||||
def __init__(self, docEditor):
|
||||
QFrame.__init__(self, docEditor)
|
||||
|
||||
logger.debug("Initialising GuiDocEditSearch ...")
|
||||
|
||||
self.mainConf = nw.CONFIG
|
||||
self.docEditor = docEditor
|
||||
self.theParent = docEditor.theParent
|
||||
self.theProject = docEditor.theProject
|
||||
self.theTheme = docEditor.theTheme
|
||||
|
||||
self.repVisible = False
|
||||
self.isCaseSense = self.mainConf.searchCase
|
||||
self.isWholeWord = self.mainConf.searchWord
|
||||
self.isRegEx = self.mainConf.searchRegEx
|
||||
self.doLoop = self.mainConf.searchLoop
|
||||
self.doNextFile = self.mainConf.searchNextFile
|
||||
self.doMatchCap = self.mainConf.searchMatchCap
|
||||
|
||||
mPx = self.mainConf.pxInt(6)
|
||||
fPx = int(0.9*self.theTheme.fontPixelSize)
|
||||
tPx = int(0.8*self.theTheme.fontPixelSize)
|
||||
boxFont = self.theTheme.guiFont
|
||||
boxFont.setPointSizeF(0.9*self.theTheme.fontPointSize)
|
||||
|
||||
self.setContentsMargins(0, 0, 0, 0)
|
||||
self.setAutoFillBackground(True)
|
||||
self.setFrameStyle(QFrame.StyledPanel | QFrame.Plain)
|
||||
|
||||
self.mainBox = QGridLayout(self)
|
||||
self.setLayout(self.mainBox)
|
||||
|
||||
# Text Boxes
|
||||
# ==========
|
||||
self.searchBox = QLineEdit()
|
||||
self.searchBox.setFont(boxFont)
|
||||
self.searchBox.setPlaceholderText("Search")
|
||||
self.searchBox.returnPressed.connect(self._doSearch)
|
||||
|
||||
self.replaceBox = QLineEdit()
|
||||
self.replaceBox.setFont(boxFont)
|
||||
self.replaceBox.setPlaceholderText("Replace")
|
||||
self.replaceBox.returnPressed.connect(self._doSearch)
|
||||
|
||||
self.searchOpt = QToolBar(self)
|
||||
self.searchOpt.setToolButtonStyle(Qt.ToolButtonIconOnly)
|
||||
self.searchOpt.setIconSize(QSize(tPx, tPx))
|
||||
self.searchOpt.setContentsMargins(0, 0, 0, 0)
|
||||
self.searchOpt.setStyleSheet(r"QToolBar {padding: 0;}")
|
||||
|
||||
self.searchLabel = QLabel("Search")
|
||||
self.searchLabel.setFont(boxFont)
|
||||
self.searchLabel.setIndent(self.mainConf.pxInt(6))
|
||||
|
||||
self.toggleCase = QAction("Case Sensitive", self)
|
||||
self.toggleCase.setToolTip("Match case")
|
||||
self.toggleCase.setIcon(self.theTheme.getIcon("search_case"))
|
||||
self.toggleCase.setCheckable(True)
|
||||
self.toggleCase.setChecked(self.isCaseSense)
|
||||
self.toggleCase.toggled.connect(self._doToggleCase)
|
||||
self.searchOpt.addAction(self.toggleCase)
|
||||
|
||||
self.toggleWord = QAction("Whole Words Only", self)
|
||||
self.toggleWord.setToolTip("Match whole words")
|
||||
self.toggleWord.setIcon(self.theTheme.getIcon("search_word"))
|
||||
self.toggleWord.setCheckable(True)
|
||||
self.toggleWord.setChecked(self.isWholeWord)
|
||||
self.toggleWord.toggled.connect(self._doToggleWord)
|
||||
self.searchOpt.addAction(self.toggleWord)
|
||||
|
||||
self.toggleRegEx = QAction("RegEx Mode", self)
|
||||
self.toggleRegEx.setToolTip("Use regular expressions")
|
||||
self.toggleRegEx.setIcon(self.theTheme.getIcon("search_regex"))
|
||||
self.toggleRegEx.setCheckable(True)
|
||||
self.toggleRegEx.setChecked(self.isRegEx)
|
||||
self.toggleRegEx.toggled.connect(self._doToggleRegEx)
|
||||
self.searchOpt.addAction(self.toggleRegEx)
|
||||
|
||||
self.toggleLoop = QAction("Loop Search", self)
|
||||
self.toggleLoop.setToolTip("Loop the search when reaching the end")
|
||||
self.toggleLoop.setIcon(self.theTheme.getIcon("search_loop"))
|
||||
self.toggleLoop.setCheckable(True)
|
||||
self.toggleLoop.setChecked(self.doLoop)
|
||||
self.toggleLoop.toggled.connect(self._doToggleLoop)
|
||||
self.searchOpt.addAction(self.toggleLoop)
|
||||
|
||||
self.toggleProject = QAction("Search Next File", self)
|
||||
self.toggleProject.setToolTip("Continue searching in the next file")
|
||||
self.toggleProject.setIcon(self.theTheme.getIcon("search_project"))
|
||||
self.toggleProject.setCheckable(True)
|
||||
self.toggleProject.setChecked(self.doNextFile)
|
||||
self.toggleProject.toggled.connect(self._doToggleProject)
|
||||
self.searchOpt.addAction(self.toggleProject)
|
||||
|
||||
self.searchOpt.addSeparator()
|
||||
|
||||
self.toggleMatchCap = QAction("Preserve Case", self)
|
||||
self.toggleMatchCap.setToolTip("Preserve case on replace")
|
||||
self.toggleMatchCap.setIcon(self.theTheme.getIcon("search_preserve"))
|
||||
self.toggleMatchCap.setCheckable(True)
|
||||
self.toggleMatchCap.setChecked(self.doMatchCap)
|
||||
self.toggleMatchCap.toggled.connect(self._doToggleMatchCap)
|
||||
self.searchOpt.addAction(self.toggleMatchCap)
|
||||
|
||||
self.searchOpt.addSeparator()
|
||||
|
||||
self.cancelSearch = QAction("Close Search", self)
|
||||
self.cancelSearch.setToolTip("Close the search box [Esc]")
|
||||
self.cancelSearch.setIcon(self.theTheme.getIcon("search_cancel"))
|
||||
self.cancelSearch.triggered.connect(self._doClose)
|
||||
self.searchOpt.addAction(self.cancelSearch)
|
||||
|
||||
# Buttons
|
||||
# =======
|
||||
bPx = self.searchBox.sizeHint().height()
|
||||
|
||||
self.showReplace = QToolButton(self)
|
||||
self.showReplace.setArrowType(Qt.RightArrow)
|
||||
self.showReplace.setCheckable(True)
|
||||
self.showReplace.setStyleSheet(r"QToolButton {border: none; background: transparent;}")
|
||||
self.showReplace.toggled.connect(self._doToggleReplace)
|
||||
|
||||
self.searchButton = QPushButton(self.theTheme.getIcon("search"),"")
|
||||
self.searchButton.setFixedSize(QSize(bPx, bPx))
|
||||
self.searchButton.setToolTip("Find in current document")
|
||||
self.searchButton.clicked.connect(self._doSearch)
|
||||
|
||||
self.replaceButton = QPushButton(self.theTheme.getIcon("search-replace"),"")
|
||||
self.replaceButton.setFixedSize(QSize(bPx, bPx))
|
||||
self.replaceButton.setToolTip("Find and replace in current document")
|
||||
self.replaceButton.clicked.connect(self._doReplace)
|
||||
|
||||
self.mainBox.addWidget(self.searchLabel, 0, 0, 1, 2, Qt.AlignLeft)
|
||||
self.mainBox.addWidget(self.searchOpt, 0, 2, 1, 2, Qt.AlignRight)
|
||||
self.mainBox.addWidget(self.showReplace, 1, 0, 1, 1)
|
||||
self.mainBox.addWidget(self.searchBox, 1, 1, 1, 2)
|
||||
self.mainBox.addWidget(self.searchButton, 1, 3, 1, 1)
|
||||
self.mainBox.addWidget(self.replaceBox, 2, 1, 1, 2)
|
||||
self.mainBox.addWidget(self.replaceButton, 2, 3, 1, 1)
|
||||
|
||||
self.mainBox.setColumnStretch(0, 1)
|
||||
self.mainBox.setColumnStretch(1, 0)
|
||||
self.mainBox.setColumnStretch(2, 0)
|
||||
self.mainBox.setColumnStretch(3, 0)
|
||||
self.mainBox.setColumnStretch(4, 0)
|
||||
self.mainBox.setSpacing(self.mainConf.pxInt(2))
|
||||
self.mainBox.setContentsMargins(mPx, mPx, mPx, mPx)
|
||||
|
||||
boxWidth = self.mainConf.pxInt(200)
|
||||
self.searchBox.setFixedWidth(boxWidth)
|
||||
self.replaceBox.setFixedWidth(boxWidth)
|
||||
self.replaceBox.setVisible(False)
|
||||
self.replaceButton.setVisible(False)
|
||||
self.adjustSize()
|
||||
|
||||
# Construct Box Colours
|
||||
qPalette = self.searchBox.palette()
|
||||
baseCol = qPalette.base().color()
|
||||
rCol = baseCol.redF() + 0.1
|
||||
gCol = baseCol.greenF() - 0.1
|
||||
bCol = baseCol.blueF() - 0.1
|
||||
|
||||
mCol = max(rCol, gCol, bCol, 1.0)
|
||||
errCol = QColor()
|
||||
errCol.setRedF(rCol/mCol)
|
||||
errCol.setGreenF(gCol/mCol)
|
||||
errCol.setBlueF(bCol/mCol)
|
||||
|
||||
self.rxCol = {
|
||||
True : baseCol,
|
||||
False : errCol
|
||||
}
|
||||
|
||||
logger.debug("GuiDocEditSearch initialisation complete")
|
||||
|
||||
return
|
||||
|
||||
## END Class WordCounter
|
||||
def closeSearch(self):
|
||||
"""Close the search box.
|
||||
"""
|
||||
self.mainConf.searchCase = self.isCaseSense
|
||||
self.mainConf.searchWord = self.isWholeWord
|
||||
self.mainConf.searchRegEx = self.isRegEx
|
||||
self.mainConf.searchLoop = self.doLoop
|
||||
self.mainConf.searchNextFile = self.doNextFile
|
||||
self.mainConf.searchMatchCap = self.doMatchCap
|
||||
|
||||
self.showReplace.setChecked(False)
|
||||
self.setVisible(False)
|
||||
self.docEditor.updateDocMargins()
|
||||
self.docEditor.setFocus()
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
# Get and Set Functions
|
||||
##
|
||||
|
||||
def setSearchText(self, theText):
|
||||
"""Open the search bar and set the search text to the text
|
||||
provided, if any.
|
||||
"""
|
||||
if not self.isVisible():
|
||||
self.setVisible(True)
|
||||
self.searchBox.setText(theText)
|
||||
self.searchBox.setFocus()
|
||||
if self.isRegEx:
|
||||
self._alertSearchValid(True)
|
||||
logger.verbose("Setting search text to '%s'" % theText)
|
||||
return True
|
||||
|
||||
def setReplaceText(self, theText):
|
||||
"""Set the replace text.
|
||||
"""
|
||||
self.showReplace.setChecked(True)
|
||||
self.replaceBox.setFocus()
|
||||
self.replaceBox.setText(theText)
|
||||
return True
|
||||
|
||||
def getSearchText(self):
|
||||
"""Return the current search text either as text or as a regular
|
||||
expression object.
|
||||
"""
|
||||
theText = self.searchBox.text()
|
||||
if self.isRegEx and self.mainConf.verQtValue >= 50300:
|
||||
if self.isCaseSense:
|
||||
rxCase = Qt.CaseSensitive
|
||||
else:
|
||||
rxCase = Qt.CaseInsensitive
|
||||
theRegEx = QRegExp(theText, rxCase)
|
||||
self._alertSearchValid(theRegEx.isValid())
|
||||
return theRegEx
|
||||
|
||||
return theText
|
||||
|
||||
def getReplaceText(self):
|
||||
"""Return the current replace text.
|
||||
"""
|
||||
return self.replaceBox.text()
|
||||
|
||||
##
|
||||
# Slots
|
||||
##
|
||||
|
||||
def _doClose(self):
|
||||
"""Hide the search/replace bar.
|
||||
"""
|
||||
self.closeSearch()
|
||||
return
|
||||
|
||||
def _doSearch(self):
|
||||
"""Call the search action function for the document editor.
|
||||
"""
|
||||
modKey = qApp.keyboardModifiers()
|
||||
if modKey == Qt.ShiftModifier:
|
||||
self.docEditor.docAction(nwDocAction.GO_PREV)
|
||||
else:
|
||||
self.docEditor.docAction(nwDocAction.GO_NEXT)
|
||||
return
|
||||
|
||||
def _doReplace(self):
|
||||
"""Call the replace action function for the document editor.
|
||||
"""
|
||||
self.docEditor.docAction(nwDocAction.REPL_NEXT)
|
||||
return
|
||||
|
||||
def _doToggleReplace(self, theState):
|
||||
"""Toggle the show/hide of the
|
||||
"""
|
||||
if theState:
|
||||
self.showReplace.setArrowType(Qt.DownArrow)
|
||||
else:
|
||||
self.showReplace.setArrowType(Qt.RightArrow)
|
||||
self.replaceBox.setVisible(theState)
|
||||
self.replaceButton.setVisible(theState)
|
||||
self.repVisible = theState
|
||||
self.adjustSize()
|
||||
self.docEditor.updateDocMargins()
|
||||
return
|
||||
|
||||
def _doToggleCase(self, theState):
|
||||
"""Enable/disable case sensitive mode.
|
||||
"""
|
||||
self.isCaseSense = theState
|
||||
return
|
||||
|
||||
def _doToggleWord(self, theState):
|
||||
"""Enable/disable whole word search mode.
|
||||
"""
|
||||
self.isWholeWord = theState
|
||||
return
|
||||
|
||||
def _doToggleRegEx(self, theState):
|
||||
"""Enable/disable regular expression search mode.
|
||||
"""
|
||||
self.isRegEx = theState
|
||||
return
|
||||
|
||||
def _doToggleLoop(self, theState):
|
||||
"""Enable/disable looping the search.
|
||||
"""
|
||||
self.doLoop = theState
|
||||
return
|
||||
|
||||
def _doToggleProject(self, theState):
|
||||
"""Enable/disable continuing search in next project file.
|
||||
"""
|
||||
self.doNextFile = theState
|
||||
return
|
||||
|
||||
def _doToggleMatchCap(self, theState):
|
||||
"""Enable/disable preserving capitalisation when replacing.
|
||||
"""
|
||||
self.doMatchCap = theState
|
||||
return
|
||||
|
||||
##
|
||||
# Internal Functions
|
||||
##
|
||||
|
||||
def _alertSearchValid(self, isValid):
|
||||
"""Highlight the search box to indicate the search string is or
|
||||
isn't valid. Take the colour from the replace box.
|
||||
"""
|
||||
qPalette = self.replaceBox.palette()
|
||||
qPalette.setColor(QPalette.Base, self.rxCol[isValid])
|
||||
self.searchBox.setPalette(qPalette)
|
||||
return
|
||||
|
||||
# END Class GuiDocEditSearch
|
||||
|
||||
# =============================================================================================== #
|
||||
# The Embedded Document Header
|
||||
# Only used by DocEditor, and is at a fixed position in the QTextEdit's viewport
|
||||
# =============================================================================================== #
|
||||
|
||||
class GuiDocEditHeader(QWidget):
|
||||
|
||||
|
||||
@@ -236,13 +236,14 @@ class GuiDocViewer(QTextBrowser):
|
||||
else:
|
||||
sW = 0
|
||||
|
||||
cM = self.mainConf.getTextMargin()
|
||||
tB = self.frameWidth()
|
||||
tW = self.width() - 2*tB - sW
|
||||
tH = self.docHeader.height()
|
||||
fH = self.docFooter.height()
|
||||
fY = self.height() - fH - tB
|
||||
tT = self.mainConf.getTextMargin() - tH
|
||||
bT = self.mainConf.getTextMargin() - fH
|
||||
tT = cM - tH
|
||||
bT = cM - fH
|
||||
self.docHeader.setGeometry(tB, tB, tW, tH)
|
||||
self.docFooter.setGeometry(tB, fY, tW, fH)
|
||||
self.setViewportMargins(0, tH, 0, fH)
|
||||
@@ -558,16 +559,16 @@ class GuiDocViewHeader(QWidget):
|
||||
|
||||
class GuiDocViewFooter(QWidget):
|
||||
|
||||
def __init__(self, theParent):
|
||||
QWidget.__init__(self, theParent)
|
||||
def __init__(self, docViewer):
|
||||
QWidget.__init__(self, docViewer)
|
||||
|
||||
logger.debug("Initialising GuiDocViewFooter ...")
|
||||
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theParent = theParent
|
||||
self.theTheme = theParent.theTheme
|
||||
self.optState = theParent.theProject.optState
|
||||
self.viewMeta = theParent.theParent.viewMeta
|
||||
self.docViewer = docViewer
|
||||
self.theParent = docViewer.theParent
|
||||
self.theTheme = docViewer.theTheme
|
||||
self.viewMeta = docViewer.theParent.viewMeta
|
||||
self.theHandle = None
|
||||
|
||||
# Make a QPalette that matches the Syntax Theme
|
||||
@@ -669,9 +670,9 @@ class GuiDocViewFooter(QWidget):
|
||||
"""Toggle the sticky flag for the reference panel.
|
||||
"""
|
||||
logger.verbose("Reference sticky is %s" % str(theState))
|
||||
self.theParent.stickyRef = theState
|
||||
if not theState and self.theParent.theHandle is not None:
|
||||
self.viewMeta.refreshReferences(self.theParent.theHandle)
|
||||
self.docViewer.stickyRef = theState
|
||||
if not theState and self.docViewer.theHandle is not None:
|
||||
self.viewMeta.refreshReferences(self.docViewer.theHandle)
|
||||
return
|
||||
|
||||
# END Class GuiDocViewFooter
|
||||
|
||||
@@ -60,8 +60,9 @@ class GuiProjectTree(QTreeWidget):
|
||||
self.theProject = theParent.theProject
|
||||
|
||||
# Tree Settings
|
||||
self.theMap = None
|
||||
self.orphRoot = None
|
||||
self.theMap = None
|
||||
self.orphRoot = None
|
||||
self.treeChanged = False
|
||||
|
||||
self.ctxMenu = GuiProjectTreeMenu(self)
|
||||
self.clearTree()
|
||||
@@ -256,7 +257,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
pItem.insertChild(nIndex, cItem)
|
||||
self.clearSelection()
|
||||
cItem.setSelected(True)
|
||||
self.theProject.setProjectChanged(True)
|
||||
self._setTreeChanged(True)
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
@@ -276,6 +277,16 @@ class GuiProjectTree(QTreeWidget):
|
||||
self.theProject.setTreeOrder(theList)
|
||||
return True
|
||||
|
||||
def flushTreeOrder(self):
|
||||
"""Calls saveTreeOrder if there are unsaved changes, otherwise
|
||||
does nothing.
|
||||
"""
|
||||
if self.treeChanged:
|
||||
logger.verbose("Flushing project tree to project class")
|
||||
self.saveTreeOrder()
|
||||
self._setTreeChanged(False)
|
||||
return
|
||||
|
||||
def getTreeFromHandle(self, tHandle):
|
||||
"""Recursively return all the children items starting from a
|
||||
given item handle.
|
||||
@@ -332,6 +343,9 @@ class GuiProjectTree(QTreeWidget):
|
||||
continue
|
||||
self.deleteItem(tHandle, True)
|
||||
|
||||
if nTrash > 0:
|
||||
self._setTreeChanged(True)
|
||||
|
||||
return True
|
||||
|
||||
def deleteItem(self, tHandle=None, alreadyAsked=False, askForTrash=False):
|
||||
@@ -413,7 +427,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
trItemT.addChild(trItemC)
|
||||
nwItemS.setParent(self.theProject.projTree.trashRoot())
|
||||
|
||||
self.theProject.setProjectChanged(True)
|
||||
self._setTreeChanged(True)
|
||||
self.theParent.theIndex.deleteHandle(tHandle)
|
||||
|
||||
elif nwItemS.itemType == nwItemType.FOLDER:
|
||||
@@ -436,7 +450,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
if trItemS.childCount() == 0:
|
||||
self.takeTopLevelItem(tIndex)
|
||||
self.theParent.mainMenu.setAvailableRoot()
|
||||
self.theProject.setProjectChanged(True)
|
||||
self._setTreeChanged(True)
|
||||
else:
|
||||
self.makeAlert("Cannot delete root folder. It is not empty.", nwAlert.ERROR)
|
||||
return False
|
||||
@@ -732,6 +746,8 @@ class GuiProjectTree(QTreeWidget):
|
||||
elif nwItem.itemType == nwItemType.TRASH:
|
||||
newItem.setIcon(self.C_NAME, self.theTheme.getIcon(nwLabels.CLASS_ICON[tClass]))
|
||||
|
||||
self._setTreeChanged(True)
|
||||
|
||||
return newItem
|
||||
|
||||
def _addTrashRoot(self):
|
||||
@@ -747,6 +763,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
self.theProject.projTree[trashHandle]
|
||||
)
|
||||
trItem.setExpanded(True)
|
||||
self._setTreeChanged(True)
|
||||
return trItem
|
||||
|
||||
def _addOrphanedRoot(self):
|
||||
@@ -793,7 +810,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
nwItemS.setParent(pHandle)
|
||||
self.propagateCount(tHandle, wC)
|
||||
self.setTreeItemValues(tHandle)
|
||||
self.theProject.setProjectChanged(True)
|
||||
self._setTreeChanged(True)
|
||||
|
||||
logger.debug("The parent of item %s has been changed to %s" % (tHandle,pHandle))
|
||||
|
||||
@@ -815,7 +832,15 @@ class GuiProjectTree(QTreeWidget):
|
||||
pHandle = trItemP.data(self.C_NAME, Qt.UserRole)
|
||||
nwItemS.setParent(pHandle)
|
||||
self.setTreeItemValues(tHandle)
|
||||
self.theProject.setProjectChanged(True)
|
||||
self._setTreeChanged(True)
|
||||
return
|
||||
|
||||
def _setTreeChanged(self, theState):
|
||||
"""Set the tree change flag, and propagate to the project.
|
||||
"""
|
||||
self.treeChanged = theState
|
||||
if theState:
|
||||
self.theProject.setProjectChanged(True)
|
||||
return
|
||||
|
||||
# END Class GuiProjectTree
|
||||
|
||||
@@ -495,52 +495,58 @@ class GuiIcons:
|
||||
|
||||
ICON_MAP = {
|
||||
# Project and GUI icons
|
||||
"cls_none" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_novel" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_plot" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_character" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_world" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_timeline" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_object" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_entity" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_custom" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_trash" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"proj_document" : (QStyle.SP_FileIcon, "x-office-document"),
|
||||
"proj_folder" : (QStyle.SP_DirIcon, "folder"),
|
||||
"proj_orphan" : (QStyle.SP_MessageBoxWarning, "dialog-warning"),
|
||||
"proj_nwx" : (None, None),
|
||||
"status_lang" : (None, None),
|
||||
"status_time" : (None, None),
|
||||
"status_stats" : (None, None),
|
||||
"doc_h1" : (QStyle.SP_FileIcon, "x-office-document"),
|
||||
"doc_h2" : (QStyle.SP_FileIcon, "x-office-document"),
|
||||
"doc_h3" : (QStyle.SP_FileIcon, "x-office-document"),
|
||||
"doc_h4" : (QStyle.SP_FileIcon, "x-office-document"),
|
||||
"cls_none" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_novel" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_plot" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_character" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_world" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_timeline" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_object" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_entity" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_custom" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"cls_trash" : (QStyle.SP_DriveHDIcon, "drive-harddisk"),
|
||||
"proj_document" : (QStyle.SP_FileIcon, "x-office-document"),
|
||||
"proj_folder" : (QStyle.SP_DirIcon, "folder"),
|
||||
"proj_orphan" : (QStyle.SP_MessageBoxWarning, "dialog-warning"),
|
||||
"proj_nwx" : (None, None),
|
||||
"status_lang" : (None, None),
|
||||
"status_time" : (None, None),
|
||||
"status_stats" : (None, None),
|
||||
"doc_h1" : (QStyle.SP_FileIcon, "x-office-document"),
|
||||
"doc_h2" : (QStyle.SP_FileIcon, "x-office-document"),
|
||||
"doc_h3" : (QStyle.SP_FileIcon, "x-office-document"),
|
||||
"doc_h4" : (QStyle.SP_FileIcon, "x-office-document"),
|
||||
"search_case" : (None, None),
|
||||
"search_regex" : (None, None),
|
||||
"search_word" : (None, None),
|
||||
"search_loop" : (None, None),
|
||||
"search_project" : (None, None),
|
||||
"search_cancel" : (None, None),
|
||||
"search_preserve" : (None, None),
|
||||
|
||||
## General Button Icons
|
||||
"folder-open" : (QStyle.SP_DirOpenIcon, "folder-open"),
|
||||
"delete" : (QStyle.SP_DialogDiscardButton, "edit-delete"),
|
||||
"add" : (None, "list-add"),
|
||||
"remove" : (None, "list-remove"),
|
||||
"close" : (QStyle.SP_DialogCloseButton, "window-close"),
|
||||
"done" : (QStyle.SP_DialogApplyButton, None),
|
||||
"search" : (None, "edit-find"),
|
||||
"search-replace" : (None, "edit-find-replace"),
|
||||
"clear" : (QStyle.SP_LineEditClearButton, "clear_left"),
|
||||
"save" : (QStyle.SP_DialogSaveButton, "document-save"),
|
||||
"edit" : (None, None),
|
||||
"check" : (None, None),
|
||||
"cross" : (None, None),
|
||||
"hash" : (None, None),
|
||||
"maximise" : (None, None),
|
||||
"minimise" : (None, None),
|
||||
"refresh" : (None, None),
|
||||
"reference" : (None, None),
|
||||
"sticky-on" : (None, None),
|
||||
"sticky-off" : (None, None),
|
||||
"add" : (None, "list-add"),
|
||||
"remove" : (None, "list-remove"),
|
||||
"search" : (None, "edit-find"),
|
||||
"search-replace" : (None, "edit-find-replace"),
|
||||
"edit" : (None, None),
|
||||
"check" : (None, None),
|
||||
"cross" : (None, None),
|
||||
"hash" : (None, None),
|
||||
"maximise" : (None, None),
|
||||
"minimise" : (None, None),
|
||||
"refresh" : (None, None),
|
||||
"reference" : (None, None),
|
||||
|
||||
## Other Icons
|
||||
"warning" : (QStyle.SP_MessageBoxWarning, "dialog-warning"),
|
||||
## Switches
|
||||
"sticky-on" : (None, None),
|
||||
"sticky-off" : (None, None),
|
||||
}
|
||||
|
||||
DECO_MAP = {
|
||||
|
||||
@@ -42,8 +42,8 @@ from PyQt5.QtWidgets import (
|
||||
from nw.gui import (
|
||||
GuiBuildNovel, GuiDocEditor, GuiDocMerge, GuiDocSplit, GuiDocViewDetails,
|
||||
GuiDocViewer, GuiItemDetails, GuiItemEditor, GuiMainMenu, GuiMainStatus,
|
||||
GuiOutline, GuiOutlineDetails, GuiPreferences, GuiProjectLoad,
|
||||
GuiProjectSettings, GuiProjectTree, GuiSearchBar, GuiSessionLogView, GuiTheme
|
||||
GuiOutline, GuiOutlineDetails, GuiPreferences, GuiProjectLoad, GuiTheme,
|
||||
GuiProjectSettings, GuiProjectTree, GuiSessionLogView
|
||||
)
|
||||
from nw.core import NWProject, NWDoc, NWIndex
|
||||
from nw.constants import nwFiles, nwItemType, nwAlert
|
||||
@@ -93,7 +93,6 @@ class GuiMain(QMainWindow):
|
||||
self.docEditor = GuiDocEditor(self)
|
||||
self.viewMeta = GuiDocViewDetails(self)
|
||||
self.docViewer = GuiDocViewer(self)
|
||||
self.searchBar = GuiSearchBar(self)
|
||||
self.treeMeta = GuiItemDetails(self)
|
||||
self.projView = GuiOutline(self)
|
||||
self.projMeta = GuiOutlineDetails(self)
|
||||
@@ -111,22 +110,13 @@ class GuiMain(QMainWindow):
|
||||
self.treeBox.addWidget(self.treeMeta)
|
||||
self.treePane.setLayout(self.treeBox)
|
||||
|
||||
self.editPane = QWidget()
|
||||
self.docEdit = QVBoxLayout()
|
||||
self.docEdit.setContentsMargins(0, 0, 0, 0)
|
||||
self.docEdit.setSpacing(self.mainConf.pxInt(2))
|
||||
self.docEdit.addWidget(self.searchBar)
|
||||
self.docEdit.addWidget(self.docEditor)
|
||||
self.editPane.setLayout(self.docEdit)
|
||||
|
||||
self.splitView = QSplitter(Qt.Vertical)
|
||||
self.splitView.addWidget(self.docViewer)
|
||||
self.splitView.addWidget(self.viewMeta)
|
||||
self.splitView.setSizes(self.mainConf.getViewPanePos())
|
||||
|
||||
self.splitDocs = QSplitter(Qt.Horizontal)
|
||||
self.splitDocs.setOpaqueResize(False)
|
||||
self.splitDocs.addWidget(self.editPane)
|
||||
self.splitDocs.addWidget(self.docEditor)
|
||||
self.splitDocs.addWidget(self.splitView)
|
||||
|
||||
self.splitOutline = QSplitter(Qt.Vertical)
|
||||
@@ -144,7 +134,6 @@ class GuiMain(QMainWindow):
|
||||
xCM = self.mainConf.pxInt(4)
|
||||
self.splitMain = QSplitter(Qt.Horizontal)
|
||||
self.splitMain.setContentsMargins(xCM, xCM, xCM, xCM)
|
||||
self.splitMain.setOpaqueResize(False)
|
||||
self.splitMain.addWidget(self.treePane)
|
||||
self.splitMain.addWidget(self.tabWidget)
|
||||
self.splitMain.setSizes(self.mainConf.getMainPanePos())
|
||||
@@ -153,7 +142,7 @@ class GuiMain(QMainWindow):
|
||||
|
||||
self.idxTree = self.splitMain.indexOf(self.treePane)
|
||||
self.idxMain = self.splitMain.indexOf(self.tabWidget)
|
||||
self.idxEditor = self.splitDocs.indexOf(self.editPane)
|
||||
self.idxEditor = self.splitDocs.indexOf(self.docEditor)
|
||||
self.idxViewer = self.splitDocs.indexOf(self.splitView)
|
||||
self.idxViewDoc = self.splitView.indexOf(self.docViewer)
|
||||
self.idxViewMeta = self.splitView.indexOf(self.viewMeta)
|
||||
@@ -168,7 +157,7 @@ class GuiMain(QMainWindow):
|
||||
self.splitView.setCollapsible(self.idxViewMeta, False)
|
||||
|
||||
self.splitView.setVisible(False)
|
||||
self.searchBar.setVisible(False)
|
||||
self.docEditor.closeSearch()
|
||||
|
||||
# Build the Tree View
|
||||
self.treeView.itemSelectionChanged.connect(self._treeSingleClick)
|
||||
@@ -487,6 +476,37 @@ class GuiMain(QMainWindow):
|
||||
return False
|
||||
return True
|
||||
|
||||
def openNextDocument(self, tHandle, wrapAround=False):
|
||||
"""Opens the next document in the project tree, following the
|
||||
document with the given handle. Stops when reaching the end.
|
||||
"""
|
||||
if self.hasProject:
|
||||
self.treeView.flushTreeOrder()
|
||||
nHandle = None # The next handle after tHandle
|
||||
fHandle = None # The first file handle we encounter
|
||||
foundIt = False # We've found tHandle, pick the next we see
|
||||
for tItem in self.theProject.projTree:
|
||||
if tItem is None:
|
||||
continue
|
||||
if tItem.itemType != nwItemType.FILE:
|
||||
continue
|
||||
if fHandle is None:
|
||||
fHandle = tItem.itemHandle
|
||||
if tItem.itemHandle == tHandle:
|
||||
foundIt = True
|
||||
elif foundIt:
|
||||
nHandle = tItem.itemHandle
|
||||
break
|
||||
|
||||
if nHandle is not None:
|
||||
self.openDocument(nHandle, tLine=0)
|
||||
return True
|
||||
elif wrapAround:
|
||||
self.openDocument(fHandle, tLine=0)
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
def saveDocument(self):
|
||||
"""Save the current documents.
|
||||
"""
|
||||
@@ -601,15 +621,13 @@ class GuiMain(QMainWindow):
|
||||
return True
|
||||
|
||||
def passDocumentAction(self, theAction):
|
||||
"""Pass on document action theAction to whatever document has
|
||||
the focus. If no document has focus, the action is discarded.
|
||||
"""Pass on document action theAction to the document viewer if
|
||||
it has focus, otherwise pass it to the document editor.
|
||||
"""
|
||||
if self.docEditor.hasFocus():
|
||||
self.docEditor.docAction(theAction)
|
||||
elif self.docViewer.hasFocus():
|
||||
if self.docViewer.hasFocus():
|
||||
self.docViewer.docAction(theAction)
|
||||
else:
|
||||
logger.debug("Document action requested, but no document has focus")
|
||||
self.docEditor.docAction(theAction)
|
||||
return True
|
||||
|
||||
##
|
||||
@@ -1075,8 +1093,8 @@ class GuiMain(QMainWindow):
|
||||
"""When the escape key is pressed somewhere in the main window,
|
||||
do the following, in order:
|
||||
"""
|
||||
if self.searchBar.isVisible():
|
||||
self.searchBar.setVisible(False)
|
||||
if self.docEditor.docSearch.isVisible():
|
||||
self.docEditor.closeSearch()
|
||||
return
|
||||
elif self.isZenMode:
|
||||
self.toggleZenMode()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[Main]
|
||||
timestamp = 2020-06-13 22:59:36
|
||||
timestamp = 2020-06-17 19:45:53
|
||||
theme = default
|
||||
syntax = default_light
|
||||
icons = typicons_colour_light
|
||||
@@ -55,6 +55,12 @@ askbeforebackup = True
|
||||
showrefpanel = True
|
||||
viewcomments = True
|
||||
viewsynopsis = True
|
||||
searchcase = False
|
||||
searchword = False
|
||||
searchregex = False
|
||||
searchloop = False
|
||||
searchnextfile = False
|
||||
searchmatchcap = False
|
||||
|
||||
[Path]
|
||||
lastpath =
|
||||
|
||||