[PictureLoader] Allow saving downloaded images to local storage and not just the QNetworkManager cache (#6620)

* [PictureLoader] Allow saving downloaded images to local storage and not just the QNetworkManager cache.

Took 1 hour 11 minutes

Took 4 seconds


Took 25 seconds

* Give people options from a dropdown.

Took 1 hour 6 minutes

Took 3 seconds

* Simplify directory removal code.

Took 5 minutes

Took 8 seconds

* Merge pull request #8

* Create new category for new settings

* Split off storage settings

Took 47 minutes

Took 4 seconds

* Allow toggling between caching methods.

Took 1 hour 30 minutes

Took 9 seconds

* Adjust settings dialog.

Took 5 minutes

Took 59 seconds

Took 22 seconds

Took 6 seconds

* tr() strings

Took 1 minute

Took 6 seconds

* Readjust layout, default naming scheme.

Took 5 minutes

* Add stretch.

Took 9 minutes

* Make scrollable.

Took 2 minutes

* Add icon.

Took 7 minutes

* Change naming to be uniform.

Took 3 minutes

Took 3 seconds

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
Co-authored-by: RickyRister <42636155+RickyRister@users.noreply.github.com>
This commit is contained in:
BruebachL 2026-05-16 20:15:10 +02:00 committed by GitHub
parent 20cd7ce73d
commit f8ce5c2e39
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 1382 additions and 132 deletions

View file

@ -69,6 +69,7 @@
<file>resources/config/interface.svg</file>
<file>resources/config/messages.svg</file>
<file>resources/config/deckeditor.svg</file>
<file>resources/config/storage.svg</file>
<file>resources/config/shorcuts.svg</file>
<file>resources/config/sound.svg</file>
<file>resources/config/debug.ini</file>

View file

@ -0,0 +1,799 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
width="62.636364"
height="62.090908"
id="svg2"
sodipodi:version="0.32"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
sodipodi:docname="storage.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"><defs
id="defs4"><linearGradient
id="linearGradient3169"><stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop3171" /><stop
style="stop-color:#000067;stop-opacity:1;"
offset="1"
id="stop3173" /></linearGradient><linearGradient
id="linearGradient4766"><stop
style="stop-color:#784421;stop-opacity:1;"
offset="0"
id="stop4768" /><stop
style="stop-color:#3d2210;stop-opacity:0;"
offset="1"
id="stop4770" /></linearGradient><linearGradient
id="linearGradient4758"><stop
style="stop-color:#a05a2c;stop-opacity:1;"
offset="0"
id="stop4760" /><stop
style="stop-color:#3d2210;stop-opacity:1;"
offset="1"
id="stop4762" /></linearGradient><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" /><inkscape:perspective
id="perspective2484"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 526.18109 : 1"
sodipodi:type="inkscape:persp3d" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4758"
id="linearGradient4764"
x1="466.09601"
y1="485.96021"
x2="715.14801"
y2="485.96021"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4766"
id="linearGradient4772"
x1="496.548"
y1="485.26816"
x2="683.31201"
y2="485.26816"
gradientUnits="userSpaceOnUse" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3169"
id="radialGradient3175"
cx="120.07376"
cy="56.138123"
fx="120.07376"
fy="56.138123"
r="82.790039"
gradientTransform="matrix(1,0,0,0.2116376,0,44.257186)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6482"
id="linearGradient6488"
x1="32.18182"
y1="3.2835093"
x2="32.18182"
y2="13.02554"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0281354,0,0,1.0429299,85.21874,131.0326)" /><linearGradient
id="linearGradient6482"><stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop6484" /><stop
style="stop-color:#00ff00;stop-opacity:0;"
offset="1"
id="stop6486" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6464"
id="linearGradient6470"
x1="32.090908"
y1="1.8181819"
x2="31.09091"
y2="62.909088"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,-0.1818182)" /><linearGradient
id="linearGradient6464"><stop
style="stop-color:#0061ff;stop-opacity:1;"
offset="0"
id="stop6466" /><stop
style="stop-color:#001c4c;stop-opacity:1;"
offset="1"
id="stop6468" /></linearGradient><linearGradient
y2="62.909088"
x2="31.09091"
y1="1.8181819"
x1="32.090908"
gradientTransform="translate(86.2151,131.5372)"
gradientUnits="userSpaceOnUse"
id="linearGradient4477"
xlink:href="#linearGradient6464"
inkscape:collect="always" /><linearGradient
inkscape:collect="always"
id="linearGradient2916"><stop
style="stop-color:white;stop-opacity:1;"
offset="0"
id="stop2918" /><stop
style="stop-color:white;stop-opacity:0;"
offset="1"
id="stop2920" /></linearGradient><linearGradient
inkscape:collect="always"
id="linearGradient2902"><stop
style="stop-color:black;stop-opacity:1;"
offset="0"
id="stop2905" /><stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop2907" /></linearGradient><linearGradient
id="linearGradient2064"><stop
id="stop2066"
offset="0"
style="stop-color:white;stop-opacity:1;" /><stop
style="stop-color:#555753;stop-opacity:0.60000002;"
offset="0.5"
id="stop2070" /><stop
id="stop2068"
offset="1"
style="stop-color:#555753;stop-opacity:0;" /></linearGradient><linearGradient
id="linearGradient9641"><stop
style="stop-color:white;stop-opacity:1"
offset="0"
id="stop9643" /><stop
style="stop-color:#888a85;stop-opacity:1"
offset="1"
id="stop9645" /></linearGradient><linearGradient
id="linearGradient9633"><stop
style="stop-color:#eeeeec;stop-opacity:1"
offset="0"
id="stop9635" /><stop
style="stop-color:#888a85;stop-opacity:1"
offset="1"
id="stop9639" /></linearGradient><linearGradient
id="linearGradient9613"><stop
style="stop-color:white;stop-opacity:1"
offset="0"
id="stop9615" /><stop
id="stop9619"
offset="0.5"
style="stop-color:white;stop-opacity:1;" /><stop
style="stop-color:#cccfca;stop-opacity:1"
offset="1"
id="stop9617" /></linearGradient><linearGradient
id="linearGradient8710"><stop
style="stop-color:black;stop-opacity:1;"
offset="0"
id="stop8712" /><stop
style="stop-color:white;stop-opacity:1;"
offset="1"
id="stop8714" /></linearGradient><linearGradient
id="linearGradient8631"><stop
id="stop8633"
offset="0"
style="stop-color:#eeeeec;stop-opacity:1" /><stop
style="stop-color:#eeeeec;stop-opacity:1;"
offset="0.2"
id="stop8637" /><stop
id="stop8635"
offset="1"
style="stop-color:#babdb6;stop-opacity:1" /></linearGradient><linearGradient
id="linearGradient8625"><stop
id="stop8627"
offset="0"
style="stop-color:white;stop-opacity:1" /><stop
id="stop8629"
offset="1"
style="stop-color:#babdb6;stop-opacity:1" /></linearGradient><linearGradient
id="linearGradient8613"><stop
style="stop-color:#babdb6;stop-opacity:1"
offset="0"
id="stop8615" /><stop
style="stop-color:#2e3436;stop-opacity:1"
offset="1"
id="stop8617" /></linearGradient><linearGradient
id="linearGradient5740"><stop
style="stop-color:#d0d0cb;stop-opacity:1;"
offset="0"
id="stop5742" /><stop
style="stop-color:#babdb6;stop-opacity:1"
offset="1"
id="stop5744" /></linearGradient><linearGradient
id="linearGradient5690"><stop
style="stop-color:white;stop-opacity:1;"
offset="0"
id="stop5692" /><stop
style="stop-color:#888a85;stop-opacity:0.59848487"
offset="1"
id="stop5694" /></linearGradient><linearGradient
id="linearGradient2899"><stop
id="stop2901"
offset="0"
style="stop-color:#555753;stop-opacity:1" /><stop
id="stop2903"
offset="1"
style="stop-color:#2e3436;stop-opacity:1" /></linearGradient><linearGradient
id="linearGradient3468"><stop
style="stop-color:#fdfdfc;stop-opacity:1"
offset="0"
id="stop3470" /><stop
style="stop-color:white;stop-opacity:0.37121212"
offset="1"
id="stop3472" /></linearGradient><linearGradient
id="linearGradient2909"><stop
style="stop-color:white;stop-opacity:0;"
offset="0"
id="stop2911" /><stop
id="stop2917"
offset="0.5"
style="stop-color:white;stop-opacity:1;" /><stop
style="stop-color:white;stop-opacity:0;"
offset="1"
id="stop2913" /></linearGradient><linearGradient
id="linearGradient2839"><stop
style="stop-color:white;stop-opacity:0.25773194;"
offset="0"
id="stop2841" /><stop
id="stop2847"
offset="0.5472973"
style="stop-color:white;stop-opacity:1;" /><stop
style="stop-color:white;stop-opacity:0.24705882;"
offset="0.66243607"
id="stop2849" /><stop
id="stop2851"
offset="0.875"
style="stop-color:white;stop-opacity:0.83505154;" /><stop
style="stop-color:white;stop-opacity:0;"
offset="1"
id="stop2843" /></linearGradient><linearGradient
id="linearGradient2900"><stop
style="stop-color:black;stop-opacity:0;"
offset="0"
id="stop2902" /><stop
id="stop2908"
offset="0.5"
style="stop-color:black;stop-opacity:1;" /><stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop2904" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3468"
id="linearGradient3474"
x1="24.748737"
y1="35.354588"
x2="24.998737"
y2="14.997767"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.995556,0,-3.931113)" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2902"
id="radialGradient4700"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(4.095822,0,0,3.101282,-9.53921,-94.5433)"
cx="0"
cy="17"
fx="0"
fy="17"
r="2" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2902"
id="radialGradient4702"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(4.095822,0,0,3.101282,38.20996,-10.90025)"
cx="0"
cy="17"
fx="0"
fy="17"
r="2" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2900"
id="linearGradient4704"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.047911,0,0,2.067521,1.347566,6.673675)"
x1="9.8994951"
y1="20"
x2="9.8994951"
y2="13.979153" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2909"
id="linearGradient4711"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,1.42294,10.5,-14.95703)"
x1="15.335379"
y1="33.06237"
x2="20.329321"
y2="36.37693" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2909"
id="linearGradient4713"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,1.42294,-0.875,-15.04578)"
x1="15.335379"
y1="33.06237"
x2="20.329321"
y2="36.37693" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2909"
id="linearGradient4715"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.459833,0,-0.391165,1.370105,40.62503,-13.29892)"
x1="15.335379"
y1="33.06237"
x2="20.329321"
y2="36.37693" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5740"
id="radialGradient5748"
cx="25.251999"
cy="16.47991"
fx="25.251999"
fy="16.47991"
r="21.980215"
gradientTransform="matrix(1.032991,-0.596398,0.575121,0.99614,-12.23456,11.55448)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2064"
id="linearGradient5790"
gradientUnits="userSpaceOnUse"
x1="18.048874"
y1="25.461344"
x2="22.211937"
y2="12.143078"
gradientTransform="matrix(0.940224,0,0,0.931632,1.331811,1.401537)" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient8631"
id="linearGradient5865"
x1="24"
y1="36.638382"
x2="25.818018"
y2="6.8314762"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2839"
id="linearGradient7658"
gradientUnits="userSpaceOnUse"
x1="27.057796"
y1="12.669416"
x2="32.042896"
y2="31.219666" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5690"
id="linearGradient8603"
x1="20.304037"
y1="24.035707"
x2="18.498415"
y2="40.647167"
gradientUnits="userSpaceOnUse" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8613"
id="radialGradient8619"
cx="7.5177727"
cy="30.573555"
fx="7.5177727"
fy="30.573555"
r="0.53125"
gradientTransform="matrix(1.662477,0,0,1.61358,-4.989175,-18.65647)"
gradientUnits="userSpaceOnUse" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient9613"
id="radialGradient8623"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.389748,0,0,1.348872,-2.91982,-10.63815)"
cx="7.5191436"
cy="30.304251"
fx="7.5191436"
fy="30.304251"
r="0.53125" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient9633"
id="radialGradient8664"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.569487,0,0,1.523325,-4.288627,-15.92107)"
cx="7.5336008"
cy="30.307562"
fx="7.5336008"
fy="30.307562"
r="0.53125" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8613"
id="radialGradient8666"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.662477,0,0,1.61358,-4.989175,-18.65647)"
cx="7.5177727"
cy="30.573555"
fx="7.5177727"
fy="30.573555"
r="0.53125" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8625"
id="radialGradient8676"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.662477,0,0,1.61358,-4.989175,-18.65647)"
cx="7.4792061"
cy="30.36071"
fx="7.4792061"
fy="30.36071"
r="0.53125" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8613"
id="radialGradient8678"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.662477,0,0,1.61358,-4.989175,-18.65647)"
cx="7.5177727"
cy="30.573555"
fx="7.5177727"
fy="30.573555"
r="0.53125" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient9641"
id="radialGradient8680"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.662477,0,0,1.61358,-4.989175,-18.65647)"
cx="7.4893188"
cy="30.337601"
fx="7.4893188"
fy="30.337601"
r="0.53125" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8613"
id="radialGradient8682"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.662477,0,0,1.61358,-4.989175,-18.65647)"
cx="7.5177727"
cy="30.573555"
fx="7.5177727"
fy="30.573555"
r="0.53125" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient8710"
id="linearGradient8716"
x1="40.617188"
y1="30.554688"
x2="40.710938"
y2="30.359375"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient8710"
id="linearGradient9605"
gradientUnits="userSpaceOnUse"
x1="40.617188"
y1="30.554688"
x2="40.710938"
y2="30.359375"
gradientTransform="matrix(0.602867,-0.797841,0.797841,0.602867,-41.12611,44.62773)" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient8710"
id="linearGradient9649"
gradientUnits="userSpaceOnUse"
x1="40.617188"
y1="30.554688"
x2="40.710938"
y2="30.359375"
gradientTransform="rotate(-30.000012,-5.5813167,76.089146)" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient8710"
id="linearGradient9654"
gradientUnits="userSpaceOnUse"
x1="40.617188"
y1="30.554688"
x2="40.710938"
y2="30.359375"
gradientTransform="matrix(0.707107,0.527555,-0.707107,0.527555,29.0058,-24.09196)" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2916"
id="linearGradient2973"
x1="12.5"
y1="43.1875"
x2="12.5"
y2="34.045513"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2899"
id="linearGradient5655"
gradientUnits="userSpaceOnUse"
x1="53.812813"
y1="43.573235"
x2="-2.8138931"
y2="35.500015"
gradientTransform="translate(0,50)" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2902"
id="linearGradient2992"
x1="21.9375"
y1="39"
x2="21.9375"
y2="37.995617"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2902"
id="linearGradient2910"
x1="22.101398"
y1="27.658131"
x2="22.971142"
y2="20.903238"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,2)" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2916"
id="linearGradient2922"
x1="24.847851"
y1="28.908398"
x2="24.847851"
y2="25.757175"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,2)" /></defs><sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.8830488"
inkscape:cx="-3.9945275"
inkscape:cy="-14.363301"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1408"
inkscape:window-x="0"
inkscape:window-y="32"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:showpageshadow="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050" /><metadata
id="metadata7"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-86.987816,-132.85536)"><rect
style="fill:url(#linearGradient4477);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-opacity:1"
id="rect6462"
width="61.636364"
height="61.090908"
x="87.487816"
y="133.35536"
ry="5.6363635" /><rect
style="fill:url(#linearGradient6488);fill-opacity:1;fill-rule:nonzero;stroke:none"
id="rect6472"
width="59.796619"
height="13.251164"
x="88.407707"
y="134.45705"
ry="4.7325583" /><g
inkscape:label="Livello 1"
id="layer1-3"
style="display:inline"
transform="matrix(1.1537183,0,0,1.1537183,91.003924,136.40297)"><g
id="g3519"
style="opacity:0.7"
transform="matrix(1.030831,0,0,1.151147,-0.73609,-12.57431)"
inkscape:export-filename="/home/lapo/Desktop/uhm.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"><rect
transform="scale(-1)"
y="-48.024086"
x="-9.5392103"
height="12.405126"
width="8.1916437"
id="rect2884"
style="opacity:1;fill:url(#radialGradient4700);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /><rect
y="35.618961"
x="38.209965"
height="12.405126"
width="8.1916437"
id="rect2894"
style="opacity:1;fill:url(#radialGradient4702);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /><rect
y="35.618961"
x="9.5392103"
height="12.405126"
width="28.670753"
id="rect2898"
style="opacity:1;fill:url(#linearGradient4704);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /></g><g
id="g5672"
transform="translate(0,-48.99747)"><path
sodipodi:nodetypes="ccccccccccccc"
id="rect2010"
d="M 4.5182287,80.500013 H 43.481768 c 0.564099,0 1.018229,0.45413 1.018229,1.018229 v 2.963543 c 0,1.315584 -0.450231,3.018228 -2.455729,3.018228 L 40.5,87.5 v 1 h -33 v -1 l -1.8567713,1.3e-5 c -1.2712053,0 -2.1432282,-0.884627 -2.1432282,-2.255665 v -3.726106 c 0,-0.564099 0.4541297,-1.018229 1.0182282,-1.018229 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient5655);fill-opacity:1;fill-rule:nonzero;stroke:#2e3436;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" /><path
transform="translate(0,50)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2973);stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
d="m 4.59375,31.59375 v 3.729743 c 0,0.599619 0.3756505,1.104854 0.8863276,1.104854 H 42.426407 c 0.512469,0 0.979843,-0.507235 0.979843,-1.016466 V 31.59375 Z"
id="path2076"
sodipodi:nodetypes="ccccccc" /><g
transform="translate(0,50)"
style="opacity:0.5"
id="g4706"><path
style="opacity:0.109524;fill:url(#linearGradient4711);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 26.144738,32.088747 c 0,0 -1.502602,5.533939 -3.226175,5.911253 0,0 6.231378,-0.125771 6.231378,-0.125771 1.387072,-0.317461 3.358758,-5.785482 3.358758,-5.785482 z"
id="path2907"
sodipodi:nodetypes="ccccc"
inkscape:export-filename="/home/lapo/Desktop/uhm.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/lapo/Desktop/uhm.png"
sodipodi:nodetypes="ccccc"
id="path2892"
d="m 14.769738,32 c 0,0 -1.502602,5.533939 -3.226175,5.911253 0,0 6.231378,-0.125771 6.231378,-0.125771 C 19.162013,37.468021 21.133699,32 21.133699,32 Z"
style="opacity:0.109524;fill:url(#linearGradient4713);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /><path
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="/home/lapo/Desktop/uhm.png"
sodipodi:nodetypes="ccccc"
id="path2896"
d="m 34.886139,32 c 0,0 -2.212224,5.328458 -3.108503,5.691761 0,0 2.899969,-0.121101 2.899969,-0.121101 C 35.402697,37.264987 37.8125,32 37.8125,32 Z"
style="opacity:0.109524;fill:url(#linearGradient4715);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /></g></g><path
style="fill:url(#radialGradient5748);fill-opacity:1;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
d="m 11.693127,10.498788 h 24.572566 c 1.68417,0 2.396517,0.117479 3.040019,2.385005 l 5.074491,17.881119 c 0.501024,1.765471 -1.355848,2.735101 -3.040018,2.735101 H 6.6186312 c -1.868408,0 -3.4893833,-1.181417 -3.0400182,-2.735101 L 8.8290448,12.611497 c 0.5683008,-1.964905 1.1799122,-2.112709 2.8640822,-2.112709 z"
id="rect1879"
sodipodi:nodetypes="cczzcczzc"
inkscape:export-filename="/home/lapo/Desktop/uhm.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
sodipodi:type="inkscape:offset"
inkscape:radius="-0.5"
inkscape:original="M 11.6875 10.5 C 10.00333 10.5 9.4120513 10.660095 8.84375 12.625 L 3.59375 30.75 C 3.1443849 32.303684 4.7565918 33.500002 6.625 33.5 L 41.34375 33.5 C 43.02792 33.5 44.876024 32.515471 44.375 30.75 L 39.3125 12.875 C 38.668998 10.607474 37.965419 10.5 36.28125 10.5 L 11.6875 10.5 z "
style="display:inline;opacity:0.462406;fill:url(#linearGradient7658);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
id="path5806"
d="m 11.6875,11 c -0.826242,0 -1.28475,0.05742 -1.5625,0.242188 -0.2777497,0.184768 -0.5284825,0.580009 -0.8007812,1.521484 l -5.2500001,18.125 c -0.1708248,0.590628 0.021709,1.039316 0.4902344,1.4375 C 5.0329784,32.724356 5.7975106,33.000001 6.625,33 h 34.71875 c 0.744655,0 1.538941,-0.232575 2.03125,-0.609375 0.492309,-0.3768 0.719298,-0.799984 0.519531,-1.503906 l -5.0625,-17.875 C 38.52278,11.922001 38.224454,11.462814 37.910156,11.253906 37.595859,11.044998 37.112699,11 36.28125,11 Z" /><ellipse
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient8623);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path8621"
transform="matrix(-2.628602,0,0,1.777765,27.79309,-23.77739)"
cx="7.625"
cy="30.578125"
rx="0.53125"
ry="0.515625" /><path
style="fill:none;fill-opacity:1;stroke:url(#linearGradient5790);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m 16.110953,12.552805 c -0.573581,0 -1.02837,0.431821 -1.02837,0.989859 l -0.940223,3.230801 c -2.859962,1.276514 -4.6423552,3.099073 -4.6423552,5.123976 0,3.856957 6.4790242,6.987239 14.4853222,6.98724 8.006296,0 14.514705,-3.130284 14.514704,-6.98724 0,-2.039034 -1.835591,-3.875388 -4.730501,-5.153089 l -0.940224,-3.201688 c 0,-0.558038 -0.454788,-0.989859 -1.02837,-0.989859 z"
id="path2784"
sodipodi:nodetypes="cccssscccc" /><path
style="display:inline;fill:none;fill-opacity:1;stroke:url(#linearGradient3474);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
d="m 11.6875,11.500005 c -0.803124,0 -1.097168,0.07051 -1.21875,0.155556 -0.121582,0.08504 -0.357707,0.40212 -0.6875,1.306667 l -5.25,18.137786 c -0.1337204,0.366765 -0.054827,0.533865 0.3125,0.84 0.3673267,0.306136 1.066693,0.56 1.78125,0.560001 h 34.71875 c 0.639793,0 1.393345,-0.237954 1.78125,-0.52889 0.387905,-0.290935 0.488311,-0.382809 0.3125,-0.871111 L 38.375,13.242228 c -0.377206,-1.04766 -0.68208,-1.439297 -0.84375,-1.555556 -0.16167,-0.116259 -0.443711,-0.186667 -1.25,-0.186667 z"
id="path3394"
sodipodi:nodetypes="csccsccsccscc" /><g
id="g5657"
transform="translate(7,-1)"
style="opacity:0.302857"><rect
ry="0.74712253"
rx="0.75130093"
y="35.500008"
x="18.499996"
height="1.9999924"
width="14.000004"
id="rect5641"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#eeeeec;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" /><rect
y="36"
x="19"
height="1"
width="1"
id="rect5645"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" /><rect
y="36"
x="22"
height="1"
width="1"
id="rect5647"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" /><rect
y="36"
x="24"
height="1"
width="1"
id="rect5649"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" /><rect
y="36"
x="26"
height="1"
width="1"
id="rect5651"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" /><rect
y="36"
x="29"
height="1"
width="2"
id="rect5653"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" /></g><path
sodipodi:type="inkscape:offset"
inkscape:radius="-0.44194174"
inkscape:original="M 16.125 12.5625 C 15.55142 12.5625 15.09375 12.973212 15.09375 13.53125 L 14.15625 16.78125 C 11.296288 18.057765 9.5 19.881347 9.5 21.90625 C 9.5 25.763206 15.993702 28.874999 24 28.875 C 32.006296 28.874999 38.500001 25.763206 38.5 21.90625 C 38.5 19.867215 36.67616 18.027701 33.78125 16.75 L 32.84375 13.53125 C 32.843748 12.973212 32.386082 12.5625 31.8125 12.5625 L 16.125 12.5625 z "
style="display:inline;fill:url(#linearGradient5865);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path5857"
d="m 16.125,13.003906 c -0.362612,0 -0.589844,0.210942 -0.589844,0.527344 a 0.44198593,0.44198593 0 0 1 -0.01758,0.123047 l -0.9375,3.25 a 0.44198593,0.44198593 0 0 1 -0.24414,0.28125 c -1.389903,0.620369 -2.504368,1.368471 -3.25586,2.177734 -0.751491,0.809263 -1.1386718,1.661199 -1.1386717,2.542969 0,1.680455 1.4530107,3.311153 3.9980467,4.533203 2.545037,1.22205 6.114654,1.99414 10.060547,1.994141 3.945892,-1e-6 7.51551,-0.772091 10.060547,-1.994141 2.545037,-1.22205 3.998047,-2.852748 3.998047,-4.533203 0,-0.887751 -0.391823,-1.747213 -1.154297,-2.5625 -0.762474,-0.815287 -1.893636,-1.568394 -3.300781,-2.189453 a 0.44198593,0.44198593 0 0 1 -0.246094,-0.28125 l -0.9375,-3.21875 a 0.44198593,0.44198593 0 0 1 -0.01758,-0.123047 c -10e-7,-0.316404 -0.22723,-0.527344 -0.589844,-0.527344 z" /><ellipse
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.9;fill:#000000;fill-opacity:0.0530303;fill-rule:nonzero;stroke:url(#linearGradient8603);stroke-width:2.52015;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path8595"
transform="matrix(0.449978,0,0,0.349909,16.36363,12.21469)"
cx="16.970562"
cy="25.107418"
rx="7.7781744"
ry="4.2868347" /><ellipse
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient8619);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path8611"
transform="matrix(1.411772,0,0,0.969697,-3.014767,0.848485)"
cx="7.625"
cy="30.578125"
rx="0.53125"
ry="0.515625" /><ellipse
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient8664);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.462594;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path8660"
transform="matrix(-2.628602,0,0,1.777765,60.79309,-23.77739)"
cx="7.625"
cy="30.578125"
rx="0.53125"
ry="0.515625" /><ellipse
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient8666);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path8662"
transform="matrix(1.411772,0,0,0.969697,29.98523,0.848485)"
cx="7.625"
cy="30.578125"
rx="0.53125"
ry="0.515625" /><ellipse
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient8676);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path8668"
transform="matrix(-2.628602,0,0,1.777765,31.79309,-40.77739)"
cx="7.625"
cy="30.578125"
rx="0.53125"
ry="0.515625" /><ellipse
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient8678);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path8670"
transform="matrix(1.411772,0,0,0.969697,0.985233,-16.15152)"
cx="7.625"
cy="30.578125"
rx="0.53125"
ry="0.515625" /><ellipse
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient8680);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path8672"
transform="matrix(-2.628602,0,0,1.777765,56.3029,-40.77739)"
cx="7.625"
cy="30.578125"
rx="0.53125"
ry="0.515625" /><ellipse
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#radialGradient8682);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.4;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path8674"
transform="matrix(1.411772,0,0,0.969697,25.49504,-16.15152)"
cx="7.625"
cy="30.578125"
rx="0.53125"
ry="0.515625" /><path
style="opacity:0.4;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8716);stroke-width:0.3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 40.328109,30.261401 0.874999,0.430332"
id="path8700" /><path
style="display:inline;opacity:0.4;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient9605);stroke-width:0.3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 7.330186,30.695906 8.201031,30.257228"
id="path9603" /><path
style="display:inline;opacity:0.4;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient9649);stroke-width:0.3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 11.263531,13.446473 0.972937,-0.06482"
id="path9647" /><path
style="display:inline;opacity:0.4;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient9654);stroke-width:0.3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 36.124038,13.147874 0.314427,0.688634"
id="path9652" /><rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.12;fill:url(#linearGradient2992);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.681836;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="rect2984"
width="32.03125"
height="1"
x="8"
y="38" /><path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.12;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2910);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
d="M 10.460155,15.082355 6.8513979,27.675762 C 8.2982685,28.375511 10.625,29.167061 10.429825,31.533131 H 37.299883 C 37.869398,29.640915 39.875,28.375 41.34614,28.25 L 37.498106,15.082355 32.350135,12.523347 H 14.318912 Z"
id="path1997"
sodipodi:nodetypes="ccccccccc" /><path
sodipodi:nodetypes="ccccc"
id="path2912"
d="m 7.9763979,27.050762 c 1.4468706,0.699749 3.1789321,1.433241 3.4256991,3.357369 H 36.857941 C 37.427456,28.515915 38.875,27.5 40.34614,27.375 Z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.834286;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2922);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" /></g></g></svg>

After

Width:  |  Height:  |  Size: 40 KiB

View file

@ -1,5 +1,7 @@
#include "cache_settings.h"
#include "../../interface/card_picture_loader/card_picture_loader_cache_method.h"
#include "../../interface/card_picture_loader/card_picture_loader_local_schemes.h"
#include "../network/update/client/release_channel.h"
#include "card_counter_settings.h"
#include "version_string.h"
@ -278,6 +280,16 @@ SettingsCache::SettingsCache()
networkCacheSize = settings->value("personal/networkCacheSize", NETWORK_CACHE_SIZE_DEFAULT).toInt();
redirectCacheTtl = settings->value("personal/redirectCacheTtl", NETWORK_REDIRECT_CACHE_TTL_DEFAULT).toInt();
cardPictureLoaderCacheMethod =
settings
->value("personal/cardPictureLoaderCacheMethod",
static_cast<int>(CardPictureLoaderCacheMethod::CacheMethod::NETWORK_CACHE))
.toInt();
localCardImageStorageNamingScheme =
settings
->value("personal/localCardImageStorageNamingScheme",
static_cast<int>(CardPictureLoaderLocalSchemes::NamingScheme::Set_Folder_Name_Set_Collector))
.toInt();
picDownload = settings->value("personal/picturedownload", true).toBool();
showStatusBar = settings->value("personal/showStatusBar", false).toBool();
@ -1112,6 +1124,13 @@ void SettingsCache::setPixmapCacheSize(const int _pixmapCacheSize)
emit pixmapCacheSizeChanged(pixmapCacheSize);
}
void SettingsCache::setCardImageCacheMethod(const CardPictureLoaderCacheMethod::CacheMethod _cardImageCachingMethod)
{
cardPictureLoaderCacheMethod = static_cast<int>(_cardImageCachingMethod);
settings->setValue("personal/cardPictureLoaderCacheMethod", cardPictureLoaderCacheMethod);
emit cardPictureLoaderCacheMethodChanged(cardPictureLoaderCacheMethod);
}
void SettingsCache::setNetworkCacheSizeInMB(const int _networkCacheSize)
{
networkCacheSize = _networkCacheSize;
@ -1126,6 +1145,14 @@ void SettingsCache::setNetworkRedirectCacheTtl(const int _redirectCacheTtl)
emit redirectCacheTtlChanged(redirectCacheTtl);
}
void SettingsCache::setLocalCardImageStorageNamingScheme(
const CardPictureLoaderLocalSchemes::NamingScheme _localCardImageStorageNamingScheme)
{
localCardImageStorageNamingScheme = static_cast<int>(_localCardImageStorageNamingScheme);
settings->setValue("personal/localCardImageStorageNamingScheme", localCardImageStorageNamingScheme);
emit localCardImageStorageNamingSchemeChanged(localCardImageStorageNamingScheme);
}
void SettingsCache::setClientID(const QString &_clientID)
{
clientID = _clientID;

View file

@ -7,6 +7,8 @@
#ifndef SETTINGSCACHE_H
#define SETTINGSCACHE_H
#include "../../interface/card_picture_loader/card_picture_loader_cache_method.h"
#include "../../interface/card_picture_loader/card_picture_loader_local_schemes.h"
#include "shortcuts_settings.h"
#include <QDate>
@ -184,6 +186,8 @@ signals:
void pixmapCacheSizeChanged(int newSizeInMBs);
void networkCacheSizeChanged(int newSizeInMBs);
void redirectCacheTtlChanged(int newTtl);
void cardPictureLoaderCacheMethodChanged(int cardPictureLoaderCacheMethod);
void localCardImageStorageNamingSchemeChanged(int localCardImageStorageNamingScheme);
void masterVolumeChanged(int value);
void chatMentionCompleterChanged();
void downloadSpoilerTimeIndexChanged();
@ -303,6 +307,8 @@ private:
int pixmapCacheSize;
int networkCacheSize;
int redirectCacheTtl;
int cardPictureLoaderCacheMethod;
int localCardImageStorageNamingScheme;
bool scaleCards;
int verticalCardOverlapPercent;
bool showMessagePopups;
@ -786,6 +792,10 @@ public:
{
return pixmapCacheSize;
}
[[nodiscard]] CardPictureLoaderCacheMethod::CacheMethod getCardPictureLoaderCacheMethod() const
{
return static_cast<CardPictureLoaderCacheMethod::CacheMethod>(cardPictureLoaderCacheMethod);
}
[[nodiscard]] int getNetworkCacheSizeInMB() const
{
return networkCacheSize;
@ -794,6 +804,10 @@ public:
{
return redirectCacheTtl;
}
[[nodiscard]] CardPictureLoaderLocalSchemes::NamingScheme getLocalCardImageStorageNamingScheme() const
{
return static_cast<CardPictureLoaderLocalSchemes::NamingScheme>(localCardImageStorageNamingScheme);
}
[[nodiscard]] bool getScaleCards() const
{
return scaleCards;
@ -1098,8 +1112,11 @@ public slots:
void setIgnoreUnregisteredUsers(QT_STATE_CHANGED_T _ignoreUnregisteredUsers);
void setIgnoreUnregisteredUserMessages(QT_STATE_CHANGED_T _ignoreUnregisteredUserMessages);
void setPixmapCacheSize(const int _pixmapCacheSize);
void setCardImageCacheMethod(CardPictureLoaderCacheMethod::CacheMethod _cardImageCachingMethod);
void setNetworkCacheSizeInMB(const int _networkCacheSize);
void setNetworkRedirectCacheTtl(const int _redirectCacheTtl);
void setLocalCardImageStorageNamingScheme(
const CardPictureLoaderLocalSchemes::NamingScheme _localCardImageStorageNamingScheme);
void setCardScaling(const QT_STATE_CHANGED_T _scaleCards);
void setStackCardOverlapPercent(const int _verticalCardOverlapPercent);
void setShowMessagePopups(const QT_STATE_CHANGED_T _showMessagePopups);

View file

@ -150,9 +150,10 @@ void CardPictureLoader::getPixmap(QPixmap &pixmap, const ExactCard &card, QSize
void CardPictureLoader::imageLoaded(const ExactCard &card, const QImage &image)
{
QPixmap finalPixmap;
if (image.isNull()) {
qCDebug(CardPictureLoaderLog) << "Caching NULL pixmap for" << card.getName();
QPixmapCache::insert(card.getPixmapCacheKey(), QPixmap());
} else {
if (card.getInfo().getUiAttributes().upsideDownArt) {
#if (QT_VERSION >= QT_VERSION_CHECK(6, 9, 0))
@ -160,12 +161,19 @@ void CardPictureLoader::imageLoaded(const ExactCard &card, const QImage &image)
#else
QImage mirrorImage = image.mirrored(true, true);
#endif
QPixmapCache::insert(card.getPixmapCacheKey(), QPixmap::fromImage(mirrorImage));
finalPixmap = QPixmap::fromImage(mirrorImage);
} else {
QPixmapCache::insert(card.getPixmapCacheKey(), QPixmap::fromImage(image));
finalPixmap = QPixmap::fromImage(image);
}
}
QPixmapCache::insert(card.getPixmapCacheKey(), finalPixmap);
if (SettingsCache::instance().getCardPictureLoaderCacheMethod() ==
CardPictureLoaderCacheMethod::CacheMethod::FILESYSTEM_CACHE) {
saveCardImageToLocalStorage(card, finalPixmap);
}
// imageLoaded should only be reached if the exactCard isn't already in cache.
// (plus there's a deduplication mechanism in CardPictureLoaderWorker)
// It should be safe to connect the CardInfo here without worrying about redundant connections.
@ -175,6 +183,88 @@ void CardPictureLoader::imageLoaded(const ExactCard &card, const QImage &image)
card.emitPixmapUpdated();
}
void CardPictureLoader::saveCardImageToLocalStorage(const ExactCard &card, const QPixmap &pixmap)
{
if (pixmap.isNull() || !card) {
return;
}
const QString picsRoot = SettingsCache::instance().getPicsPath();
CardPictureLoaderLocalSchemes::NamingScheme scheme =
SettingsCache::instance().getLocalCardImageStorageNamingScheme();
QString pattern;
for (const auto &s : CardPictureLoaderLocalSchemes::exportSchemes()) {
if (s.id == scheme) {
pattern = s.pattern;
break;
}
}
if (picsRoot.isEmpty() || pattern.isEmpty()) {
return;
}
// Base directory: <picsPath>/downloadedPics
QDir baseDir(picsRoot);
if (!baseDir.exists("downloadedPics")) {
baseDir.mkpath("downloadedPics");
}
baseDir.cd("downloadedPics");
// Collect card metadata
const QString cardName = card.getInfo().getCorrectedName();
QString setName;
QString collectorNumber;
QString uuid;
PrintingInfo printing = card.getPrinting();
if (printing.getSet()) {
setName = printing.getSet()->getCorrectedShortName();
collectorNumber = printing.getProperty("num");
uuid = printing.getUuid();
}
// Build path from scheme
QString relativePath =
CardPictureLoaderLocalSchemes::expandPattern(pattern, cardName, setName, collectorNumber, uuid);
if (relativePath.isEmpty()) {
return;
}
// append extension
relativePath += ".png";
// Normalize slashes
relativePath = QDir::cleanPath(relativePath);
QFileInfo outInfo(baseDir.filePath(relativePath));
// Do not overwrite existing files
if (outInfo.exists()) {
return;
}
QDir outDir = outInfo.dir();
// Ensure directory exists
if (!outDir.exists()) {
if (!baseDir.mkpath(outDir.path())) {
qCWarning(CardPictureLoaderLog) << "Failed to create directory for downloaded card image:" << outDir.path();
return;
}
}
// Save image
QImage image = pixmap.toImage();
if (!image.save(outInfo.absoluteFilePath(), "PNG")) {
qCWarning(CardPictureLoaderLog) << "Failed to save card image to" << outInfo.absoluteFilePath();
}
}
void CardPictureLoader::clearPixmapCache()
{
QPixmapCache::clear();

View file

@ -117,6 +117,7 @@ public slots:
* @param image Loaded QImage.
*/
void imageLoaded(const ExactCard &card, const QImage &image);
void saveCardImageToLocalStorage(const ExactCard &card, const QPixmap &pixmap);
private slots:
/**

View file

@ -0,0 +1,31 @@
#ifndef COCKATRICE_CARD_PICTURE_LOADER_CACHE_METHOD_H
#define COCKATRICE_CARD_PICTURE_LOADER_CACHE_METHOD_H
#include <QCoreApplication>
#include <QList>
#include <QString>
namespace CardPictureLoaderCacheMethod
{
enum class CacheMethod
{
NETWORK_CACHE,
FILESYSTEM_CACHE
};
struct CacheMethodInfo
{
CacheMethod id;
QString displayName;
};
static inline const QList<CacheMethodInfo> methods()
{
static QList<CacheMethodInfo> all = {
{CacheMethod::NETWORK_CACHE, QCoreApplication::translate("CardPictureLoaderCacheMethod", "Network Cache")},
{CacheMethod::FILESYSTEM_CACHE, QCoreApplication::translate("CardPictureLoaderCacheMethod", "Filesystem")},
};
return all;
}
} // namespace CardPictureLoaderCacheMethod
#endif // COCKATRICE_CARD_PICTURE_LOADER_CACHE_METHOD_H

View file

@ -1,6 +1,7 @@
#include "card_picture_loader_local.h"
#include "../../client/settings/cache_settings.h"
#include "card_picture_loader_local_schemes.h"
#include "card_picture_to_load.h"
#include <QDirIterator>
@ -77,26 +78,8 @@ QImage CardPictureLoaderLocal::tryLoadCardImageFromDisk(const QString &setName,
imgReader.setDecideFormatFromContent(true);
// Most-to-least specific, these will fall through in order.
QStringList nameVariants;
// cardName_providerId
if (!providerId.isEmpty()) {
nameVariants << QString("%1-%2").arg(correctedCardName, providerId)
<< QString("%1_%2").arg(correctedCardName, providerId);
}
// cardName_setName_collectorNumber & setName-collectorNumber-cardName
if (!setName.isEmpty() && !collectorNumber.isEmpty()) {
nameVariants << QString("%1_%2_%3").arg(correctedCardName, setName, collectorNumber)
<< QString("%1-%2-%3").arg(setName, collectorNumber, correctedCardName);
}
// cardName_setName
if (!setName.isEmpty()) {
nameVariants << QString("%1_%2").arg(correctedCardName, setName)
<< QString("%1-%2").arg(setName, correctedCardName);
}
// cardName
nameVariants << correctedCardName;
QStringList nameVariants =
CardPictureLoaderLocalSchemes::generateImportVariants(correctedCardName, setName, collectorNumber, providerId);
for (const QString &nameVariant : nameVariants) {
if (nameVariant.isEmpty()) {

View file

@ -0,0 +1,109 @@
#ifndef COCKATRICE_CARD_PICTURE_LOADER_LOCAL_SCHEMES_H
#define COCKATRICE_CARD_PICTURE_LOADER_LOCAL_SCHEMES_H
#include <QList>
#include <QRegularExpression>
#include <QString>
#include <QStringList>
namespace CardPictureLoaderLocalSchemes
{
enum class NamingScheme
{
NameOnly,
Name_Set,
Name_Set_Collector,
Set_Collector_Name,
Name_ProviderId,
Set_Folder_Name_ProviderId,
Set_Folder_Name_Set_Collector
};
struct NamingSchemeInfo
{
NamingScheme id;
QString displayName;
QString pattern;
};
inline const QList<NamingSchemeInfo> &importSchemes()
{
static QList<NamingSchemeInfo> list = {
{NamingScheme::Name_ProviderId, "Card Name + Provider ID", "{name}_{providerId}"},
{NamingScheme::Name_Set_Collector, "Card Name + Set + Collector", "{name}_{set}_{collector}"},
{NamingScheme::Set_Collector_Name, "Set + Collector + Card Name", "{set}_{collector}_{name}"},
{NamingScheme::Name_Set, "Card Name + Set", "{name}_{set}"},
{NamingScheme::NameOnly, "Card Name", "{name}"},
};
return list;
}
inline const QList<NamingSchemeInfo> &exportSchemes()
{
static QList<NamingSchemeInfo> list = {
{NamingScheme::Set_Folder_Name_ProviderId, "Set Folder / Name + Provider ID", "{set}/{name}_{providerId}"},
{NamingScheme::Set_Folder_Name_Set_Collector, "Set Folder / Name + Set Name + Collector",
"{set}/{name}_{set}_{collector}"},
{NamingScheme::Name_ProviderId, "Card Name + Provider ID", "{name}_{providerId}"},
{NamingScheme::Name_Set_Collector, "Card Name + Set + Collector", "{name}_{set}_{collector}"},
{NamingScheme::Set_Collector_Name, "Set + Collector + Card Name", "{set}_{collector}_{name}"},
};
return list;
}
inline QString expandPattern(const QString &pattern,
const QString &name,
const QString &set,
const QString &collector,
const QString &providerId)
{
QString result = pattern;
auto replaceIfPresent = [&](const QString &token, const QString &value) -> bool {
if (!result.contains(token))
return true;
if (value.isEmpty())
return false;
result.replace(token, value);
return true;
};
if (!replaceIfPresent("{name}", name))
return {};
if (!replaceIfPresent("{set}", set))
return {};
if (!replaceIfPresent("{collector}", collector))
return {};
if (!replaceIfPresent("{providerId}", providerId))
return {};
return result;
}
inline QStringList
generateImportVariants(const QString &name, const QString &set, const QString &collector, const QString &providerId)
{
QStringList variants;
const QStringList separators = {"_", "-"};
for (const auto &scheme : importSchemes()) {
for (const QString &sep : separators) {
QString pattern = scheme.pattern;
pattern.replace("_", sep);
QString v = expandPattern(pattern, name, set, collector, providerId);
if (!v.isEmpty())
variants << v;
}
}
return variants;
}
} // namespace CardPictureLoaderLocalSchemes
#endif // COCKATRICE_CARD_PICTURE_LOADER_LOCAL_SCHEMES_H

View file

@ -26,10 +26,14 @@ CardPictureLoaderWorker::CardPictureLoaderWorker()
cache->setCacheDirectory(SettingsCache::instance().getNetworkCachePath());
cache->setMaximumCacheSize(1024L * 1024L *
static_cast<qint64>(SettingsCache::instance().getNetworkCacheSizeInMB()));
// Note: the settings is in MB, but QNetworkDiskCache uses bytes
connect(&SettingsCache::instance(), &SettingsCache::networkCacheSizeChanged, this,
[this](int newSizeInMB) { cache->setMaximumCacheSize(1024L * 1024L * static_cast<qint64>(newSizeInMB)); });
connect(&SettingsCache::instance(), &SettingsCache::networkCacheSizeChanged, cache, [this](int newSizeInMB) {
if (cache)
cache->setMaximumCacheSize(1024L * 1024L * static_cast<qint64>(newSizeInMB));
});
networkManager->setCache(cache);
// Use a ManualRedirectPolicy since we keep track of redirects in picDownloadFinished
// We can't use NoLessSafeRedirectPolicy because it is not applied with AlwaysCache
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
@ -65,14 +69,19 @@ void CardPictureLoaderWorker::queueRequest(const QUrl &url, CardPictureLoaderWor
QUrl cachedRedirect = getCachedRedirect(url);
if (!cachedRedirect.isEmpty()) {
queueRequest(cachedRedirect, worker);
} else if (cache->metaData(url).isValid()) {
// If we hit a cached url, we get to make the request for free, since it won't contribute towards the rate-limit
makeRequest(url, worker);
} else {
requestLoadQueue.append(qMakePair(url, worker));
emit imageRequestQueued(url, worker->cardToDownload.getCard(), worker->cardToDownload.getSetName());
processQueuedRequests();
return;
}
if (SettingsCache::instance().getCardPictureLoaderCacheMethod() ==
CardPictureLoaderCacheMethod::CacheMethod::NETWORK_CACHE &&
cache->metaData(url).isValid()) {
// If we hit a cached url, we get to make the request for free, since it won't contribute towards the
// rate-limit
makeRequest(url, worker);
return;
}
requestLoadQueue.append(qMakePair(url, worker));
emit imageRequestQueued(url, worker->cardToDownload.getCard(), worker->cardToDownload.getSetName());
processQueuedRequests();
}
QNetworkReply *CardPictureLoaderWorker::makeRequest(const QUrl &url, CardPictureLoaderWorkerWork *worker)
@ -87,9 +96,12 @@ QNetworkReply *CardPictureLoaderWorker::makeRequest(const QUrl &url, CardPicture
QNetworkRequest req(url);
req.setHeader(QNetworkRequest::UserAgentHeader, QString("Cockatrice %1").arg(VERSION_STRING));
req.setRawHeader("Accept", "image/avif,image/webp,image/apng,image/,/*;q=0.8");
if (!picDownload) {
req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache);
}
bool useNetworkCache = !picDownload && SettingsCache::instance().getCardPictureLoaderCacheMethod() ==
CardPictureLoaderCacheMethod::CacheMethod::NETWORK_CACHE;
req.setAttribute(QNetworkRequest::CacheLoadControlAttribute,
useNetworkCache ? QNetworkRequest::AlwaysCache : QNetworkRequest::AlwaysNetwork);
QNetworkReply *reply = networkManager->get(req);

View file

@ -1013,8 +1013,6 @@ DeckEditorSettingsPage::DeckEditorSettingsPage()
urlLinkLabel.setTextInteractionFlags(Qt::LinksAccessibleByMouse);
urlLinkLabel.setOpenExternalLinks(true);
connect(&clearDownloadedPicsButton, &QPushButton::clicked, this,
&DeckEditorSettingsPage::clearDownloadedPicsButtonClicked);
connect(&resetDownloadURLs, &QPushButton::clicked, this, &DeckEditorSettingsPage::resetDownloadedURLsButtonClicked);
auto *lpGeneralGrid = new QGridLayout;
@ -1066,49 +1064,11 @@ DeckEditorSettingsPage::DeckEditorSettingsPage()
urlListLayout->addWidget(urlToolBar);
urlListLayout->addWidget(urlList);
// pixmap cache
pixmapCacheEdit.setMinimum(PIXMAPCACHE_SIZE_MIN);
// 2047 is the max value to avoid overflowing of QPixmapCache::setCacheLimit(int size)
pixmapCacheEdit.setMaximum(PIXMAPCACHE_SIZE_MAX);
pixmapCacheEdit.setSingleStep(64);
pixmapCacheEdit.setValue(SettingsCache::instance().getPixmapCacheSize());
pixmapCacheEdit.setSuffix(" MB");
networkCacheEdit.setMinimum(NETWORK_CACHE_SIZE_MIN);
networkCacheEdit.setMaximum(NETWORK_CACHE_SIZE_MAX);
networkCacheEdit.setSingleStep(1);
networkCacheEdit.setValue(SettingsCache::instance().getNetworkCacheSizeInMB());
networkCacheEdit.setSuffix(" MB");
networkRedirectCacheTtlEdit.setMinimum(NETWORK_REDIRECT_CACHE_TTL_MIN);
networkRedirectCacheTtlEdit.setMaximum(NETWORK_REDIRECT_CACHE_TTL_MAX);
networkRedirectCacheTtlEdit.setSingleStep(1);
networkRedirectCacheTtlEdit.setValue(SettingsCache::instance().getRedirectCacheTtl());
auto networkCacheLayout = new QHBoxLayout;
networkCacheLayout->addStretch();
networkCacheLayout->addWidget(&networkCacheLabel);
networkCacheLayout->addWidget(&networkCacheEdit);
auto networkRedirectCacheLayout = new QHBoxLayout;
networkRedirectCacheLayout->addStretch();
networkRedirectCacheLayout->addWidget(&networkRedirectCacheTtlLabel);
networkRedirectCacheLayout->addWidget(&networkRedirectCacheTtlEdit);
auto pixmapCacheLayout = new QHBoxLayout;
pixmapCacheLayout->addStretch();
pixmapCacheLayout->addWidget(&pixmapCacheLabel);
pixmapCacheLayout->addWidget(&pixmapCacheEdit);
// Top Layout
lpGeneralGrid->addWidget(&picDownloadCheckBox, 0, 0);
lpGeneralGrid->addWidget(&resetDownloadURLs, 0, 1);
lpGeneralGrid->addLayout(urlListLayout, 1, 0, 1, 2);
lpGeneralGrid->addLayout(networkCacheLayout, 2, 1);
lpGeneralGrid->addLayout(networkRedirectCacheLayout, 3, 0);
lpGeneralGrid->addLayout(pixmapCacheLayout, 3, 1);
lpGeneralGrid->addWidget(&urlLinkLabel, 5, 0);
lpGeneralGrid->addWidget(&clearDownloadedPicsButton, 5, 1);
lpGeneralGrid->addWidget(&urlLinkLabel, 4, 0);
// Spoiler Layout
lpSpoilerGrid->addWidget(&mcDownloadSpoilersCheckBox, 0, 0);
@ -1123,12 +1083,6 @@ DeckEditorSettingsPage::DeckEditorSettingsPage()
connect(&mcDownloadSpoilersCheckBox, &QCheckBox::toggled, &SettingsCache::instance(),
&SettingsCache::setDownloadSpoilerStatus);
connect(&mcDownloadSpoilersCheckBox, &QCheckBox::toggled, this, &DeckEditorSettingsPage::setSpoilersEnabled);
connect(&pixmapCacheEdit, qOverload<int>(&QSpinBox::valueChanged), &SettingsCache::instance(),
&SettingsCache::setPixmapCacheSize);
connect(&networkCacheEdit, qOverload<int>(&QSpinBox::valueChanged), &SettingsCache::instance(),
&SettingsCache::setNetworkCacheSizeInMB);
connect(&networkRedirectCacheTtlEdit, qOverload<int>(&QSpinBox::valueChanged), &SettingsCache::instance(),
&SettingsCache::setNetworkRedirectCacheTtl);
mpGeneralGroupBox = new QGroupBox;
mpGeneralGroupBox->setLayout(lpGeneralGrid);
@ -1154,46 +1108,6 @@ void DeckEditorSettingsPage::resetDownloadedURLsButtonClicked()
QMessageBox::information(this, tr("Success"), tr("Download URLs have been reset."));
}
void DeckEditorSettingsPage::clearDownloadedPicsButtonClicked()
{
CardPictureLoader::clearNetworkCache();
// These are not used anymore, but we don't delete them automatically, so
// we should do it here lest we leave pictures hanging around on users'
// machines.
QString picsPath = SettingsCache::instance().getPicsPath() + "/downloadedPics/";
QStringList dirs = QDir(picsPath).entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
bool outerSuccessRemove = true;
for (const auto &dir : dirs) {
QString currentPath = picsPath + dir + "/";
QStringList files = QDir(currentPath).entryList(QDir::Files);
bool innerSuccessRemove = true;
for (int j = 0; j < files.length(); j++) {
if (!QDir(currentPath).remove(files.at(j))) {
qInfo() << "Failed to remove " + currentPath.toUtf8() + files.at(j).toUtf8();
outerSuccessRemove = false;
innerSuccessRemove = false;
}
qInfo() << "Removed " << currentPath << files.at(j);
}
if (innerSuccessRemove) {
bool success = QDir(picsPath).rmdir(dir);
if (!success) {
qInfo() << "Failed to remove inner directory" << picsPath;
} else {
qInfo() << "Removed" << currentPath;
}
}
}
if (outerSuccessRemove) {
QMessageBox::information(this, tr("Success"), tr("Downloaded card pictures have been reset."));
QDir(SettingsCache::instance().getPicsPath()).rmdir("downloadedPics");
} else {
QMessageBox::critical(this, tr("Error"), tr("One or more downloaded card pictures could not be cleared."));
}
}
void DeckEditorSettingsPage::actAddURL()
{
bool ok;
@ -1312,18 +1226,246 @@ void DeckEditorSettingsPage::retranslateUi()
tr("Do not close settings until manual update is complete"));
picDownloadCheckBox.setText(tr("Download card pictures on the fly"));
urlLinkLabel.setText(QString("<a href='%1'>%2</a>").arg(WIKI_CUSTOM_PIC_URL).arg(tr("How to add a custom URL")));
clearDownloadedPicsButton.setText(tr("Delete Downloaded Images"));
resetDownloadURLs.setText(tr("Reset Download URLs"));
updateNowButton->setText(tr("Update Spoilers"));
aAdd->setText(tr("Add New URL"));
aEdit->setText(tr("Edit URL"));
aRemove->setText(tr("Remove URL"));
}
StorageSettingsPage::StorageSettingsPage()
{
auto *lpNetworkCacheGrid = new QGridLayout;
auto *lpImageBackupGrid = new QGridLayout;
auto *lpPixmapCacheGrid = new QGridLayout;
networkCacheExplainerLabel.setWordWrap(true);
imageBackupExplainerLabel.setWordWrap(true);
pixmapCacheExplainerLabel.setWordWrap(true);
connect(&clearDownloadedPicsButton, &QPushButton::clicked, this,
&StorageSettingsPage::clearDownloadedPicsButtonClicked);
connect(&clearPixmapCacheButton, &QPushButton::clicked, this, &StorageSettingsPage::clearPixmapCacheButtonClicked);
// pixmap cache
pixmapCacheEdit.setMinimum(PIXMAPCACHE_SIZE_MIN);
// 2047 is the max value to avoid overflowing of QPixmapCache::setCacheLimit(int size)
pixmapCacheEdit.setMaximum(PIXMAPCACHE_SIZE_MAX);
pixmapCacheEdit.setSingleStep(64);
pixmapCacheEdit.setValue(SettingsCache::instance().getPixmapCacheSize());
pixmapCacheEdit.setSuffix(" MB");
// Caching method
cardPictureLoaderCacheMethodComboBox = new QComboBox;
for (auto method : CardPictureLoaderCacheMethod::methods()) {
cardPictureLoaderCacheMethodComboBox->addItem(method.displayName, static_cast<int>(method.id));
}
int currentCacheMethod = static_cast<int>(SettingsCache::instance().getCardPictureLoaderCacheMethod());
int currentIndex = cardPictureLoaderCacheMethodComboBox->findData(currentCacheMethod);
if (currentIndex >= 0) {
cardPictureLoaderCacheMethodComboBox->setCurrentIndex(currentIndex);
}
connect(cardPictureLoaderCacheMethodComboBox, qOverload<int>(&QComboBox::currentIndexChanged), this,
[this](int index) {
auto cacheMethod = static_cast<CardPictureLoaderCacheMethod::CacheMethod>(
cardPictureLoaderCacheMethodComboBox->itemData(index).toInt());
bool useNetworkCache = (cacheMethod == CardPictureLoaderCacheMethod::CacheMethod::NETWORK_CACHE);
if (useNetworkCache) {
clearImageBackupsButtonClicked();
} else {
clearDownloadedPicsButtonClicked();
}
mpNetworkCacheGroupBox->setEnabled(useNetworkCache);
mpImageBackupGroupBox->setEnabled(!useNetworkCache);
SettingsCache::instance().setCardImageCacheMethod(cacheMethod);
});
// Network Cache
networkCacheEdit.setMinimum(NETWORK_CACHE_SIZE_MIN);
networkCacheEdit.setMaximum(NETWORK_CACHE_SIZE_MAX);
networkCacheEdit.setSingleStep(1);
networkCacheEdit.setValue(SettingsCache::instance().getNetworkCacheSizeInMB());
networkCacheEdit.setSuffix(" MB");
networkRedirectCacheTtlEdit.setMinimum(NETWORK_REDIRECT_CACHE_TTL_MIN);
networkRedirectCacheTtlEdit.setMaximum(NETWORK_REDIRECT_CACHE_TTL_MAX);
networkRedirectCacheTtlEdit.setSingleStep(1);
networkRedirectCacheTtlEdit.setValue(SettingsCache::instance().getRedirectCacheTtl());
// Image Backup
localCardImageStorageNamingSchemeComboBox = new QComboBox;
for (const auto &scheme : CardPictureLoaderLocalSchemes::exportSchemes()) {
localCardImageStorageNamingSchemeComboBox->addItem(scheme.displayName, static_cast<int>(scheme.id));
}
int current = static_cast<int>(SettingsCache::instance().getLocalCardImageStorageNamingScheme());
int index = localCardImageStorageNamingSchemeComboBox->findData(current);
if (index >= 0) {
localCardImageStorageNamingSchemeComboBox->setCurrentIndex(index);
}
connect(localCardImageStorageNamingSchemeComboBox, qOverload<int>(&QComboBox::currentIndexChanged), this,
[this](int index) {
auto scheme = static_cast<CardPictureLoaderLocalSchemes::NamingScheme>(
localCardImageStorageNamingSchemeComboBox->itemData(index).toInt());
SettingsCache::instance().setLocalCardImageStorageNamingScheme(scheme);
});
connect(&clearBackupsButton, &QPushButton::clicked, this, &StorageSettingsPage::clearImageBackupsButtonClicked);
auto cacheMethodLayout = new QHBoxLayout;
cacheMethodLayout->addWidget(&cardPictureLoaderCacheMethodLabel);
cacheMethodLayout->addWidget(cardPictureLoaderCacheMethodComboBox);
auto networkCacheLayout = new QHBoxLayout;
networkCacheLayout->addWidget(&clearDownloadedPicsButton);
networkCacheLayout->addStretch();
networkCacheLayout->addWidget(&networkCacheLabel);
networkCacheLayout->addWidget(&networkCacheEdit);
auto networkRedirectCacheLayout = new QHBoxLayout;
networkRedirectCacheLayout->addStretch();
networkRedirectCacheLayout->addWidget(&networkRedirectCacheTtlLabel);
networkRedirectCacheLayout->addWidget(&networkRedirectCacheTtlEdit);
auto pixmapCacheLayout = new QHBoxLayout;
pixmapCacheLayout->addWidget(&clearPixmapCacheButton);
pixmapCacheLayout->addStretch();
pixmapCacheLayout->addWidget(&pixmapCacheLabel);
pixmapCacheLayout->addWidget(&pixmapCacheEdit);
lpNetworkCacheGrid->addWidget(&networkCacheExplainerLabel, 0, 0);
lpNetworkCacheGrid->addLayout(networkCacheLayout, 1, 0);
lpNetworkCacheGrid->addLayout(networkRedirectCacheLayout, 2, 0);
// Image Backup Layout
lpImageBackupGrid->addWidget(&imageBackupExplainerLabel, 0, 0, 1, 2);
lpImageBackupGrid->addWidget(&localCardImageStorageNamingSchemeLabel, 1, 0);
lpImageBackupGrid->addWidget(localCardImageStorageNamingSchemeComboBox, 1, 1);
lpImageBackupGrid->addWidget(&clearBackupsButton, 2, 0);
lpPixmapCacheGrid->addWidget(&pixmapCacheExplainerLabel, 0, 0);
lpPixmapCacheGrid->addLayout(pixmapCacheLayout, 1, 0);
connect(&pixmapCacheEdit, qOverload<int>(&QSpinBox::valueChanged), &SettingsCache::instance(),
&SettingsCache::setPixmapCacheSize);
connect(&networkCacheEdit, qOverload<int>(&QSpinBox::valueChanged), &SettingsCache::instance(),
&SettingsCache::setNetworkCacheSizeInMB);
connect(&networkRedirectCacheTtlEdit, qOverload<int>(&QSpinBox::valueChanged), &SettingsCache::instance(),
&SettingsCache::setNetworkRedirectCacheTtl);
mpCacheMethodGroupBox = new QGroupBox;
mpCacheMethodGroupBox->setLayout(cacheMethodLayout);
mpNetworkCacheGroupBox = new QGroupBox;
mpNetworkCacheGroupBox->setLayout(lpNetworkCacheGrid);
mpImageBackupGroupBox = new QGroupBox;
mpImageBackupGroupBox->setLayout(lpImageBackupGrid);
mpPixmapCacheGroupBox = new QGroupBox;
mpPixmapCacheGroupBox->setLayout(lpPixmapCacheGrid);
auto *lpMainLayout = new QVBoxLayout;
lpMainLayout->addWidget(mpCacheMethodGroupBox);
lpMainLayout->addWidget(mpNetworkCacheGroupBox);
lpMainLayout->addWidget(mpImageBackupGroupBox);
lpMainLayout->addWidget(mpPixmapCacheGroupBox);
lpMainLayout->addStretch();
setLayout(lpMainLayout);
bool useNetworkCache = SettingsCache::instance().getCardPictureLoaderCacheMethod() ==
CardPictureLoaderCacheMethod::CacheMethod::NETWORK_CACHE;
mpNetworkCacheGroupBox->setEnabled(useNetworkCache);
mpImageBackupGroupBox->setEnabled(!useNetworkCache);
connect(&SettingsCache::instance(), &SettingsCache::langChanged, this, &StorageSettingsPage::retranslateUi);
retranslateUi();
}
void StorageSettingsPage::clearDownloadedPicsButtonClicked()
{
CardPictureLoader::clearNetworkCache();
CardPictureLoader::clearPixmapCache();
QMessageBox::information(this, tr("Success"), tr("Cached card pictures have been reset."));
}
void StorageSettingsPage::clearImageBackupsButtonClicked()
{
QString picsPath = SettingsCache::instance().getPicsPath() + "/downloadedPics";
QDir dir(picsPath);
bool success = dir.removeRecursively();
CardPictureLoader::clearPixmapCache();
if (success) {
QMessageBox::information(this, tr("Success"), tr("Downloaded card pictures have been reset."));
} else {
QMessageBox::critical(this, tr("Error"), tr("One or more downloaded card pictures could not be cleared."));
}
}
void StorageSettingsPage::clearPixmapCacheButtonClicked()
{
CardPictureLoader::clearPixmapCache();
QMessageBox::information(this, tr("Success"), tr("In-memory (currently loaded) card pictures have been reset."));
}
void StorageSettingsPage::retranslateUi()
{
cardPictureLoaderCacheMethodLabel.setText(tr("Card Picture Loader Caching Method:"));
networkCacheExplainerLabel.setText(
tr("The network cache is the preferred way of storing images. Downloaded images "
"are stored here until the size of the cache exceeds the configured size. Cockatrice automatically monitors "
"this cache and deletes the least recently seen card images to ensure the cache does not exceed the "
"configured size."));
imageBackupExplainerLabel.setText(
tr("Writing card images directly to a folder on your hard drive is another way "
"of storing images. This does not change how Cockatrice accesses or downloads "
"images. Cockatrice will NOT automatically monitor and clear this folder, so if you enable this option, it "
"is up to you to ensure sufficient available space. It should also be noted that if a provider outage "
"causes you to download the wrong picture (i.e. wrong printing) you will be stuck with it until you "
"manually delete the file, as opposed to using the network cache, which automatically rotates and thus "
"correct errors after a while."));
pixmapCacheExplainerLabel.setText(
tr("This is the in-memory picture cache used by the application at runtime. It determines how much memory "
"(RAM) Cockatrice can use before it has to fetch card images from the hard disk again. Increasing this will "
"allow more card images to be displayed at once but shouldn't be necessary. Clearing this will make "
"Cockatrice reload all images from the network cache or the disk."));
clearDownloadedPicsButton.setText(tr("Delete Cached Images"));
clearBackupsButton.setText(tr("Delete Saved Images"));
clearPixmapCacheButton.setText(tr("Clear In-Memory Images"));
mpCacheMethodGroupBox->setTitle(tr("Card Picture Loader Cache Method"));
mpNetworkCacheGroupBox->setTitle(tr("Network Cache"));
mpImageBackupGroupBox->setTitle(tr("Filesystem"));
mpPixmapCacheGroupBox->setTitle(tr("In-Memory Picture Cache"));
networkCacheLabel.setText(tr("Network Cache Size:"));
networkCacheEdit.setToolTip(tr("On-disk cache for downloaded pictures"));
networkRedirectCacheTtlLabel.setText(tr("Redirect Cache TTL:"));
networkRedirectCacheTtlEdit.setToolTip(tr("How long cached redirects for urls are valid for."));
pixmapCacheLabel.setText(tr("Picture Cache Size:"));
pixmapCacheEdit.setToolTip(tr("In-memory cache for pictures not currently on screen"));
updateNowButton->setText(tr("Update Spoilers"));
aAdd->setText(tr("Add New URL"));
aEdit->setText(tr("Edit URL"));
aRemove->setText(tr("Remove URL"));
localCardImageStorageNamingSchemeLabel.setText(tr("Naming scheme:"));
networkRedirectCacheTtlEdit.setSuffix(" " + tr("Day(s)"));
}
@ -1803,6 +1945,7 @@ DlgSettings::DlgSettings(QWidget *parent) : QDialog(parent)
pagesWidget->addWidget(makeScrollable(new AppearanceSettingsPage));
pagesWidget->addWidget(makeScrollable(new UserInterfaceSettingsPage));
pagesWidget->addWidget(new DeckEditorSettingsPage);
pagesWidget->addWidget(makeScrollable(new StorageSettingsPage));
pagesWidget->addWidget(new MessagesSettingsPage);
pagesWidget->addWidget(new SoundSettingsPage);
pagesWidget->addWidget(new ShortcutSettingsPage);
@ -1851,6 +1994,11 @@ void DlgSettings::createIcons()
deckEditorButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
deckEditorButton->setIcon(QPixmap("theme:config/deckeditor"));
storageButton = new QListWidgetItem(contentsWidget);
storageButton->setTextAlignment(Qt::AlignHCenter);
storageButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
storageButton->setIcon(QPixmap("theme:config/storage"));
messagesButton = new QListWidgetItem(contentsWidget);
messagesButton->setTextAlignment(Qt::AlignHCenter);
messagesButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
@ -1975,6 +2123,7 @@ void DlgSettings::retranslateUi()
generalButton->setText(tr("General"));
appearanceButton->setText(tr("Appearance"));
userInterfaceButton->setText(tr("User Interface"));
storageButton->setText(tr("Storage"));
deckEditorButton->setText(tr("Card Sources"));
messagesButton->setText(tr("Chat"));
soundButton->setText(tr("Sound"));

View file

@ -213,11 +213,9 @@ private slots:
void actAddURL();
void actRemoveURL();
void actEditURL();
void clearDownloadedPicsButtonClicked();
void resetDownloadedURLsButtonClicked();
private:
QPushButton clearDownloadedPicsButton;
QPushButton resetDownloadURLs;
QLabel urlLinkLabel;
QCheckBox picDownloadCheckBox;
@ -227,18 +225,51 @@ private:
QLabel msDownloadSpoilersLabel;
QGroupBox *mpGeneralGroupBox;
QGroupBox *mpSpoilerGroupBox;
QLineEdit *mpSpoilerSavePathLineEdit;
QLabel mcSpoilerSaveLabel;
QLabel lastUpdatedLabel;
QLabel infoOnSpoilersLabel;
QPushButton *mpSpoilerPathButton;
QPushButton *updateNowButton;
};
class StorageSettingsPage : public AbstractSettingsPage
{
Q_OBJECT
public:
StorageSettingsPage();
void retranslateUi() override;
private slots:
void clearDownloadedPicsButtonClicked();
void clearImageBackupsButtonClicked();
void clearPixmapCacheButtonClicked();
private:
QPushButton clearDownloadedPicsButton;
QPushButton clearBackupsButton;
QPushButton clearPixmapCacheButton;
QGroupBox *mpCacheMethodGroupBox;
QGroupBox *mpNetworkCacheGroupBox;
QGroupBox *mpImageBackupGroupBox;
QGroupBox *mpPixmapCacheGroupBox;
QLabel networkCacheExplainerLabel;
QLabel imageBackupExplainerLabel;
QLabel pixmapCacheExplainerLabel;
QLabel cardPictureLoaderCacheMethodLabel;
QComboBox *cardPictureLoaderCacheMethodComboBox;
QLabel networkCacheLabel;
QSpinBox networkCacheEdit;
QLabel networkRedirectCacheTtlLabel;
QSpinBox networkRedirectCacheTtlEdit;
QSpinBox pixmapCacheEdit;
QLabel pixmapCacheLabel;
QLabel localCardImageStorageNamingSchemeLabel;
QComboBox *localCardImageStorageNamingSchemeComboBox;
};
class MessagesSettingsPage : public AbstractSettingsPage
@ -353,8 +384,8 @@ private slots:
private:
QListWidget *contentsWidget;
QStackedWidget *pagesWidget;
QListWidgetItem *generalButton, *appearanceButton, *userInterfaceButton, *deckEditorButton, *messagesButton,
*soundButton, *shortcutsButton;
QListWidgetItem *generalButton, *appearanceButton, *userInterfaceButton, *deckEditorButton, *storageButton,
*messagesButton, *soundButton, *shortcutsButton;
void createIcons();
void retranslateUi();