merge and updates
10
lib/Makefile
@@ -1,24 +1,28 @@
|
||||
ifeq ($(shell uname),Darwin)
|
||||
EXT := dylib
|
||||
CFLAGS := "-mmacosx-version-min=10.11"
|
||||
else
|
||||
EXT := a
|
||||
CFLAGS := ""
|
||||
endif
|
||||
|
||||
PWD := $(shell pwd)
|
||||
|
||||
all: release
|
||||
|
||||
winrelease: target/x86_64-pc-windows-gnu/release/silentdragonlite.lib
|
||||
|
||||
target/x86_64-pc-windows-gnu/release/silentdragonlite.lib: src/lib.rs Cargo.toml
|
||||
cargo build --lib --release --target x86_64-pc-windows-gnu
|
||||
SODIUM_LIB_DIR="$(PWD)/libsodium-mingw/" cargo build --lib --release --target x86_64-pc-windows-gnu
|
||||
|
||||
release: target/release/silentdragonlite.$(EXT)
|
||||
debug: target/debug/silentdragonlite.$(EXT)
|
||||
|
||||
target/release/silentdragonlite.$(EXT): src/lib.rs Cargo.toml
|
||||
cargo build --lib --release
|
||||
CFLAGS=$(CFLAGS) cargo build --lib --release
|
||||
|
||||
target/debug/silentdragonlite.$(EXT): src/lib.rs Cargo.toml
|
||||
cargo build --lib
|
||||
CFLAGS=$(CFLAGS) cargo build --lib
|
||||
|
||||
clean:
|
||||
rm -rf target
|
||||
BIN
lib/libsodium-mingw/libsodium.a
Normal file
122
res/logo.svg
@@ -14,12 +14,25 @@
|
||||
xml:space="preserve"
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5"
|
||||
id="svg947"
|
||||
sodipodi:docname="logo2.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
|
||||
sodipodi:docname="logo.svg"
|
||||
inkscape:version="0.92.4 (f8dce91, 2019-08-02)"><metadata
|
||||
id="metadata953"><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="defs951" /><sodipodi:namedview
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs951">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</defs><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
@@ -28,107 +41,92 @@
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2493"
|
||||
inkscape:window-width="3440"
|
||||
inkscape:window-height="1385"
|
||||
id="namedview949"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.204"
|
||||
inkscape:cx="69.774919"
|
||||
inkscape:cx="-65.607141"
|
||||
inkscape:cy="327.00515"
|
||||
inkscape:window-x="67"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg947"
|
||||
units="in" />
|
||||
<g
|
||||
id="Layer1"
|
||||
transform="matrix(0.36813642,0,0,0.36813642,312.34626,301.46667)">
|
||||
<g
|
||||
transform="matrix(21.7676,-1.67174,1.56756,20.411,-1459.09,-1317.23)"
|
||||
id="g906">
|
||||
id="g906"
|
||||
transform="matrix(8.0134463,-0.61542838,0.57707593,7.5140325,-224.79791,-183.45367)">
|
||||
<path
|
||||
d="m 101.667,55.665 c 0,-4.644 -3.536,-8.415 -7.891,-8.415 H 34.391 c -4.355,0 -7.891,3.771 -7.891,8.415 v 32.67 c 0,4.644 3.536,8.415 7.891,8.415 h 59.385 c 4.355,0 7.891,-3.771 7.891,-8.415 z"
|
||||
style="fill:#403c3c;stroke:#676767;stroke-width:1.55999994px"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path904"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(10.4324,-0.762793,0.788494,10.7839,-910.913,-519.817)"
|
||||
id="g910">
|
||||
style="fill:#403c3c;stroke:#676767;stroke-width:1.55999994px"
|
||||
d="m 101.667,55.665 c 0,-4.644 -3.536,-8.415 -7.891,-8.415 H 34.391 c -4.355,0 -7.891,3.771 -7.891,8.415 v 32.67 c 0,4.644 3.536,8.415 7.891,8.415 h 59.385 c 4.355,0 7.891,-3.771 7.891,-8.415 z" />
|
||||
</g><g
|
||||
id="g910"
|
||||
transform="matrix(3.8405464,-0.28081188,0.29027336,3.9699463,-22.993991,110.1031)">
|
||||
<rect
|
||||
x="30.333"
|
||||
y="15.958"
|
||||
width="123.333"
|
||||
height="10.333"
|
||||
id="rect908"
|
||||
style="fill:#989898"
|
||||
id="rect908" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(10.4426,-0.607527,0.590589,10.1515,-857.477,-497.419)"
|
||||
id="g914">
|
||||
<rect
|
||||
x="30.333"
|
||||
y="15.958"
|
||||
width="123.333"
|
||||
height="10.333"
|
||||
width="123.333"
|
||||
y="15.958"
|
||||
x="30.333" />
|
||||
</g><g
|
||||
id="g914"
|
||||
transform="matrix(3.8443014,-0.22365281,0.21741732,3.7371369,-3.322253,118.34862)">
|
||||
<rect
|
||||
id="rect912"
|
||||
style="fill:#d4d4d4"
|
||||
id="rect912" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(22.5859,0,0,20.3805,-1392.73,-1333.51)"
|
||||
id="g918">
|
||||
height="10.333"
|
||||
width="123.333"
|
||||
y="15.958"
|
||||
x="30.333" />
|
||||
</g><g
|
||||
id="g918"
|
||||
transform="matrix(8.3146924,0,0,7.5028043,-200.36838,-189.44693)"
|
||||
style="fill:#e5e5e5;fill-opacity:1">
|
||||
<path
|
||||
d="m 101.667,55.665 c 0,-4.644 -3.403,-8.415 -7.594,-8.415 h -59.98 c -4.191,0 -7.593,3.771 -7.593,8.415 v 32.67 c 0,4.644 3.402,8.415 7.593,8.415 h 59.98 c 4.191,0 7.594,-3.771 7.594,-8.415 z"
|
||||
style="fill:#545454;stroke:#676767;stroke-width:1.54999995px"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path916"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
|
||||
|
||||
<g
|
||||
transform="matrix(22.0427,0,0,22.0427,-1356.84,-1529.77)"
|
||||
id="g940">
|
||||
<g
|
||||
transform="matrix(0.0166278,0,0,0.0169216,38.2584,49.3588)"
|
||||
style="fill:#e5e5e5;stroke:#676767;stroke-width:1.54999995px;fill-opacity:1"
|
||||
d="m 101.667,55.665 c 0,-4.644 -3.403,-8.415 -7.594,-8.415 h -59.98 c -4.191,0 -7.593,3.771 -7.593,8.415 v 32.67 c 0,4.644 3.402,8.415 7.593,8.415 h 59.98 c 4.191,0 7.594,-3.771 7.594,-8.415 z" />
|
||||
</g><g
|
||||
transform="matrix(0.13492995,0,0,0.13731406,123.30027,138.8355)"
|
||||
id="g930">
|
||||
<path
|
||||
d="m 408.79,544.347 c -4.781,393.34 11.42,829.733 222.972,1280.253 233.27,496.77 562.438,768.91 880.738,902.9 400.43,-203.47 700.25,-512.61 875.74,-926.93 C 2565.08,1390.14 2623.25,986.361 2613.93,546.64 2401.04,668.826 2190.35,711.166 1980.91,665.398 1800.1,625.888 1619.67,480.693 1504.39,342.5 1342.48,544.925 1094.45,674.584 905.24,674.128 603.662,673.4 408.79,544.347 408.79,544.347 Z"
|
||||
style="fill:#535050;stroke:#231f20;stroke-width:113.56999969px;stroke-linecap:butt;stroke-miterlimit:1.41420996"
|
||||
id="path928"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.0156112,0,0,0.01624605,39.675272,50.611315)"
|
||||
id="g934">
|
||||
</g><g
|
||||
transform="matrix(0.12668053,0,0,0.13183216,134.79779,148.99931)"
|
||||
id="g934"
|
||||
style="fill:#52ffff;fill-opacity:1">
|
||||
<path
|
||||
d="m 395.114,579.927 c -4.781,393.341 25.096,794.153 236.648,1244.673 233.27,496.77 562.438,768.91 880.738,902.9 400.43,-203.47 677.91,-509.43 866.26,-919.86 157.91,-344.09 267.28,-776.03 257.97,-1215.749 -212.9,122.186 -446.38,119.275 -655.82,73.507 C 1800.1,625.888 1626.34,498.787 1511.05,360.594 1349.14,563.019 1067.1,686.858 877.887,686.402 576.309,685.674 395.114,579.927 395.114,579.927 Z"
|
||||
style="fill:#f4b728"
|
||||
style="fill:#52ffff;fill-opacity:1"
|
||||
id="path932"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.0863573,0,0,0.0863573,43.8769,56.212)"
|
||||
</g><g
|
||||
transform="matrix(0.70076537,0,0,0.70076537,168.89283,194.4473)"
|
||||
id="g938">
|
||||
<path
|
||||
d="M 305.776,155.342 V 120.964 H 244.28 V 83.228 h -37.768 v 37.736 h -61.496 v 45.532 h 95.333 l -77.956,107.298 -17.377,22.075 v 34.377 h 61.496 v 37.616 h 4.529 v 0.153 h 28.709 v -0.153 h 4.53 v -37.616 h 61.496 V 284.714 H 210.443 L 288.4,177.416 Z"
|
||||
style="fill:#231f20;fill-rule:nonzero"
|
||||
id="path936"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
|
||||
</g><g
|
||||
</g><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
inkscape:label="Belt"
|
||||
style="display:inline"
|
||||
transform="translate(0,547.00007)"><g
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5"
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;fill:#52504f;fill-opacity:1"
|
||||
transform="matrix(3.6074755,0,0,3.1676851,24.481313,-551.22181)"
|
||||
id="g922">
|
||||
<path
|
||||
d="m 174.197,108.212 c 0,-3.207 -2.286,-5.81 -5.101,-5.81 h -31.213 c -2.816,0 -5.102,2.603 -5.102,5.81 v 13.64 c 0,3.206 2.286,5.809 5.102,5.809 h 31.213 c 2.815,0 5.101,-2.603 5.101,-5.809 z"
|
||||
style="fill:#545454;stroke:#676767;stroke-width:5.17999983px"
|
||||
style="fill:#52504f;stroke:#676767;stroke-width:5.17999983px;fill-opacity:1"
|
||||
id="path920"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g><g
|
||||
|
||||
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
145
res/logo2.svg
@@ -1,145 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="7in"
|
||||
height="7in"
|
||||
viewBox="0 0 672.00001 672.00003"
|
||||
version="1.1"
|
||||
xml:space="preserve"
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5"
|
||||
id="svg947"
|
||||
sodipodi:docname="logo2.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
|
||||
id="metadata953"><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="defs951" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2493"
|
||||
inkscape:window-height="1385"
|
||||
id="namedview949"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.204"
|
||||
inkscape:cx="69.774919"
|
||||
inkscape:cy="327.00515"
|
||||
inkscape:window-x="67"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg947"
|
||||
units="in" />
|
||||
<g
|
||||
id="Layer1"
|
||||
transform="matrix(0.36813642,0,0,0.36813642,312.34626,301.46667)">
|
||||
<g
|
||||
transform="matrix(21.7676,-1.67174,1.56756,20.411,-1459.09,-1317.23)"
|
||||
id="g906">
|
||||
<path
|
||||
d="m 101.667,55.665 c 0,-4.644 -3.536,-8.415 -7.891,-8.415 H 34.391 c -4.355,0 -7.891,3.771 -7.891,8.415 v 32.67 c 0,4.644 3.536,8.415 7.891,8.415 h 59.385 c 4.355,0 7.891,-3.771 7.891,-8.415 z"
|
||||
style="fill:#403c3c;stroke:#676767;stroke-width:1.55999994px"
|
||||
id="path904"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(10.4324,-0.762793,0.788494,10.7839,-910.913,-519.817)"
|
||||
id="g910">
|
||||
<rect
|
||||
x="30.333"
|
||||
y="15.958"
|
||||
width="123.333"
|
||||
height="10.333"
|
||||
style="fill:#989898"
|
||||
id="rect908" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(10.4426,-0.607527,0.590589,10.1515,-857.477,-497.419)"
|
||||
id="g914">
|
||||
<rect
|
||||
x="30.333"
|
||||
y="15.958"
|
||||
width="123.333"
|
||||
height="10.333"
|
||||
style="fill:#d4d4d4"
|
||||
id="rect912" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(22.5859,0,0,20.3805,-1392.73,-1333.51)"
|
||||
id="g918">
|
||||
<path
|
||||
d="m 101.667,55.665 c 0,-4.644 -3.403,-8.415 -7.594,-8.415 h -59.98 c -4.191,0 -7.593,3.771 -7.593,8.415 v 32.67 c 0,4.644 3.402,8.415 7.593,8.415 h 59.98 c 4.191,0 7.594,-3.771 7.594,-8.415 z"
|
||||
style="fill:#545454;stroke:#676767;stroke-width:1.54999995px"
|
||||
id="path916"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
|
||||
|
||||
<g
|
||||
transform="matrix(22.0427,0,0,22.0427,-1356.84,-1529.77)"
|
||||
id="g940">
|
||||
<g
|
||||
transform="matrix(0.0166278,0,0,0.0169216,38.2584,49.3588)"
|
||||
id="g930">
|
||||
<path
|
||||
d="m 408.79,544.347 c -4.781,393.34 11.42,829.733 222.972,1280.253 233.27,496.77 562.438,768.91 880.738,902.9 400.43,-203.47 700.25,-512.61 875.74,-926.93 C 2565.08,1390.14 2623.25,986.361 2613.93,546.64 2401.04,668.826 2190.35,711.166 1980.91,665.398 1800.1,625.888 1619.67,480.693 1504.39,342.5 1342.48,544.925 1094.45,674.584 905.24,674.128 603.662,673.4 408.79,544.347 408.79,544.347 Z"
|
||||
style="fill:#535050;stroke:#231f20;stroke-width:113.56999969px;stroke-linecap:butt;stroke-miterlimit:1.41420996"
|
||||
id="path928"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.0156112,0,0,0.01624605,39.675272,50.611315)"
|
||||
id="g934">
|
||||
<path
|
||||
d="m 395.114,579.927 c -4.781,393.341 25.096,794.153 236.648,1244.673 233.27,496.77 562.438,768.91 880.738,902.9 400.43,-203.47 677.91,-509.43 866.26,-919.86 157.91,-344.09 267.28,-776.03 257.97,-1215.749 -212.9,122.186 -446.38,119.275 -655.82,73.507 C 1800.1,625.888 1626.34,498.787 1511.05,360.594 1349.14,563.019 1067.1,686.858 877.887,686.402 576.309,685.674 395.114,579.927 395.114,579.927 Z"
|
||||
style="fill:#f4b728"
|
||||
id="path932"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.0863573,0,0,0.0863573,43.8769,56.212)"
|
||||
id="g938">
|
||||
<path
|
||||
d="M 305.776,155.342 V 120.964 H 244.28 V 83.228 h -37.768 v 37.736 h -61.496 v 45.532 h 95.333 l -77.956,107.298 -17.377,22.075 v 34.377 h 61.496 v 37.616 h 4.529 v 0.153 h 28.709 v -0.153 h 4.53 v -37.616 h 61.496 V 284.714 H 210.443 L 288.4,177.416 Z"
|
||||
style="fill:#231f20;fill-rule:nonzero"
|
||||
id="path936"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
|
||||
</g><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
inkscape:label="Belt"
|
||||
style="display:inline"
|
||||
transform="translate(0,547.00007)"><g
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5"
|
||||
transform="matrix(3.6074755,0,0,3.1676851,24.481313,-551.22181)"
|
||||
id="g922">
|
||||
<path
|
||||
d="m 174.197,108.212 c 0,-3.207 -2.286,-5.81 -5.101,-5.81 h -31.213 c -2.816,0 -5.102,2.603 -5.102,5.81 v 13.64 c 0,3.206 2.286,5.809 5.102,5.809 h 31.213 c 2.815,0 5.101,-2.603 5.101,-5.809 z"
|
||||
style="fill:#545454;stroke:#676767;stroke-width:5.17999983px"
|
||||
id="path920"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g><g
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5"
|
||||
transform="matrix(4.2945691,0,0,4.3255294,-62.20745,-679.73088)"
|
||||
id="g926">
|
||||
<circle
|
||||
cx="140.291"
|
||||
cy="113.78"
|
||||
r="5.006"
|
||||
style="fill:#ffffff"
|
||||
id="circle924" />
|
||||
</g></g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 451 KiB After Width: | Height: | Size: 451 KiB |
@@ -60,7 +60,8 @@ SOURCES += \
|
||||
src/viewalladdresses.cpp \
|
||||
src/datamodel.cpp \
|
||||
src/controller.cpp \
|
||||
src/liteinterface.cpp
|
||||
src/liteinterface.cpp \
|
||||
src/camount.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/firsttimewizard.h \
|
||||
@@ -88,6 +89,7 @@ HEADERS += \
|
||||
src/datamodel.h \
|
||||
src/controller.h \
|
||||
src/liteinterface.h \
|
||||
src/camount.h \
|
||||
lib/silentdragonlitelib.h
|
||||
|
||||
FORMS += \
|
||||
@@ -110,7 +112,7 @@ FORMS += \
|
||||
src/recurringdialog.ui \
|
||||
src/newrecurring.ui \
|
||||
src/requestdialog.ui \
|
||||
src/recurringmultiple.ui
|
||||
src/recurringmultiple.ui
|
||||
|
||||
|
||||
TRANSLATIONS = res/zec_qt_wallet_es.ts \
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string notr="true">silentdragon FullNode</string>
|
||||
<string notr="true">SilentDragon Lite</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
@@ -52,7 +52,7 @@
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.1pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">Copyright (c) 2018 Aditya Kulkarni. (MIT License)</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">Copyright (c) 2018-2019 Aditya Kulkarni. (MIT License)</span></p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt;"><br /></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">Special thanks to:</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Ubuntu'; font-size:11pt;">JSON for Modern C++ : </span><a href="https://nlohmann.github.io/json/"><span style=" font-size:8pt; text-decoration: underline; color:#0000ff;">https://nlohmann.github.io/json/</span></a></p>
|
||||
|
||||
@@ -24,16 +24,16 @@ void AddressCombo::setCurrentText(const QString& text) {
|
||||
}
|
||||
}
|
||||
|
||||
void AddressCombo::addItem(const QString& text, double bal) {
|
||||
void AddressCombo::addItem(const QString& text, CAmount bal) {
|
||||
QString txt = AddressBook::addLabelToAddress(text);
|
||||
if (bal > 0)
|
||||
txt = txt % "(" % Settings::gethushDisplayFormat(bal) % ")";
|
||||
if (bal.toqint64() > 0)
|
||||
txt = txt % "(" % bal.toDecimalhushString() % ")";
|
||||
|
||||
QComboBox::addItem(txt);
|
||||
}
|
||||
|
||||
void AddressCombo::insertItem(int index, const QString& text, double bal) {
|
||||
void AddressCombo::insertItem(int index, const QString& text, CAmount bal) {
|
||||
QString txt = AddressBook::addLabelToAddress(text) %
|
||||
"(" % Settings::gethushDisplayFormat(bal) % ")";
|
||||
"(" % bal.toDecimalhushString() % ")";
|
||||
QComboBox::insertItem(index, txt);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef ADDRESSCOMBO_H
|
||||
#define ADDRESSCOMBO_H
|
||||
|
||||
#include "camount.h"
|
||||
#include "precompiled.h"
|
||||
|
||||
class AddressCombo : public QComboBox
|
||||
@@ -12,8 +13,8 @@ public:
|
||||
QString itemText(int i);
|
||||
QString currentText();
|
||||
|
||||
void addItem(const QString& itemText, double bal);
|
||||
void insertItem(int index, const QString& text, double bal = 0.0);
|
||||
void addItem(const QString& itemText, CAmount bal);
|
||||
void insertItem(int index, const QString& text, CAmount bal = CAmount::fromqint64(0));
|
||||
|
||||
public slots:
|
||||
void setCurrentText(const QString& itemText);
|
||||
|
||||
@@ -1,32 +1,45 @@
|
||||
#include "balancestablemodel.h"
|
||||
#include "addressbook.h"
|
||||
#include "settings.h"
|
||||
#include "camount.h"
|
||||
|
||||
BalancesTableModel::BalancesTableModel(QObject *parent)
|
||||
: QAbstractTableModel(parent) {
|
||||
}
|
||||
|
||||
void BalancesTableModel::setNewData(const QMap<QString, double> balances,
|
||||
const QList<UnspentOutput> outputs)
|
||||
void BalancesTableModel::setNewData(const QList<QString> zaddrs, const QList<QString> taddrs,
|
||||
const QMap<QString, CAmount> balances, const QList<UnspentOutput> outputs)
|
||||
{
|
||||
loading = false;
|
||||
|
||||
int currentRows = rowCount(QModelIndex());
|
||||
// Copy over the utxos for our use
|
||||
delete utxos;
|
||||
utxos = new QList<UnspentOutput>();
|
||||
delete unspentOutputs;
|
||||
unspentOutputs = new QList<UnspentOutput>();
|
||||
|
||||
// This is a QList deep copy.
|
||||
*utxos = outputs;
|
||||
*unspentOutputs = outputs;
|
||||
|
||||
// Process the address balances into a list
|
||||
delete modeldata;
|
||||
modeldata = new QList<std::tuple<QString, double>>();
|
||||
modeldata = new QList<std::tuple<QString, CAmount>>();
|
||||
std::for_each(balances.keyBegin(), balances.keyEnd(), [=] (auto keyIt) {
|
||||
if (balances.value(keyIt) > 0)
|
||||
modeldata->push_back(std::make_tuple(keyIt, balances.value(keyIt)));
|
||||
modeldata->push_back(std::make_tuple(keyIt, balances.value(keyIt)));
|
||||
});
|
||||
|
||||
// Add all addresses that have no balances as well
|
||||
for (auto zaddr: zaddrs) {
|
||||
if (!balances.contains(zaddr)) {
|
||||
modeldata->push_back(std::make_tuple(zaddr, CAmount::fromqint64(0)));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto taddr: taddrs) {
|
||||
if (!balances.contains(taddr)) {
|
||||
modeldata->push_back(std::make_tuple(taddr, CAmount::fromqint64(0)));
|
||||
}
|
||||
}
|
||||
|
||||
// And then update the data
|
||||
dataChanged(index(0, 0), index(modeldata->size()-1, columnCount(index(0,0))-1));
|
||||
|
||||
@@ -37,7 +50,7 @@ void BalancesTableModel::setNewData(const QMap<QString, double> balances,
|
||||
|
||||
BalancesTableModel::~BalancesTableModel() {
|
||||
delete modeldata;
|
||||
delete utxos;
|
||||
delete unspentOutputs;
|
||||
}
|
||||
|
||||
int BalancesTableModel::rowCount(const QModelIndex&) const
|
||||
@@ -70,8 +83,9 @@ QVariant BalancesTableModel::data(const QModelIndex &index, int role) const
|
||||
if (role == Qt::ForegroundRole) {
|
||||
// If any of the UTXOs for this address has zero confirmations, paint it in red
|
||||
const auto& addr = std::get<0>(modeldata->at(index.row()));
|
||||
for (auto utxo : *utxos) {
|
||||
if (utxo.address == addr && !utxo.spendable) {
|
||||
for (auto unconfirmedOutput : *unspentOutputs) {
|
||||
if (unconfirmedOutput.address == addr &&
|
||||
(!unconfirmedOutput.spendable || unconfirmedOutput.pending)) {
|
||||
QBrush b;
|
||||
b.setColor(Qt::red);
|
||||
return b;
|
||||
@@ -87,14 +101,14 @@ QVariant BalancesTableModel::data(const QModelIndex &index, int role) const
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch (index.column()) {
|
||||
case 0: return AddressBook::addLabelToAddress(std::get<0>(modeldata->at(index.row())));
|
||||
case 1: return Settings::gethushDisplayFormat(std::get<1>(modeldata->at(index.row())));
|
||||
case 1: return std::get<1>(modeldata->at(index.row())).toDecimalhushString();
|
||||
}
|
||||
}
|
||||
|
||||
if(role == Qt::ToolTipRole) {
|
||||
switch (index.column()) {
|
||||
case 0: return AddressBook::addLabelToAddress(std::get<0>(modeldata->at(index.row())));
|
||||
case 1: return Settings::getUSDFormat(std::get<1>(modeldata->at(index.row())));
|
||||
case 1: return std::get<1>(modeldata->at(index.row())).toDecimalhushString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "datamodel.h"
|
||||
#include "camount.h"
|
||||
|
||||
|
||||
class BalancesTableModel : public QAbstractTableModel
|
||||
@@ -11,7 +12,7 @@ public:
|
||||
BalancesTableModel(QObject* parent);
|
||||
~BalancesTableModel();
|
||||
|
||||
void setNewData(const QMap<QString, double> balances, const QList<UnspentOutput> outputs);
|
||||
void setNewData(const QList<QString> zaddrs, const QList<QString> taddrs, const QMap<QString, CAmount> balances, const QList<UnspentOutput> outputs);
|
||||
|
||||
int rowCount(const QModelIndex &parent) const;
|
||||
int columnCount(const QModelIndex &parent) const;
|
||||
@@ -19,8 +20,8 @@ public:
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
|
||||
private:
|
||||
QList<std::tuple<QString, double>>* modeldata = nullptr;
|
||||
QList<UnspentOutput>* utxos = nullptr;
|
||||
QList<std::tuple<QString, CAmount>>* modeldata = nullptr;
|
||||
QList<UnspentOutput>* unspentOutputs = nullptr;
|
||||
|
||||
bool loading = true;
|
||||
};
|
||||
|
||||
61
src/camount.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "camount.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
const int NUMPLACES = 8;
|
||||
const qint64 COIN = 100000000;
|
||||
|
||||
double CAmount::toDecimalDouble() const {
|
||||
return static_cast<double>(this->amount) / COIN;
|
||||
}
|
||||
|
||||
QString CAmount::toDecimalString() const {
|
||||
if (amount < 0) {
|
||||
CAmount negative(-1 * this->amount);
|
||||
return "-" + negative.toDecimalString();
|
||||
}
|
||||
|
||||
int wholePart = amount / COIN;
|
||||
int decimalPart = amount % COIN;
|
||||
|
||||
QString r = QString::number(wholePart);
|
||||
if (decimalPart > 0) {
|
||||
QString decimalPartStr = QString::number(decimalPart);
|
||||
QString leadingZeros = QString("0").repeated(NUMPLACES - decimalPartStr.length());
|
||||
|
||||
r = r + "." + leadingZeros + decimalPartStr;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
QString CAmount::toDecimalUSDString() const {
|
||||
double dblAmount = static_cast<double>(this->amount) / COIN;
|
||||
double price = Settings::getInstance()->gethushPrice();
|
||||
|
||||
return "$" + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
|
||||
}
|
||||
|
||||
QString CAmount::toDecimalhushString() const {
|
||||
return this->toDecimalString() % " " % Settings::getTokenName();
|
||||
}
|
||||
|
||||
QString CAmount::toDecimalhushUSDString() const {
|
||||
auto usdString = this->toDecimalUSDString();
|
||||
if (!usdString.isEmpty())
|
||||
return this->toDecimalhushString() % " (" % usdString % ")";
|
||||
else
|
||||
return this->toDecimalhushString();
|
||||
}
|
||||
|
||||
CAmount CAmount::fromDecimalString(QString decimalString) {
|
||||
auto amtParts = decimalString.split(".");
|
||||
qint64 r = amtParts[0].toULongLong() * COIN;
|
||||
if (amtParts.length() == 2) {
|
||||
auto trailingZeros = QString("0").repeated(NUMPLACES - amtParts[1].length());
|
||||
r += QString(amtParts[1] + trailingZeros).toULongLong();
|
||||
}
|
||||
|
||||
return CAmount(r);
|
||||
}
|
||||
55
src/camount.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef CAMOUNT_H
|
||||
#define CAMOUNT_H
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
class CAmount {
|
||||
private:
|
||||
CAmount(qint64 amount) {
|
||||
this->amount = amount;
|
||||
}
|
||||
|
||||
qint64 amount;
|
||||
|
||||
public:
|
||||
static CAmount fromDecimalString(QString decimalString);
|
||||
static CAmount fromqint64(qint64 a) {
|
||||
return CAmount(a);
|
||||
}
|
||||
static CAmount fromDouble(double d) {
|
||||
return CAmount::fromDecimalString(QString::number(d, 'f', 8));
|
||||
}
|
||||
|
||||
CAmount() : amount(0) {};
|
||||
CAmount(const CAmount&) = default;
|
||||
~CAmount() = default;
|
||||
|
||||
double toDecimalDouble() const;
|
||||
QString toDecimalString() const;
|
||||
QString toDecimalUSDString() const;
|
||||
QString toDecimalhushString() const;
|
||||
QString toDecimalhushUSDString() const;
|
||||
qint64 toqint64() const { return amount; };
|
||||
|
||||
CAmount operator+ (const CAmount& other) const {
|
||||
return CAmount(this->amount + other.amount);
|
||||
}
|
||||
|
||||
CAmount operator- (const CAmount& other) const {
|
||||
return CAmount(this->amount - other.amount);
|
||||
}
|
||||
|
||||
bool operator< (const CAmount& other) const {
|
||||
return this->amount < other.amount;
|
||||
}
|
||||
|
||||
bool operator< (const qint64& other) const {
|
||||
return this->amount < other;
|
||||
}
|
||||
|
||||
bool operator> (const CAmount& other) const {
|
||||
return this->amount > other.amount;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CAMOUNT_H
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>538</width>
|
||||
<height>458</height>
|
||||
<width>626</width>
|
||||
<height>713</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -174,19 +174,6 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="nopeersWarning">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: red;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>hushd doesn't seem to have any peers. You might not be connected to the internet, so this transaction might not work.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="syncingWarning">
|
||||
<property name="styleSheet">
|
||||
@@ -200,19 +187,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="warningLabel">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: red;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>You are using a custom fee. Since fees are transparent, you are giving up some privacy. Please use this only if you know what you are doing!</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
|
||||
@@ -43,20 +43,20 @@ void ConnectionLoader::doAutoConnect() {
|
||||
|
||||
auto config = std::shared_ptr<ConnectionConfig>(new ConnectionConfig());
|
||||
config->dangerous = true;
|
||||
config->server = QString("https://hush-lightwallet.de:439");
|
||||
config->server = Settings::getInstance()->getSettings().server;
|
||||
|
||||
// Initialize the library
|
||||
main->logger->write(QObject::tr("Attempting to initialize"));
|
||||
main->logger->write(QObject::tr("Attempting to initialize library with ") + config->server);
|
||||
|
||||
// Check to see if there's an existing wallet
|
||||
if (litelib_wallet_exists(Settings::getChainName().toStdString().c_str())) {
|
||||
main->logger->write(QObject::tr("Using existing wallet."));
|
||||
char* resp = litelib_initialize_existing(config->dangerous, config->server.toStdString().c_str());
|
||||
char* resp = litelib_initialize_existing(config->dangerous, config->server.toStdString().c_str());
|
||||
QString response = litelib_process_response(resp);
|
||||
|
||||
if (response.toUpper().trimmed() != "OK") {
|
||||
showError(response);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
main->logger->write(QObject::tr("Create/restore wallet."));
|
||||
@@ -65,9 +65,10 @@ void ConnectionLoader::doAutoConnect() {
|
||||
}
|
||||
|
||||
auto connection = makeConnection(config);
|
||||
auto me = this;
|
||||
|
||||
// After the lib is initialized, try to do get info
|
||||
connection->doRPC("info", "", [=](auto reply) {
|
||||
connection->doRPC("info", "", [=](auto) {
|
||||
// If success, set the connection
|
||||
main->logger->write("Connection is online.");
|
||||
|
||||
@@ -95,7 +96,7 @@ void ConnectionLoader::doAutoConnect() {
|
||||
if (isSyncing != nullptr && reply.find("synced_blocks") != reply.end()) {
|
||||
qint64 synced = reply["synced_blocks"].get<json::number_unsigned_t>();
|
||||
qint64 total = reply["total_blocks"].get<json::number_unsigned_t>();
|
||||
showInformation("Synced " + QString::number(synced) + " / " + QString::number(total));
|
||||
me->showInformation("Synced " + QString::number(synced) + " / " + QString::number(total));
|
||||
}
|
||||
},
|
||||
[=](QString err) {
|
||||
@@ -173,15 +174,11 @@ void Executor::run() {
|
||||
|
||||
QString reply = litelib_process_response(resp);
|
||||
|
||||
qDebug() << "Reply=" << reply;
|
||||
qDebug() << "RPC Reply=" << reply;
|
||||
auto parsed = json::parse(reply.toStdString().c_str(), nullptr, false);
|
||||
if (parsed.is_discarded() || parsed.is_null()) {
|
||||
emit handleError(reply);
|
||||
} else {
|
||||
const bool isGuiThread =
|
||||
QThread::currentThread() == QCoreApplication::instance()->thread();
|
||||
qDebug() << "executing RPC: isGUI=" << isGuiThread;
|
||||
|
||||
emit responseReady(parsed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "addressbook.h"
|
||||
#include "settings.h"
|
||||
#include "version.h"
|
||||
#include "camount.h"
|
||||
#include "websockets.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
@@ -66,12 +67,7 @@ void Controller::setConnection(Connection* c) {
|
||||
|
||||
ui->statusBar->showMessage("Connectet with https://hush-lightwallet.de");
|
||||
|
||||
// See if we need to remove the reindex/rescan flags from the hush.conf file
|
||||
auto hushConfLocation = Settings::getInstance()->gethushdConfLocation();
|
||||
Settings::removeFromhushConf(hushConfLocation, "rescan");
|
||||
Settings::removeFromhushConf(hushConfLocation, "reindex");
|
||||
|
||||
// If we're allowed to get the hush Price, get the prices
|
||||
// If we're allowed to get the Hush Price, get the prices
|
||||
if (Settings::getInstance()->getAllowFetchPrices())
|
||||
refreshhushPrice();
|
||||
|
||||
@@ -96,18 +92,12 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) {
|
||||
// Construct the JSON params
|
||||
json rec = json::object();
|
||||
rec["address"] = toAddr.addr.toStdString();
|
||||
rec["amount"] = toAddr.amount * 100000000;
|
||||
rec["amount"] = toAddr.amount.toqint64();
|
||||
if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty())
|
||||
rec["memo"] = toAddr.memo.toStdString();
|
||||
|
||||
allRecepients.push_back(rec);
|
||||
}
|
||||
|
||||
// // Add fees if custom fees are allowed.
|
||||
// if (Settings::getInstance()->getAllowCustomFees()) {
|
||||
// params.push_back(1); // minconf
|
||||
// params.push_back(tx.fee);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@@ -120,9 +110,10 @@ void Controller::noConnection() {
|
||||
main->ui->statusBar->showMessage(QObject::tr("No Connection"), 1000);
|
||||
|
||||
// Clear balances table.
|
||||
QMap<QString, double> emptyBalances;
|
||||
QMap<QString, CAmount> emptyBalances;
|
||||
QList<UnspentOutput> emptyOutputs;
|
||||
balancesTableModel->setNewData(emptyBalances, emptyOutputs);
|
||||
QList<QString> emptyAddresses;
|
||||
balancesTableModel->setNewData(emptyAddresses, emptyAddresses, emptyBalances, emptyOutputs);
|
||||
|
||||
// Clear Transactions table.
|
||||
QList<TransactionItem> emptyTxs;
|
||||
@@ -136,9 +127,6 @@ void Controller::noConnection() {
|
||||
ui->balSheilded->setToolTip("");
|
||||
ui->balTransparent->setToolTip("");
|
||||
ui->balTotal->setToolTip("");
|
||||
|
||||
// Clear send tab from address
|
||||
ui->inputsCombo->clear();
|
||||
}
|
||||
|
||||
/// This will refresh all the balance data from hushd
|
||||
@@ -177,12 +165,15 @@ void Controller::getInfoThenRefresh(bool force) {
|
||||
ui->blockHeight->setText(QString::number(curBlock));
|
||||
|
||||
// Connected, so display checkmark.
|
||||
auto tooltip = Settings::getInstance()->getSettings().server + "\n" + QString::fromStdString(reply.dump());
|
||||
QIcon i(":/icons/res/connected.gif");
|
||||
main->statusLabel->setText( "connected" "(" + QString::number(curBlock) + ")");
|
||||
main->statusLabel->setText(chainName + "(" + QString::number(curBlock) + ")");
|
||||
main->statusLabel->setText(" HUSH/USD=$" + QString::number( (double) Settings::getInstance()->gethushPrice() ));
|
||||
main->statusLabel->setToolTip(tooltip);
|
||||
main->statusIcon->setPixmap(i.pixmap(16, 16));
|
||||
|
||||
//int version = reply["version"].get<json::string_t>();
|
||||
main->statusIcon->setToolTip(tooltip);
|
||||
|
||||
//int version = reply["version"].get<json::string_t>();
|
||||
int version = 1;
|
||||
Settings::getInstance()->sethushdVersion(version);
|
||||
ui->Version->setText(QString::fromStdString(reply["version"].get<json::string_t>()));
|
||||
@@ -255,33 +246,33 @@ void Controller::updateUI(bool anyUnconfirmed) {
|
||||
ui->unconfirmedWarning->setVisible(anyUnconfirmed);
|
||||
|
||||
// Update balances model data, which will update the table too
|
||||
balancesTableModel->setNewData(model->getAllBalances(), model->getUTXOs());
|
||||
|
||||
// Update from address
|
||||
main->updateFromCombo();
|
||||
balancesTableModel->setNewData(model->getAllZAddresses(), model->getAllTAddresses(), model->getAllBalances(), model->getUTXOs());
|
||||
};
|
||||
|
||||
// Function to process reply of the listunspent and z_listunspent API calls, used below.
|
||||
bool Controller::processUnspent(const json& reply, QMap<QString, double>* balancesMap, QList<UnspentOutput>* newUtxos) {
|
||||
bool anyUnconfirmed = false;
|
||||
|
||||
auto processFn = [=](const json& array) {
|
||||
void Controller::processUnspent(const json& reply, QMap<QString, CAmount>* balancesMap, QList<UnspentOutput>* unspentOutputs) {
|
||||
auto processFn = [=](const json& array) {
|
||||
for (auto& it : array) {
|
||||
QString qsAddr = QString::fromStdString(it["address"]);
|
||||
int block = it["created_in_block"].get<json::number_unsigned_t>();
|
||||
QString txid = QString::fromStdString(it["created_in_txid"]);
|
||||
QString amount = Settings::getDecimalString(it["value"].get<json::number_float_t>());
|
||||
CAmount amount = CAmount::fromqint64(it["value"].get<json::number_unsigned_t>());
|
||||
|
||||
newUtxos->push_back(UnspentOutput{ qsAddr, txid, amount, block, true });
|
||||
bool spendable = it["unconfirmed_spent"].is_null() && it["spent"].is_null(); // TODO: Wait for 4 confirmations
|
||||
bool pending = !it["unconfirmed_spent"].is_null();
|
||||
|
||||
(*balancesMap)[qsAddr] = ((*balancesMap)[qsAddr] + (it["value"].get<json::number_float_t>()) /100000000);
|
||||
}
|
||||
unspentOutputs->push_back(UnspentOutput{ qsAddr, txid, amount, block, spendable, pending });
|
||||
if (spendable) {
|
||||
(*balancesMap)[qsAddr] = (*balancesMap)[qsAddr] +
|
||||
CAmount::fromqint64(it["value"].get<json::number_unsigned_t>());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
processFn(reply["unspent_notes"].get<json::array_t>());
|
||||
processFn(reply["utxos"].get<json::array_t>());
|
||||
|
||||
return anyUnconfirmed;
|
||||
processFn(reply["pending_notes"].get<json::array_t>());
|
||||
processFn(reply["pending_utxos"].get<json::array_t>());
|
||||
};
|
||||
|
||||
void Controller::refreshBalances() {
|
||||
@@ -290,36 +281,53 @@ void Controller::refreshBalances() {
|
||||
|
||||
// 1. Get the Balances
|
||||
zrpc->fetchBalance([=] (json reply) {
|
||||
auto balT = reply["tbalance"].get<json::number_float_t>();
|
||||
auto balZ = reply["zbalance"].get<json::number_float_t>();
|
||||
auto balTotal = balT + balZ;
|
||||
CAmount balT = CAmount::fromqint64(reply["tbalance"].get<json::number_unsigned_t>());
|
||||
CAmount balZ = CAmount::fromqint64(reply["zbalance"].get<json::number_unsigned_t>());
|
||||
CAmount balVerified = CAmount::fromqint64(reply["verified_zbalance"].get<json::number_unsigned_t>());
|
||||
|
||||
CAmount balTotal = balT + balZ;
|
||||
CAmount balAvailable = balT + balVerified;
|
||||
|
||||
// This is for the websockets
|
||||
AppDataModel::getInstance()->setBalances(balT, balZ);
|
||||
|
||||
// This is for the datamodel
|
||||
model->setAvailableBalance(balAvailable);
|
||||
|
||||
ui->balSheilded ->setText(Settings::gethushDisplayFormat(balZ /100000000));
|
||||
ui->balTransparent->setText(Settings::gethushDisplayFormat(balT /100000000));
|
||||
ui->balTotal ->setText(Settings::gethushDisplayFormat(balTotal /100000000));
|
||||
// Balances table
|
||||
ui->balSheilded ->setText(balZ.toDecimalhushString());
|
||||
ui->balVerified ->setText(balVerified.toDecimalhushString());
|
||||
ui->balTransparent->setText(balT.toDecimalhushString());
|
||||
ui->balTotal ->setText(balTotal.toDecimalhushString());
|
||||
|
||||
ui->balSheilded ->setToolTip(balZ.toDecimalUSDString());
|
||||
ui->balVerified ->setToolTip(balVerified.toDecimalUSDString());
|
||||
ui->balTransparent->setToolTip(balT.toDecimalUSDString());
|
||||
ui->balTotal ->setToolTip(balTotal.toDecimalUSDString());
|
||||
|
||||
ui->balSheilded ->setToolTip(Settings::gethushDisplayFormat(balZ /100000000));
|
||||
ui->balTransparent->setToolTip(Settings::gethushDisplayFormat(balT /100000000));
|
||||
ui->balTotal ->setToolTip(Settings::gethushDisplayFormat(balTotal /100000000));
|
||||
|
||||
|
||||
// Send tab
|
||||
ui->txtAvailablehush->setText(balAvailable.toDecimalhushString());
|
||||
ui->txtAvailableUSD->setText(balAvailable.toDecimalUSDString());
|
||||
});
|
||||
|
||||
// 2. Get the UTXOs
|
||||
// First, create a new UTXO list. It will be replacing the existing list when everything is processed.
|
||||
auto newUtxos = new QList<UnspentOutput>();
|
||||
auto newBalances = new QMap<QString, double>();
|
||||
auto newUnspentOutputs = new QList<UnspentOutput>();
|
||||
auto newBalances = new QMap<QString, CAmount>();
|
||||
|
||||
// Call the Transparent and Z unspent APIs serially and then, once they're done, update the UI
|
||||
zrpc->fetchUnspent([=] (json reply) {
|
||||
auto anyUnconfirmed = processUnspent(reply, newBalances, newUtxos);
|
||||
processUnspent(reply, newBalances, newUnspentOutputs);
|
||||
|
||||
// Swap out the balances and UTXOs
|
||||
model->replaceBalances(newBalances);
|
||||
model->replaceUTXOs(newUtxos);
|
||||
model->replaceUTXOs(newUnspentOutputs);
|
||||
|
||||
// Find if any output is not spendable or is pending
|
||||
bool anyUnconfirmed = std::find_if(newUnspentOutputs->constBegin(), newUnspentOutputs->constEnd(),
|
||||
[=](const UnspentOutput& u) -> bool {
|
||||
return !u.spendable || u.pending;
|
||||
}) != newUnspentOutputs->constEnd();
|
||||
|
||||
updateUI(anyUnconfirmed);
|
||||
|
||||
@@ -336,7 +344,7 @@ void Controller::refreshTransactions() {
|
||||
|
||||
for (auto& it : reply.get<json::array_t>()) {
|
||||
QString address;
|
||||
quint64 total_amount;
|
||||
CAmount total_amount;
|
||||
QList<TransactionItemDetail> items;
|
||||
|
||||
// First, check if there's outgoing metadata
|
||||
@@ -344,7 +352,9 @@ void Controller::refreshTransactions() {
|
||||
|
||||
for (auto o: it["outgoing_metadata"].get<json::array_t>()) {
|
||||
QString address = QString::fromStdString(o["address"]);
|
||||
double amount = -1 * o ["value"].get<json::number_float_t>() /100000000; // Sent items are -ve
|
||||
|
||||
// Sent items are -ve
|
||||
CAmount amount = CAmount::fromqint64(-1 * o["value"].get<json::number_unsigned_t>());
|
||||
|
||||
// Check for Memos
|
||||
|
||||
@@ -355,7 +365,7 @@ void Controller::refreshTransactions() {
|
||||
}
|
||||
|
||||
items.push_back(TransactionItemDetail{address, amount, memo});
|
||||
total_amount += amount;
|
||||
total_amount = total_amount + amount;
|
||||
}
|
||||
|
||||
if (items.length() == 1) {
|
||||
@@ -366,10 +376,10 @@ void Controller::refreshTransactions() {
|
||||
|
||||
txdata.push_back(TransactionItem{
|
||||
"Sent",
|
||||
it["datetime"].get<json::number_unsigned_t>(),
|
||||
it["datetime"].get<json::number_integer_t>(),
|
||||
address,
|
||||
QString::fromStdString(it["txid"]),
|
||||
model->getLatestBlock() - it["block_height"].get<json::number_unsigned_t>(),
|
||||
model->getLatestBlock() - it["block_height"].get<json::number_integer_t>(),
|
||||
items
|
||||
});
|
||||
} else {
|
||||
@@ -379,17 +389,17 @@ void Controller::refreshTransactions() {
|
||||
|
||||
items.push_back(TransactionItemDetail{
|
||||
address,
|
||||
it["amount"].get<json::number_float_t>() /100000000,
|
||||
CAmount::fromqint64(it["amount"].get<json::number_integer_t>()),
|
||||
""
|
||||
});
|
||||
|
||||
|
||||
TransactionItem tx{
|
||||
"Receive",
|
||||
it["datetime"].get<json::number_unsigned_t>(),
|
||||
it["datetime"].get<json::number_integer_t>(),
|
||||
address,
|
||||
QString::fromStdString(it["txid"]),
|
||||
model->getLatestBlock() - it["block_height"].get<json::number_unsigned_t>(),
|
||||
model->getLatestBlock() - it["block_height"].get<json::number_integer_t>() + 1,
|
||||
items
|
||||
};
|
||||
|
||||
@@ -436,10 +446,10 @@ void Controller::executeTransaction(Tx tx,
|
||||
zrpc->sendTransaction(QString::fromStdString(params.dump()), [=](const json& reply) {
|
||||
if (reply.find("txid") == reply.end()) {
|
||||
error("", "Couldn't understand Response: " + QString::fromStdString(reply.dump()));
|
||||
} else {
|
||||
QString txid = QString::fromStdString(reply["txid"].get<json::string_t>());
|
||||
submitted(txid);
|
||||
}
|
||||
|
||||
QString txid = QString::fromStdString(reply["txid"].get<json::string_t>());
|
||||
submitted(txid);
|
||||
},
|
||||
[=](QString errStr) {
|
||||
error("", errStr);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "camount.h"
|
||||
#include "datamodel.h"
|
||||
#include "balancestablemodel.h"
|
||||
#include "txtablemodel.h"
|
||||
@@ -21,15 +22,6 @@ struct WatchedTx {
|
||||
};
|
||||
|
||||
|
||||
struct MigrationStatus {
|
||||
bool available; // Whether the underlying hushd supports migration?
|
||||
bool enabled;
|
||||
QString saplingAddress;
|
||||
double unmigrated;
|
||||
double migrated;
|
||||
QList<QString> txids;
|
||||
};
|
||||
|
||||
class Controller
|
||||
{
|
||||
public:
|
||||
@@ -78,7 +70,7 @@ private:
|
||||
|
||||
void refreshTransactions();
|
||||
|
||||
bool processUnspent (const json& reply, QMap<QString, double>* newBalances, QList<UnspentOutput>* newUtxos);
|
||||
void processUnspent (const json& reply, QMap<QString, CAmount>* newBalances, QList<UnspentOutput>* newUnspentOutputs);
|
||||
void updateUI (bool anyUnconfirmed);
|
||||
|
||||
void getInfoThenRefresh(bool force);
|
||||
@@ -89,7 +81,7 @@ private:
|
||||
BalancesTableModel* balancesTableModel = nullptr;
|
||||
|
||||
DataModel* model;
|
||||
LiteInterface* zrpc;
|
||||
LiteInterface* zrpc;
|
||||
|
||||
QTimer* timer;
|
||||
QTimer* txTimer;
|
||||
|
||||
@@ -7,7 +7,7 @@ DataModel::DataModel() {
|
||||
QWriteLocker locker(lock);
|
||||
|
||||
utxos = new QList<UnspentOutput>();
|
||||
balances = new QMap<QString, double>();
|
||||
balances = new QMap<QString, CAmount>();
|
||||
usedAddresses = new QMap<QString, bool>();
|
||||
zaddresses = new QList<QString>();
|
||||
taddresses = new QList<QString>();
|
||||
@@ -44,7 +44,7 @@ void DataModel::replaceTaddresses(QList<QString>* newT) {
|
||||
taddresses = newT;
|
||||
}
|
||||
|
||||
void DataModel::replaceBalances(QMap<QString, double>* newBalances) {
|
||||
void DataModel::replaceBalances(QMap<QString, CAmount>* newBalances) {
|
||||
QWriteLocker locker(lock);
|
||||
Q_ASSERT(newBalances);
|
||||
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
#ifndef DATAMODEL_H
|
||||
#define DATAMODEL_H
|
||||
|
||||
#include "camount.h"
|
||||
#include "precompiled.h"
|
||||
|
||||
|
||||
struct UnspentOutput {
|
||||
QString address;
|
||||
QString txid;
|
||||
QString amount;
|
||||
CAmount amount;
|
||||
int blockCreated;
|
||||
bool spendable;
|
||||
bool pending;
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +20,7 @@ class DataModel {
|
||||
public:
|
||||
void replaceZaddresses(QList<QString>* newZ);
|
||||
void replaceTaddresses(QList<QString>* newZ);
|
||||
void replaceBalances(QMap<QString, double>* newBalances);
|
||||
void replaceBalances(QMap<QString, CAmount>* newBalances);
|
||||
void replaceUTXOs(QList<UnspentOutput>* utxos);
|
||||
|
||||
void markAddressUsed(QString address);
|
||||
@@ -29,9 +31,11 @@ public:
|
||||
const QList<QString> getAllZAddresses() { QReadLocker locker(lock); return *zaddresses; }
|
||||
const QList<QString> getAllTAddresses() { QReadLocker locker(lock); return *taddresses; }
|
||||
const QList<UnspentOutput> getUTXOs() { QReadLocker locker(lock); return *utxos; }
|
||||
const QMap<QString, double> getAllBalances() { QReadLocker locker(lock); return *balances; }
|
||||
const QMap<QString, bool> getUsedAddresses() { QReadLocker locker(lock); return *usedAddresses; }
|
||||
|
||||
const QMap<QString, CAmount> getAllBalances() { QReadLocker locker(lock); return *balances; }
|
||||
const QMap<QString, bool> getUsedAddresses() { QReadLocker locker(lock); return *usedAddresses; }
|
||||
|
||||
CAmount getAvailableBalance() { return availableBalance; }
|
||||
void setAvailableBalance(CAmount a) { this->availableBalance = a; }
|
||||
|
||||
DataModel();
|
||||
~DataModel();
|
||||
@@ -39,11 +43,13 @@ private:
|
||||
int latestBlock;
|
||||
|
||||
QList<UnspentOutput>* utxos = nullptr;
|
||||
QMap<QString, double>* balances = nullptr;
|
||||
QMap<QString, CAmount>* balances = nullptr;
|
||||
QMap<QString, bool>* usedAddresses = nullptr;
|
||||
QList<QString>* zaddresses = nullptr;
|
||||
QList<QString>* taddresses = nullptr;
|
||||
|
||||
CAmount availableBalance;
|
||||
|
||||
QReadWriteLock* lock;
|
||||
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "camount.h"
|
||||
#include "connection.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
@@ -11,7 +12,7 @@ using json = nlohmann::json;
|
||||
// into a struct with address, amount, memo
|
||||
struct TransactionItemDetail {
|
||||
QString address;
|
||||
double amount;
|
||||
CAmount amount;
|
||||
QString memo;
|
||||
};
|
||||
|
||||
|
||||
10
src/main.cpp
@@ -150,9 +150,8 @@ public:
|
||||
parser.setApplicationDescription("Shielded desktop light wallet for hush");
|
||||
parser.addHelpOption();
|
||||
|
||||
|
||||
// Positional argument will specify a hush payment URI
|
||||
parser.addPositionalArgument("HUSHURI", "An optional hush URI to pay");
|
||||
// Positional argument will specify a zcash payment URI
|
||||
parser.addPositionalArgument("zcashURI", "An optional hush URI to pay");
|
||||
|
||||
parser.process(a);
|
||||
|
||||
@@ -173,7 +172,7 @@ public:
|
||||
qDebug() << "Loading locale " << locale;
|
||||
|
||||
QTranslator translator;
|
||||
translator.load(QString(":/translations/res/zec_qt_wallet_") + locale);
|
||||
translator.load(QString(":/translations/res/hush_qt_wallet_") + locale);
|
||||
a.installTranslator(&translator);
|
||||
|
||||
QIcon icon(":/icons/res/icon.ico");
|
||||
@@ -203,9 +202,10 @@ public:
|
||||
}
|
||||
|
||||
Settings::getInstance()->setUseEmbedded(false);
|
||||
|
||||
|
||||
w = new MainWindow();
|
||||
w->setWindowTitle("SilentDragonLite v" + QString(APP_VERSION));
|
||||
w->setWindowTitle("SilentDragon Lite v" + QString(APP_VERSION));
|
||||
|
||||
// If there was a payment URI on the command line, pay it
|
||||
if (parser.positionalArguments().length() > 0) {
|
||||
|
||||
@@ -259,11 +259,6 @@ void MainWindow::setupSettingsModal() {
|
||||
settings.setupUi(&settingsDialog);
|
||||
Settings::saveRestore(&settingsDialog);
|
||||
|
||||
// Setup save sent check box
|
||||
QObject::connect(settings.chkSaveTxs, &QCheckBox::stateChanged, [=](auto checked) {
|
||||
Settings::getInstance()->setSaveZtxs(checked);
|
||||
});
|
||||
|
||||
// Setup theme combo
|
||||
int theme_index = settings.comboBoxTheme->findText(Settings::getInstance()->get_theme_name(), Qt::MatchExactly);
|
||||
settings.comboBoxTheme->setCurrentIndex(theme_index);
|
||||
@@ -274,55 +269,15 @@ void MainWindow::setupSettingsModal() {
|
||||
QMessageBox::information(this, tr("Restart"), tr("Please restart Silentdragonlite to have the theme apply"), QMessageBox::Ok);
|
||||
});
|
||||
|
||||
// Save sent transactions
|
||||
settings.chkSaveTxs->setChecked(Settings::getInstance()->getSaveZtxs());
|
||||
|
||||
// Custom fees
|
||||
settings.chkCustomFees->setChecked(Settings::getInstance()->getAllowCustomFees());
|
||||
|
||||
// Auto shielding
|
||||
settings.chkAutoShield->setChecked(Settings::getInstance()->getAutoShield());
|
||||
|
||||
// Check for updates
|
||||
settings.chkCheckUpdates->setChecked(Settings::getInstance()->getCheckForUpdates());
|
||||
|
||||
// Fetch prices
|
||||
settings.chkFetchPrices->setChecked(Settings::getInstance()->getAllowFetchPrices());
|
||||
|
||||
// Use Tor
|
||||
bool isUsingTor = false;
|
||||
if (rpc->getConnection() != nullptr) {
|
||||
isUsingTor = !rpc->getConnection()->config->proxy.isEmpty();
|
||||
}
|
||||
settings.chkTor->setChecked(isUsingTor);
|
||||
|
||||
// Connection Settings
|
||||
QIntValidator validator(0, 65535);
|
||||
settings.port->setValidator(&validator);
|
||||
|
||||
// If values are coming from hush.conf, then disable all the fields
|
||||
auto hushConfLocation = Settings::getInstance()->gethushdConfLocation();
|
||||
if (!hushConfLocation.isEmpty()) {
|
||||
settings.confMsg->setText("Settings are being read from \n" + hushConfLocation);
|
||||
settings.hostname->setEnabled(false);
|
||||
settings.port->setEnabled(false);
|
||||
settings.rpcuser->setEnabled(false);
|
||||
settings.rpcpassword->setEnabled(false);
|
||||
}
|
||||
else {
|
||||
settings.confMsg->setText("No local HUSH3.conf found. Please configure connection manually.");
|
||||
settings.hostname->setEnabled(true);
|
||||
settings.port->setEnabled(true);
|
||||
settings.rpcuser->setEnabled(true);
|
||||
settings.rpcpassword->setEnabled(true);
|
||||
}
|
||||
|
||||
// Load current values into the dialog
|
||||
auto conf = Settings::getInstance()->getSettings();
|
||||
settings.hostname->setText(conf.host);
|
||||
settings.port->setText(conf.port);
|
||||
settings.rpcuser->setText(conf.rpcuser);
|
||||
settings.rpcpassword->setText(conf.rpcpassword);
|
||||
settings.txtServer->setText(conf.server);
|
||||
|
||||
// Connection tab by default
|
||||
settings.tabWidget->setCurrentIndex(0);
|
||||
@@ -330,79 +285,26 @@ void MainWindow::setupSettingsModal() {
|
||||
// Enable the troubleshooting options only if using embedded hushd
|
||||
if (!rpc->isEmbedded()) {
|
||||
settings.chkRescan->setEnabled(false);
|
||||
settings.chkRescan->setToolTip(tr("You're using an external hushd. Please restart hushd with -rescan"));
|
||||
|
||||
settings.chkReindex->setEnabled(false);
|
||||
settings.chkReindex->setToolTip(tr("You're using an external hushd. Please restart hushd with -reindex"));
|
||||
settings.chkRescan->setToolTip(tr("You're using an external hushd. Please restart zcashd with -rescan"));
|
||||
}
|
||||
|
||||
if (settingsDialog.exec() == QDialog::Accepted) {
|
||||
// Custom fees
|
||||
bool customFees = settings.chkCustomFees->isChecked();
|
||||
Settings::getInstance()->setAllowCustomFees(customFees);
|
||||
ui->minerFeeAmt->setReadOnly(!customFees);
|
||||
if (!customFees)
|
||||
ui->minerFeeAmt->setText(Settings::getDecimalString(Settings::getMinerFee()));
|
||||
|
||||
// Auto shield
|
||||
Settings::getInstance()->setAutoShield(settings.chkAutoShield->isChecked());
|
||||
|
||||
// Check for updates
|
||||
Settings::getInstance()->setCheckForUpdates(settings.chkCheckUpdates->isChecked());
|
||||
|
||||
// Allow fetching prices
|
||||
Settings::getInstance()->setAllowFetchPrices(settings.chkFetchPrices->isChecked());
|
||||
|
||||
if (!isUsingTor && settings.chkTor->isChecked()) {
|
||||
// If "use tor" was previously unchecked and now checked
|
||||
Settings::addTohushConf(hushConfLocation, "proxy=127.0.0.1:9050");
|
||||
rpc->getConnection()->config->proxy = "proxy=127.0.0.1:9050";
|
||||
// Save the server
|
||||
Settings::getInstance()->saveSettings(settings.txtServer->text().trimmed());
|
||||
|
||||
QMessageBox::information(this, tr("Enable Tor"),
|
||||
tr("Connection over Tor has been enabled. To use this feature, you need to restart Silentdragonlite."),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
|
||||
if (isUsingTor && !settings.chkTor->isChecked()) {
|
||||
// If "use tor" was previously checked and now is unchecked
|
||||
Settings::removeFromhushConf(hushConfLocation, "proxy");
|
||||
rpc->getConnection()->config->proxy.clear();
|
||||
|
||||
QMessageBox::information(this, tr("Disable Tor"),
|
||||
tr("Connection over Tor has been disabled. To fully disconnect from Tor, you need to restart silentdragon."),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
|
||||
if (hushConfLocation.isEmpty()) {
|
||||
if (false /* connection needs reloading?*/) {
|
||||
// Save settings
|
||||
Settings::getInstance()->saveSettings(
|
||||
settings.hostname->text(),
|
||||
settings.port->text(),
|
||||
settings.rpcuser->text(),
|
||||
settings.rpcpassword->text());
|
||||
Settings::getInstance()->saveSettings(settings.txtServer->text());
|
||||
|
||||
auto cl = new ConnectionLoader(this, rpc);
|
||||
cl->loadConnection();
|
||||
}
|
||||
|
||||
// Check to see if rescan or reindex have been enabled
|
||||
bool showRestartInfo = false;
|
||||
if (settings.chkRescan->isChecked()) {
|
||||
Settings::addTohushConf(hushConfLocation, "rescan=1");
|
||||
showRestartInfo = true;
|
||||
}
|
||||
|
||||
if (settings.chkReindex->isChecked()) {
|
||||
Settings::addTohushConf(hushConfLocation, "reindex=1");
|
||||
showRestartInfo = true;
|
||||
}
|
||||
|
||||
if (showRestartInfo) {
|
||||
auto desc = tr("silentdragon needs to restart to rescan/reindex. silentdragon will now close, please restart silentdragon to continue");
|
||||
|
||||
QMessageBox::information(this, tr("Restart silentdragon"), desc, QMessageBox::Ok);
|
||||
QTimer::singleShot(1, [=]() { this->close(); });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -541,13 +443,9 @@ void MainWindow::payhushURI(QString uri, QString myAddr) {
|
||||
// Now, set the fields on the send tab
|
||||
clearSendForm();
|
||||
|
||||
if (!myAddr.isEmpty()) {
|
||||
ui->inputsCombo->setCurrentText(myAddr);
|
||||
}
|
||||
|
||||
ui->Address1->setText(paymentInfo.addr);
|
||||
ui->Address1->setCursorPosition(0);
|
||||
ui->Amount1->setText(Settings::getDecimalString(paymentInfo.amt.toDouble()));
|
||||
ui->Amount1->setText(paymentInfo.amt);
|
||||
ui->MemoTxt1->setText(paymentInfo.memo);
|
||||
|
||||
// And switch to the send tab.
|
||||
@@ -743,40 +641,6 @@ void MainWindow::setupBalancesTab() {
|
||||
ui->lblSyncWarning->setVisible(false);
|
||||
ui->lblSyncWarningReceive->setVisible(false);
|
||||
|
||||
// Double click on balances table
|
||||
auto fnDoSendFrom = [=](const QString& addr, const QString& to = QString(), bool sendMax = false) {
|
||||
// Find the inputs combo
|
||||
for (int i = 0; i < ui->inputsCombo->count(); i++) {
|
||||
auto inputComboAddress = ui->inputsCombo->itemText(i);
|
||||
if (inputComboAddress.startsWith(addr)) {
|
||||
ui->inputsCombo->setCurrentIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If there's a to address, add that as well
|
||||
if (!to.isEmpty()) {
|
||||
// Remember to clear any existing address fields, because we are creating a new transaction.
|
||||
this->clearSendForm();
|
||||
ui->Address1->setText(to);
|
||||
}
|
||||
|
||||
// See if max button has to be checked
|
||||
if (sendMax) {
|
||||
ui->Max1->setChecked(true);
|
||||
}
|
||||
|
||||
// And switch to the send tab.
|
||||
ui->tabWidget->setCurrentIndex(1);
|
||||
};
|
||||
|
||||
// Double click opens up memo if one exists
|
||||
QObject::connect(ui->balancesTable, &QTableView::doubleClicked, [=](auto index) {
|
||||
index = index.sibling(index.row(), 0);
|
||||
auto addr = AddressBook::addressFromAddressLabel(ui->balancesTable->model()->data(index).toString());
|
||||
|
||||
fnDoSendFrom(addr);
|
||||
});
|
||||
|
||||
// Setup context menu on balances tab
|
||||
ui->balancesTable->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
@@ -800,18 +664,8 @@ void MainWindow::setupBalancesTab() {
|
||||
this->exportKeys(addr);
|
||||
});
|
||||
|
||||
menu.addAction("Send from " % addr.left(40) % (addr.size() > 40 ? "..." : ""), [=]() {
|
||||
fnDoSendFrom(addr);
|
||||
});
|
||||
|
||||
if (Settings::isTAddress(addr)) {
|
||||
auto defaultSapling = rpc->getDefaultSaplingAddress();
|
||||
if (!defaultSapling.isEmpty()) {
|
||||
menu.addAction(tr("Shield balance to Sapling"), [=] () {
|
||||
fnDoSendFrom(addr, defaultSapling, true);
|
||||
});
|
||||
}
|
||||
|
||||
menu.addAction(tr("View on block explorer"), [=] () {
|
||||
Settings::openAddressInExplorer(addr);
|
||||
});
|
||||
@@ -1092,7 +946,7 @@ void MainWindow::setupReceiveTab() {
|
||||
}
|
||||
|
||||
ui->rcvLabel->setText(label);
|
||||
ui->rcvBal->setText(Settings::gethushUSDDisplayFormat(rpc->getModel()->getAllBalances().value(addr)));
|
||||
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushUSDString());
|
||||
ui->txtReceive->setPlainText(addr);
|
||||
ui->qrcodeDisplay->setQrcodeString(addr);
|
||||
if (rpc->getModel()->getUsedAddresses().value(addr, false)) {
|
||||
@@ -1183,7 +1037,7 @@ void MainWindow::updateTAddrCombo(bool checked) {
|
||||
// If the address is in the address book, add it.
|
||||
if (labels.contains(taddr) && !addrs.contains(taddr)) {
|
||||
addrs.insert(taddr);
|
||||
ui->listReceiveAddresses->addItem(taddr, 0);
|
||||
ui->listReceiveAddresses->addItem(taddr, CAmount::fromqint64(0));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1194,7 +1048,7 @@ void MainWindow::updateTAddrCombo(bool checked) {
|
||||
if (!addrs.contains(addr)) {
|
||||
addrs.insert(addr);
|
||||
// Balance is zero since it has not been previously added
|
||||
ui->listReceiveAddresses->addItem(addr, 0);
|
||||
ui->listReceiveAddresses->addItem(addr, CAmount::fromqint64(0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1211,7 +1065,7 @@ void MainWindow::updateTAddrCombo(bool checked) {
|
||||
// 5. Add a last, disabled item if there are remaining items
|
||||
if (allTaddrs.size() > addrs.size()) {
|
||||
auto num = QString::number(allTaddrs.size() - addrs.size());
|
||||
ui->listReceiveAddresses->addItem("-- " + num + " more --", 0);
|
||||
ui->listReceiveAddresses->addItem("-- " + num + " more --", CAmount::fromqint64(0));
|
||||
|
||||
QStandardItemModel* model = qobject_cast<QStandardItemModel*>(ui->listReceiveAddresses->model());
|
||||
QStandardItem* item = model->findItems("--", Qt::MatchStartsWith)[0];
|
||||
@@ -1230,9 +1084,6 @@ void MainWindow::updateLabels() {
|
||||
addZAddrsToComboList(ui->rdioZSAddr->isChecked())(true);
|
||||
}
|
||||
|
||||
// Update the Send Tab
|
||||
updateFromCombo();
|
||||
|
||||
// Update the autocomplete
|
||||
updateLabelsAutoComplete();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ using json = nlohmann::json;
|
||||
// Struct used to hold destination info when sending a Tx.
|
||||
struct ToFields {
|
||||
QString addr;
|
||||
double amount;
|
||||
CAmount amount;
|
||||
QString memo;
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@ struct ToFields {
|
||||
struct Tx {
|
||||
QString fromAddr;
|
||||
QList<ToFields> toAddrs;
|
||||
double fee;
|
||||
CAmount fee;
|
||||
};
|
||||
|
||||
namespace Ui {
|
||||
@@ -47,7 +47,6 @@ public:
|
||||
QRegExpValidator* getAmountValidator() { return amtValidator; }
|
||||
|
||||
QString doSendTxValidations(Tx tx);
|
||||
void setDefaultPayFrom();
|
||||
|
||||
void replaceWormholeClient(WormholeClient* newClient);
|
||||
bool isWebsocketListening();
|
||||
@@ -59,7 +58,6 @@ public:
|
||||
|
||||
void updateLabels();
|
||||
void updateTAddrCombo(bool checked);
|
||||
void updateFromCombo();
|
||||
|
||||
// Disable recurring on mainnet
|
||||
void disableRecurring();
|
||||
@@ -100,7 +98,6 @@ private:
|
||||
|
||||
void cancelButton();
|
||||
void sendButton();
|
||||
void inputComboTextChanged(int index);
|
||||
void addAddressSection();
|
||||
void maxAmountChecked(int checked);
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>968</width>
|
||||
<height>616</height>
|
||||
<width>1274</width>
|
||||
<height>779</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -22,7 +22,7 @@
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>4</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
@@ -75,6 +75,37 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_17">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Verified</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="balVerified">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
@@ -148,26 +179,13 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblSyncWarning">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color:red;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Your node is still syncing, balances may not be updated</string>
|
||||
<string>Your node is still syncing, balances may not be updated.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@@ -186,10 +204,26 @@
|
||||
<string notr="true">color: red;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Some transactions are not yet confirmed</string>
|
||||
<string>Some transactions are not yet confirmed. Balances may change.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -267,60 +301,59 @@
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="AddressCombo" name="inputsCombo"/>
|
||||
</item>
|
||||
</layout>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_15">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Address Balance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="sendAddressBalance">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="sendAddressBalanceUSD">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Total verified funds available:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="txtAvailablehush">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="txtAvailableUSD">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@@ -359,8 +392,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>920</width>
|
||||
<height>301</height>
|
||||
<width>1226</width>
|
||||
<height>504</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="sendToLayout">
|
||||
@@ -1051,7 +1084,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>968</width>
|
||||
<width>1274</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -1210,7 +1243,6 @@
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>tabWidget</tabstop>
|
||||
<tabstop>inputsCombo</tabstop>
|
||||
<tabstop>Address1</tabstop>
|
||||
<tabstop>Amount1</tabstop>
|
||||
<tabstop>Max1</tabstop>
|
||||
@@ -1229,7 +1261,6 @@
|
||||
<tabstop>transactionsTable</tabstop>
|
||||
<tabstop>balancesTable</tabstop>
|
||||
<tabstop>minerFeeAmt</tabstop>
|
||||
<tabstop>sendAddressBalance</tabstop>
|
||||
<tabstop>sendToScrollArea</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "mainwindow.h"
|
||||
#include "controller.h"
|
||||
#include "settings.h"
|
||||
#include "camount.h"
|
||||
#include "ui_newrecurring.h"
|
||||
#include "ui_recurringdialog.h"
|
||||
#include "ui_recurringpayments.h"
|
||||
@@ -69,7 +70,7 @@ QJsonObject RecurringPaymentInfo::toJson() {
|
||||
{"desc", desc},
|
||||
{"from", fromAddr},
|
||||
{"to", toAddr},
|
||||
{"amt", Settings::getDecimalString(amt)},
|
||||
{"amt", amt},
|
||||
{"memo", memo},
|
||||
{"currency", currency},
|
||||
{"schedule", (int)schedule},
|
||||
@@ -81,7 +82,8 @@ QJsonObject RecurringPaymentInfo::toJson() {
|
||||
}
|
||||
|
||||
QString RecurringPaymentInfo::getAmountPretty() const {
|
||||
return currency == "USD" ? Settings::getUSDFormat(amt) : Settings::gethushDisplayFormat(amt);
|
||||
CAmount amount = CAmount::fromDouble(amt);
|
||||
return currency == "USD" ? amount.toDecimalUSDString() : amount.toDecimalhushString();
|
||||
}
|
||||
|
||||
QString RecurringPaymentInfo::getScheduleDescription() const {
|
||||
@@ -135,7 +137,7 @@ RecurringPaymentInfo* Recurring::getNewRecurringFromTx(QWidget* parent, MainWind
|
||||
ui.lblTo->setText(tx.toAddrs[0].addr);
|
||||
|
||||
// Default is USD
|
||||
ui.lblAmt->setText(Settings::getUSDFormat(tx.toAddrs[0].amount));
|
||||
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalUSDString());
|
||||
|
||||
ui.txtMemo->setPlainText(tx.toAddrs[0].memo);
|
||||
ui.txtMemo->setEnabled(false);
|
||||
@@ -147,10 +149,10 @@ RecurringPaymentInfo* Recurring::getNewRecurringFromTx(QWidget* parent, MainWind
|
||||
return;
|
||||
|
||||
if (c == "USD") {
|
||||
ui.lblAmt->setText(Settings::getUSDFormat(tx.toAddrs[0].amount));
|
||||
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalUSDString());
|
||||
}
|
||||
else {
|
||||
ui.lblAmt->setText(Settings::getDecimalString(tx.toAddrs[0].amount));
|
||||
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalString());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -201,13 +203,13 @@ void Recurring::updateInfoWithTx(RecurringPaymentInfo* r, Tx tx) {
|
||||
r->toAddr = tx.toAddrs[0].addr;
|
||||
r->memo = tx.toAddrs[0].memo;
|
||||
r->fromAddr = tx.fromAddr;
|
||||
if (r->currency.isEmpty() || r->currency == "usd") {
|
||||
r->currency = "usd";
|
||||
r->amt = tx.toAddrs[0].amount * Settings::getInstance()->gethushPrice();
|
||||
if (r->currency.isEmpty() || r->currency == "USD") {
|
||||
r->currency = "USD";
|
||||
r->amt = tx.toAddrs[0].amount.toqint64() * Settings::getInstance()->gethushPrice();
|
||||
}
|
||||
else {
|
||||
r->currency = Settings::getTokenName();
|
||||
r->amt = tx.toAddrs[0].amount;
|
||||
r->amt = tx.toAddrs[0].amount.toqint64();
|
||||
}
|
||||
|
||||
// Make sure that the number of payments is properly listed in the array
|
||||
@@ -459,9 +461,9 @@ void Recurring::processMultiplePending(RecurringPaymentInfo rpi, MainWindow* mai
|
||||
}
|
||||
|
||||
void Recurring::executeRecurringPayment(MainWindow* main, RecurringPaymentInfo rpi, QList<int> paymentNumbers) {
|
||||
// Amount is in USD or hush?
|
||||
auto amt = rpi.amt;
|
||||
if (rpi.currency == "usd") {
|
||||
// Amount is in USD or Hush?
|
||||
double amount = rpi.amt;
|
||||
if (rpi.currency == "USD") {
|
||||
// If there is no price, then fail the payment
|
||||
if (Settings::getInstance()->gethushPrice() == 0) {
|
||||
for (auto paymentNumber: paymentNumbers) {
|
||||
@@ -473,7 +475,7 @@ void Recurring::executeRecurringPayment(MainWindow* main, RecurringPaymentInfo r
|
||||
}
|
||||
|
||||
// Translate it into hush
|
||||
amt = rpi.amt / Settings::getInstance()->gethushPrice();
|
||||
amount = rpi.amt / Settings::getInstance()->gethushPrice();
|
||||
}
|
||||
|
||||
// Build a Tx
|
||||
@@ -483,9 +485,9 @@ void Recurring::executeRecurringPayment(MainWindow* main, RecurringPaymentInfo r
|
||||
|
||||
// If this is a multiple payment, we'll add up all the amounts
|
||||
if (paymentNumbers.size() > 1)
|
||||
amt *= paymentNumbers.size();
|
||||
amount *= paymentNumbers.size();
|
||||
|
||||
tx.toAddrs.append(ToFields { rpi.toAddr, amt, rpi.memo });
|
||||
tx.toAddrs.append(ToFields { rpi.toAddr, CAmount::fromDouble(amount), rpi.memo });
|
||||
|
||||
// To prevent some weird race conditions, we immediately mark the payment as paid.
|
||||
// If something goes wrong, we'll get the error callback below, and the status will be
|
||||
|
||||
@@ -73,7 +73,8 @@ void RequestDialog::showPaymentConfirmation(MainWindow* main, QString paymentURI
|
||||
req.txtFrom->setText(payInfo.addr);
|
||||
req.txtMemo->setPlainText(payInfo.memo);
|
||||
req.txtAmount->setText(payInfo.amt);
|
||||
req.txtAmountUSD->setText(Settings::getUSDFormat(req.txtAmount->text().toDouble()));
|
||||
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
|
||||
req.txtAmountUSD->setText(amount.toDecimalUSDString());
|
||||
|
||||
req.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Pay"));
|
||||
|
||||
@@ -112,9 +113,11 @@ void RequestDialog::showRequesthush(MainWindow* main) {
|
||||
// Amount textbox
|
||||
req.txtAmount->setValidator(main->getAmountValidator());
|
||||
QObject::connect(req.txtAmount, &QLineEdit::textChanged, [=] (auto text) {
|
||||
req.txtAmountUSD->setText(Settings::getUSDFormat(text.toDouble()));
|
||||
CAmount amount = CAmount::fromDecimalString(text);
|
||||
req.txtAmountUSD->setText(amount.toDecimalUSDString());
|
||||
});
|
||||
req.txtAmountUSD->setText(Settings::getUSDFormat(req.txtAmount->text().toDouble()));
|
||||
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
|
||||
req.txtAmountUSD->setText(amount.toDecimalUSDString());
|
||||
|
||||
req.txtMemo->setAcceptButton(req.buttonBox->button(QDialogButtonBox::Ok));
|
||||
req.txtMemo->setLenDisplayLabel(req.lblMemoLen);
|
||||
@@ -124,8 +127,9 @@ void RequestDialog::showRequesthush(MainWindow* main) {
|
||||
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
// Construct a hush Payment URI with the data and pay it immediately.
|
||||
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
|
||||
QString memoURI = "hush:" + req.cmbMyAddress->currentText()
|
||||
+ "?amt=" + Settings::getDecimalString(req.txtAmount->text().toDouble())
|
||||
+ "?amt=" + amount.toDecimalString()
|
||||
+ "&memo=" + QUrl::toPercentEncoding(req.txtMemo->toPlainText());
|
||||
|
||||
QString sendURI = "hush:" + AddressBook::addressFromAddressLabel(req.txtFrom->text())
|
||||
|
||||
208
src/sendtab.cpp
@@ -22,10 +22,6 @@ void MainWindow::setupSendTab() {
|
||||
// Cancel Button
|
||||
QObject::connect(ui->cancelSendButton, &QPushButton::clicked, this, &MainWindow::cancelButton);
|
||||
|
||||
// Input Combobox current text changed
|
||||
QObject::connect(ui->inputsCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &MainWindow::inputComboTextChanged);
|
||||
|
||||
// Hook up add address button click
|
||||
QObject::connect(ui->addAddressButton, &QPushButton::clicked, this, &MainWindow::addAddressSection);
|
||||
|
||||
@@ -59,18 +55,19 @@ void MainWindow::setupSendTab() {
|
||||
});
|
||||
|
||||
// Fee amount changed
|
||||
// Disable custom fees if settings say no
|
||||
ui->minerFeeAmt->setReadOnly(!Settings::getInstance()->getAllowCustomFees());
|
||||
ui->minerFeeAmt->setReadOnly(true);
|
||||
QObject::connect(ui->minerFeeAmt, &QLineEdit::textChanged, [=](auto txt) {
|
||||
ui->lblMinerFeeUSD->setText(Settings::getUSDFormat(txt.toDouble()));
|
||||
CAmount fee = CAmount::fromDecimalString(txt);
|
||||
ui->lblMinerFeeUSD->setText(fee.toDecimalUSDString());
|
||||
});
|
||||
ui->minerFeeAmt->setText(Settings::getDecimalString(Settings::getMinerFee()));
|
||||
ui->minerFeeAmt->setText(Settings::getMinerFee().toDecimalString());
|
||||
|
||||
// Set up focus enter to set fees
|
||||
QObject::connect(ui->tabWidget, &QTabWidget::currentChanged, [=] (int pos) {
|
||||
if (pos == 1) {
|
||||
QString txt = ui->minerFeeAmt->text();
|
||||
ui->lblMinerFeeUSD->setText(Settings::getUSDFormat(txt.toDouble()));
|
||||
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalUSDString();
|
||||
ui->lblMinerFeeUSD->setText(feeUSD);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -167,70 +164,6 @@ void MainWindow::updateLabelsAutoComplete() {
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setDefaultPayFrom() {
|
||||
auto findMax = [=] (QString startsWith) {
|
||||
double max_amt = 0;
|
||||
int idx = -1;
|
||||
|
||||
for (int i=0; i < ui->inputsCombo->count(); i++) {
|
||||
auto addr = ui->inputsCombo->itemText(i);
|
||||
if (addr.startsWith(startsWith)) {
|
||||
auto amt = rpc->getModel()->getAllBalances().value(addr);
|
||||
if (max_amt < amt) {
|
||||
max_amt = amt;
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
};
|
||||
|
||||
// By default, select the z-address with the most balance from the inputs combo
|
||||
auto maxZ = findMax("zs1");
|
||||
if (maxZ >= 0) {
|
||||
ui->inputsCombo->setCurrentIndex(maxZ);
|
||||
} else {
|
||||
auto maxT = findMax("R");
|
||||
maxT = maxT >= 0 ? maxT : 0;
|
||||
ui->inputsCombo->setCurrentIndex(maxT);
|
||||
}
|
||||
};
|
||||
|
||||
void MainWindow::updateFromCombo() {
|
||||
if (!rpc)
|
||||
return;
|
||||
|
||||
auto lastFromAddr = ui->inputsCombo->currentText();
|
||||
|
||||
ui->inputsCombo->clear();
|
||||
auto i = rpc->getModel()->getAllBalances().constBegin();
|
||||
|
||||
// Add all the addresses into the inputs combo box
|
||||
while (i != rpc->getModel()->getAllBalances().constEnd()) {
|
||||
ui->inputsCombo->addItem(i.key(), i.value());
|
||||
if (i.key() == lastFromAddr) ui->inputsCombo->setCurrentText(i.key());
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
if (lastFromAddr.isEmpty()) {
|
||||
setDefaultPayFrom();
|
||||
}
|
||||
else {
|
||||
ui->inputsCombo->setCurrentText(lastFromAddr);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::inputComboTextChanged(int index) {
|
||||
auto addr = ui->inputsCombo->itemText(index);
|
||||
auto bal = rpc->getModel()->getAllBalances().value(addr);
|
||||
auto balFmt = Settings::gethushDisplayFormat(bal);
|
||||
|
||||
ui->sendAddressBalance->setText(balFmt);
|
||||
ui->sendAddressBalanceUSD->setText(Settings::getUSDFormat(bal));
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::addAddressSection() {
|
||||
int itemNumber = ui->sendToWidgets->children().size() - 1;
|
||||
@@ -341,7 +274,8 @@ void MainWindow::addressChanged(int itemNumber, const QString& text) {
|
||||
|
||||
void MainWindow::amountChanged(int item, const QString& text) {
|
||||
auto usd = ui->sendToWidgets->findChild<QLabel*>(QString("AmtUSD") % QString::number(item));
|
||||
usd->setText(Settings::getUSDFormat(text.toDouble()));
|
||||
CAmount amt = CAmount::fromDecimalString(text);
|
||||
usd->setText(amt.toDecimalUSDString());
|
||||
|
||||
// If there is a recurring payment, update the info there as well
|
||||
if (sendTxRecurringInfo != nullptr) {
|
||||
@@ -386,12 +320,9 @@ void MainWindow::memoButtonClicked(int number, bool includeReplyTo) {
|
||||
memoDialog.memoTxt->setAcceptButton(memoDialog.buttonBox->button(QDialogButtonBox::Ok));
|
||||
|
||||
auto fnAddReplyTo = [=, &dialog]() {
|
||||
QString replyTo = ui->inputsCombo->currentText();
|
||||
if (!Settings::isZAddress(replyTo)) {
|
||||
replyTo = rpc->getDefaultSaplingAddress();
|
||||
if (replyTo.isEmpty())
|
||||
return;
|
||||
}
|
||||
auto replyTo = rpc->getDefaultSaplingAddress();
|
||||
if (replyTo.isEmpty())
|
||||
return;
|
||||
|
||||
memoDialog.memoTxt->includeReplyTo(replyTo);
|
||||
|
||||
@@ -435,7 +366,7 @@ void MainWindow::clearSendForm() {
|
||||
setMemoEnabled(1, false);
|
||||
|
||||
// Reset the fee
|
||||
ui->minerFeeAmt->setText(Settings::getDecimalString(Settings::getMinerFee()));
|
||||
ui->minerFeeAmt->setText(Settings::getMinerFee().toDecimalString());
|
||||
|
||||
// Start the deletion after the first item, since we want to keep 1 send field there all there
|
||||
for (int i=1; i < totalItems; i++) {
|
||||
@@ -462,29 +393,22 @@ void MainWindow::maxAmountChecked(int checked) {
|
||||
if (rpc == nullptr) return;
|
||||
|
||||
// Calculate maximum amount
|
||||
double sumAllAmounts = 0.0;
|
||||
CAmount sumAllAmounts;
|
||||
// Calculate all other amounts
|
||||
int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that
|
||||
// Start counting the sum skipping the first one, because the MAX button is on the first one, and we don't
|
||||
// want to include it in the sum.
|
||||
for (int i=1; i < totalItems; i++) {
|
||||
auto amt = ui->sendToWidgets->findChild<QLineEdit*>(QString("Amount") % QString::number(i+1));
|
||||
sumAllAmounts += amt->text().toDouble();
|
||||
sumAllAmounts = sumAllAmounts + CAmount::fromDecimalString(amt->text());
|
||||
}
|
||||
|
||||
if (Settings::getInstance()->getAllowCustomFees()) {
|
||||
sumAllAmounts = ui->minerFeeAmt->text().toDouble();
|
||||
}
|
||||
else {
|
||||
sumAllAmounts += Settings::getMinerFee();
|
||||
}
|
||||
|
||||
auto addr = ui->inputsCombo->currentText();
|
||||
|
||||
auto maxamount = rpc->getModel()->getAllBalances().value(addr) - sumAllAmounts;
|
||||
maxamount = (maxamount < 0) ? 0 : maxamount;
|
||||
sumAllAmounts = sumAllAmounts + Settings::getMinerFee();
|
||||
|
||||
auto maxamount = rpc->getModel()->getAvailableBalance() - sumAllAmounts;
|
||||
maxamount = (maxamount < 0) ? CAmount::fromqint64(0): maxamount;
|
||||
|
||||
ui->Amount1->setText(Settings::getDecimalString(maxamount));
|
||||
ui->Amount1->setText(maxamount.toDecimalString());
|
||||
} else if (checked == Qt::Unchecked) {
|
||||
// Just remove the readonly part, don't change the content
|
||||
ui->Amount1->setReadOnly(false);
|
||||
@@ -495,60 +419,37 @@ void MainWindow::maxAmountChecked(int checked) {
|
||||
Tx MainWindow::createTxFromSendPage() {
|
||||
Tx tx;
|
||||
|
||||
bool sendChangeToSapling = Settings::getInstance()->getAutoShield();
|
||||
|
||||
// Gather the from / to addresses
|
||||
tx.fromAddr = ui->inputsCombo->currentText();
|
||||
sendChangeToSapling = sendChangeToSapling && Settings::isTAddress(tx.fromAddr);
|
||||
|
||||
// For each addr/amt in the sendTo tab
|
||||
int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that
|
||||
double totalAmt = 0;
|
||||
CAmount totalAmt;
|
||||
for (int i=0; i < totalItems; i++) {
|
||||
QString addr = ui->sendToWidgets->findChild<QLineEdit*>(QString("Address") % QString::number(i+1))->text().trimmed();
|
||||
// Remove label if it exists
|
||||
addr = AddressBook::addressFromAddressLabel(addr);
|
||||
|
||||
// If address is sprout, then we can't send change to sapling, because of turnstile.
|
||||
sendChangeToSapling = sendChangeToSapling && !Settings::getInstance()->isSproutAddress(addr);
|
||||
double amt = ui->sendToWidgets->findChild<QLineEdit*>(QString("Amount") % QString::number(i+1))->text().trimmed().toDouble();
|
||||
totalAmt += amt;
|
||||
QString amtStr = ui->sendToWidgets->findChild<QLineEdit*>(QString("Amount") % QString::number(i+1))->text().trimmed();
|
||||
if (amtStr.isEmpty()) {
|
||||
amtStr = "-1";; // The user didn't specify an amount
|
||||
}
|
||||
|
||||
bool ok;
|
||||
CAmount amt;
|
||||
|
||||
// Make sure it parses
|
||||
amtStr.toDouble(&ok);
|
||||
if (!ok) {
|
||||
amt = CAmount::fromqint64(-1);
|
||||
} else {
|
||||
amt = CAmount::fromDecimalString(amtStr);
|
||||
totalAmt = totalAmt + amt;
|
||||
}
|
||||
|
||||
QString memo = ui->sendToWidgets->findChild<QLabel*>(QString("MemoTxt") % QString::number(i+1))->text().trimmed();
|
||||
|
||||
tx.toAddrs.push_back( ToFields{addr, amt, memo,} );
|
||||
}
|
||||
|
||||
if (Settings::getInstance()->getAllowCustomFees()) {
|
||||
tx.fee = ui->minerFeeAmt->text().toDouble();
|
||||
}
|
||||
else {
|
||||
tx.fee = Settings::getMinerFee();
|
||||
}
|
||||
|
||||
if (Settings::getInstance()->getAutoShield() && sendChangeToSapling) {
|
||||
auto saplingAddr = std::find_if(rpc->getModel()->getAllZAddresses().begin(), rpc->getModel()->getAllZAddresses().end(), [=](auto i) -> bool {
|
||||
// We're finding a sapling address that is not one of the To addresses, because hush doesn't allow duplicated addresses
|
||||
bool isSapling = Settings::getInstance()->isSaplingAddress(i);
|
||||
if (!isSapling) return false;
|
||||
|
||||
// Also check all the To addresses
|
||||
for (auto t : tx.toAddrs) {
|
||||
if (t.addr == i)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (saplingAddr != rpc->getModel()->getAllZAddresses().end()) {
|
||||
double change = rpc->getModel()->getAllBalances().value(tx.fromAddr) - totalAmt - tx.fee;
|
||||
|
||||
if (Settings::getDecimalString(change) != "0") {
|
||||
QString changeMemo = tr("Change from ") + tx.fromAddr;
|
||||
tx.toAddrs.push_back(ToFields{ *saplingAddr, change, changeMemo});
|
||||
}
|
||||
}
|
||||
}
|
||||
tx.fee = Settings::getMinerFee();
|
||||
|
||||
return tx;
|
||||
}
|
||||
@@ -613,7 +514,7 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
|
||||
|
||||
// For each addr/amt/memo, construct the JSON and also build the confirm dialog box
|
||||
int row = 0;
|
||||
double totalSpending = 0;
|
||||
CAmount totalSpending;
|
||||
|
||||
for (int i=0; i < tx.toAddrs.size(); i++) {
|
||||
auto toAddr = tx.toAddrs[i];
|
||||
@@ -631,15 +532,15 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
|
||||
// Amount (hush)
|
||||
auto Amt = new QLabel(confirm.sendToAddrs);
|
||||
Amt->setObjectName(QString("Amt") % QString::number(i + 1));
|
||||
Amt->setText(Settings::gethushDisplayFormat(toAddr.amount));
|
||||
Amt->setText(toAddr.amount.toDecimalhushString());
|
||||
Amt->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
|
||||
confirm.gridLayout->addWidget(Amt, row, 1, 1, 1);
|
||||
totalSpending += toAddr.amount;
|
||||
totalSpending = totalSpending + toAddr.amount;
|
||||
|
||||
// Amount (USD)
|
||||
auto AmtUSD = new QLabel(confirm.sendToAddrs);
|
||||
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
|
||||
AmtUSD->setText(Settings::getUSDFormat(toAddr.amount));
|
||||
AmtUSD->setText(toAddr.amount.toDecimalUSDString());
|
||||
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
|
||||
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
|
||||
|
||||
@@ -681,8 +582,8 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
|
||||
minerFee->setObjectName(QStringLiteral("minerFee"));
|
||||
minerFee->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||
confirm.gridLayout->addWidget(minerFee, row, 1, 1, 1);
|
||||
minerFee->setText(Settings::gethushDisplayFormat(tx.fee));
|
||||
totalSpending += tx.fee;
|
||||
minerFee->setText(tx.fee.toDecimalhushString());
|
||||
totalSpending = totalSpending + tx.fee;
|
||||
|
||||
auto minerFeeUSD = new QLabel(confirm.sendToAddrs);
|
||||
QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Preferred);
|
||||
@@ -690,14 +591,7 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
|
||||
minerFeeUSD->setObjectName(QStringLiteral("minerFeeUSD"));
|
||||
minerFeeUSD->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||
confirm.gridLayout->addWidget(minerFeeUSD, row, 2, 1, 1);
|
||||
minerFeeUSD->setText(Settings::getUSDFormat(tx.fee));
|
||||
|
||||
if (Settings::getInstance()->getAllowCustomFees() && tx.fee != Settings::getMinerFee()) {
|
||||
confirm.warningLabel->setVisible(true);
|
||||
} else {
|
||||
// Default fee
|
||||
confirm.warningLabel->setVisible(false);
|
||||
}
|
||||
minerFeeUSD->setText(tx.fee.toDecimalUSDString());
|
||||
}
|
||||
|
||||
// Recurring payment info, show only if there is exactly one destination address
|
||||
@@ -712,16 +606,13 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
|
||||
// Syncing warning
|
||||
confirm.syncingWarning->setVisible(Settings::getInstance()->isSyncing());
|
||||
|
||||
// No peers warning
|
||||
confirm.nopeersWarning->setVisible(Settings::getInstance()->getPeers() == 0);
|
||||
|
||||
// And FromAddress in the confirm dialog
|
||||
confirm.sendFrom->setText(fnSplitAddressForWrap(tx.fromAddr));
|
||||
confirm.sendFrom->setFont(fixedFont);
|
||||
QString tooltip = tr("Current balance : ") +
|
||||
Settings::gethushUSDDisplayFormat(rpc->getModel()->getAllBalances().value(tx.fromAddr));
|
||||
rpc->getModel()->getAllBalances().value(tx.fromAddr).toDecimalhushUSDString();
|
||||
tooltip += "\n" + tr("Balance after this Tx: ") +
|
||||
Settings::gethushUSDDisplayFormat(rpc->getModel()->getAllBalances().value(tx.fromAddr) - totalSpending);
|
||||
(rpc->getModel()->getAllBalances().value(tx.fromAddr) - totalSpending).toDecimalhushUSDString();
|
||||
confirm.sendFrom->setToolTip(tooltip);
|
||||
|
||||
// Show the dialog and submit it if the user confirms
|
||||
@@ -805,13 +696,12 @@ QString MainWindow::doSendTxValidations(Tx tx) {
|
||||
|
||||
// This technically shouldn't be possible, but issue #62 seems to have discovered a bug
|
||||
// somewhere, so just add a check to make sure.
|
||||
if (toAddr.amount < 0) {
|
||||
if (toAddr.amount.toqint64() < 0) {
|
||||
return QString(tr("Amount for address '%1' is invalid!").arg(toAddr.addr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return QString();
|
||||
return "";
|
||||
}
|
||||
|
||||
void MainWindow::cancelButton() {
|
||||
|
||||
159
src/settings.cpp
@@ -1,5 +1,6 @@
|
||||
#include "mainwindow.h"
|
||||
#include "settings.h"
|
||||
#include "camount.h"
|
||||
|
||||
Settings* Settings::instance = nullptr;
|
||||
|
||||
@@ -18,33 +19,24 @@ Config Settings::getSettings() {
|
||||
// Load from the QT Settings.
|
||||
QSettings s;
|
||||
|
||||
auto host = s.value("connection/host").toString();
|
||||
auto port = s.value("connection/port").toString();
|
||||
auto username = s.value("connection/rpcuser").toString();
|
||||
auto password = s.value("connection/rpcpassword").toString();
|
||||
auto server = s.value("connection/server").toString();
|
||||
if (server.trimmed().isEmpty()) {
|
||||
server = Settings::getDefaultServer();
|
||||
}
|
||||
|
||||
return Config{host, port, username, password};
|
||||
return Config{server};
|
||||
}
|
||||
|
||||
void Settings::saveSettings(const QString& host, const QString& port, const QString& username, const QString& password) {
|
||||
void Settings::saveSettings(const QString& server) {
|
||||
QSettings s;
|
||||
|
||||
s.setValue("connection/host", host);
|
||||
s.setValue("connection/port", port);
|
||||
s.setValue("connection/rpcuser", username);
|
||||
s.setValue("connection/rpcpassword", password);
|
||||
|
||||
s.setValue("connection/server", server);
|
||||
s.sync();
|
||||
|
||||
// re-init to load correct settings
|
||||
init();
|
||||
}
|
||||
|
||||
void Settings::setUsinghushConf(QString confLocation) {
|
||||
if (!confLocation.isEmpty())
|
||||
_confLocation = confLocation;
|
||||
}
|
||||
|
||||
bool Settings::isTestnet() {
|
||||
return _isTestnet;
|
||||
}
|
||||
@@ -114,15 +106,6 @@ double Settings::gethushPrice() {
|
||||
return hushPrice;
|
||||
}
|
||||
|
||||
bool Settings::getAutoShield() {
|
||||
// Load from Qt settings
|
||||
return QSettings().value("options/autoshield", false).toBool();
|
||||
}
|
||||
|
||||
void Settings::setAutoShield(bool allow) {
|
||||
QSettings().setValue("options/autoshield", allow);
|
||||
}
|
||||
|
||||
bool Settings::getCheckForUpdates() {
|
||||
return QSettings().value("options/allowcheckupdates", true).toBool();
|
||||
}
|
||||
@@ -139,15 +122,6 @@ void Settings::setAllowFetchPrices(bool allow) {
|
||||
QSettings().setValue("options/allowfetchprices", allow);
|
||||
}
|
||||
|
||||
bool Settings::getAllowCustomFees() {
|
||||
// Load from the QT Settings.
|
||||
return QSettings().value("options/customfees", false).toBool();
|
||||
}
|
||||
|
||||
void Settings::setAllowCustomFees(bool allow) {
|
||||
QSettings().setValue("options/customfees", allow);
|
||||
}
|
||||
|
||||
QString Settings::get_theme_name() {
|
||||
// Load from the QT Settings.
|
||||
return QSettings().value("options/theme_name", false).toString();
|
||||
@@ -157,22 +131,7 @@ void Settings::set_theme_name(QString theme_name) {
|
||||
QSettings().setValue("options/theme_name", theme_name);
|
||||
}
|
||||
|
||||
bool Settings::getSaveZtxs() {
|
||||
// Load from the QT Settings.
|
||||
return QSettings().value("options/savesenttx", true).toBool();
|
||||
}
|
||||
|
||||
void Settings::setSaveZtxs(bool save) {
|
||||
QSettings().setValue("options/savesenttx", save);
|
||||
}
|
||||
|
||||
void Settings::setPeers(int peers) {
|
||||
_peerConnections = peers;
|
||||
}
|
||||
|
||||
int Settings::getPeers() {
|
||||
return _peerConnections;
|
||||
}
|
||||
//=================================
|
||||
// Static Stuff
|
||||
//=================================
|
||||
@@ -193,6 +152,10 @@ void Settings::saveRestoreTableHeader(QTableView* table, QDialog* d, QString tab
|
||||
});
|
||||
}
|
||||
|
||||
QString Settings::getDefaultServer() {
|
||||
return "https://hush-lightwallet.de:439/";
|
||||
}
|
||||
|
||||
void Settings::openAddressInExplorer(QString address) {
|
||||
QString url;
|
||||
if (Settings::getInstance()->isTestnet()) {
|
||||
@@ -216,37 +179,6 @@ void Settings::openTxInExplorer(QString txid) {
|
||||
|
||||
|
||||
|
||||
|
||||
QString Settings::getUSDFormat(double bal) {
|
||||
return "$" + QLocale(QLocale::English).toString(bal * Settings::getInstance()->gethushPrice(), 'f', 2);
|
||||
}
|
||||
|
||||
QString Settings::getDecimalString(double amt) {
|
||||
QString f = QString::number(amt, 'f', 8);
|
||||
|
||||
while (f.contains(".") && (f.right(1) == "0" || f.right(1) == ".")) {
|
||||
f = f.left(f.length() - 1);
|
||||
}
|
||||
if (f == "-0")
|
||||
f = "0";
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
QString Settings::gethushDisplayFormat(double bal) {
|
||||
// This is idiotic. Why doesn't QString have a way to do this?
|
||||
return getDecimalString(bal) % " " % Settings::getTokenName();
|
||||
}
|
||||
|
||||
QString Settings::gethushUSDDisplayFormat(double bal) {
|
||||
auto usdFormat = getUSDFormat(bal);
|
||||
if (!usdFormat.isEmpty())
|
||||
return gethushDisplayFormat(bal) % " (" % getUSDFormat(bal) % ")";
|
||||
else
|
||||
return gethushDisplayFormat(bal);
|
||||
}
|
||||
|
||||
|
||||
const QString Settings::txidStatusMessage = QString(QObject::tr("Tx submitted (right click to copy) txid:"));
|
||||
|
||||
QString Settings::getTokenName() {
|
||||
@@ -265,68 +197,8 @@ QString Settings::getDonationAddr() {
|
||||
|
||||
}
|
||||
|
||||
bool Settings::addTohushConf(QString confLocation, QString line) {
|
||||
QFile file(confLocation);
|
||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Append))
|
||||
return false;
|
||||
|
||||
|
||||
QTextStream out(&file);
|
||||
out << line << "\n";
|
||||
file.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Settings::removeFromhushConf(QString confLocation, QString option) {
|
||||
if (confLocation.isEmpty())
|
||||
return false;
|
||||
|
||||
// To remove an option, we'll create a new file, and copy over everything but the option.
|
||||
QFile file(confLocation);
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
return false;
|
||||
|
||||
QList<QString> lines;
|
||||
QTextStream in(&file);
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine();
|
||||
auto s = line.indexOf("=");
|
||||
QString name = line.left(s).trimmed().toLower();
|
||||
if (name != option) {
|
||||
lines.append(line);
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
|
||||
QFile newfile(confLocation);
|
||||
if (!newfile.open(QIODevice::ReadWrite | QIODevice::Truncate))
|
||||
return false;
|
||||
|
||||
QTextStream out(&newfile);
|
||||
for (QString line : lines) {
|
||||
out << line << endl;
|
||||
}
|
||||
newfile.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
double Settings::getMinerFee() {
|
||||
return 0.0001;
|
||||
}
|
||||
|
||||
double Settings::getZboardAmount() {
|
||||
return 0.0001;
|
||||
}
|
||||
|
||||
QString Settings::getZboardAddr() {
|
||||
if (Settings::getInstance()->isTestnet()) {
|
||||
return getDonationAddr();
|
||||
}
|
||||
else {
|
||||
return "zs10m00rvkhfm4f7n23e4sxsx275r7ptnggx39ygl0vy46j9mdll5c97gl6dxgpk0njuptg2mn9w5s";
|
||||
}
|
||||
CAmount Settings::getMinerFee() {
|
||||
return CAmount::fromqint64(10000);
|
||||
}
|
||||
|
||||
bool Settings::isValidSaplingPrivateKey(QString pk) {
|
||||
@@ -349,7 +221,8 @@ bool Settings::isValidAddress(QString addr) {
|
||||
|
||||
// Get a pretty string representation of this Payment URI
|
||||
QString Settings::paymentURIPretty(PaymentURI uri) {
|
||||
return QString() + "Payment Request\n" + "Pay: " + uri.addr + "\nAmount: " + gethushDisplayFormat(uri.amt.toDouble())
|
||||
CAmount amount = CAmount::fromDecimalString(uri.amt);
|
||||
return QString() + "Payment Request\n" + "Pay: " + uri.addr + "\nAmount: " + amount.toDecimalhushString()
|
||||
+ "\nMemo:" + QUrl::fromPercentEncoding(uri.memo.toUtf8());
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
#define SETTINGS_H
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "camount.h"
|
||||
|
||||
struct Config {
|
||||
QString host;
|
||||
QString port;
|
||||
QString rpcuser;
|
||||
QString rpcpassword;
|
||||
QString server;
|
||||
};
|
||||
|
||||
struct ToFields;
|
||||
@@ -29,7 +27,7 @@ public:
|
||||
static Settings* getInstance();
|
||||
|
||||
Config getSettings();
|
||||
void saveSettings(const QString& host, const QString& port, const QString& username, const QString& password);
|
||||
void saveSettings(const QString& server);
|
||||
|
||||
bool isTestnet();
|
||||
void setTestnet(bool isTestnet);
|
||||
@@ -54,15 +52,6 @@ public:
|
||||
int getBlockNumber();
|
||||
void setBlockNumber(int number);
|
||||
|
||||
bool getSaveZtxs();
|
||||
void setSaveZtxs(bool save);
|
||||
|
||||
bool getAutoShield();
|
||||
void setAutoShield(bool allow);
|
||||
|
||||
bool getAllowCustomFees();
|
||||
void setAllowCustomFees(bool allow);
|
||||
|
||||
bool getAllowFetchPrices();
|
||||
void setAllowFetchPrices(bool allow);
|
||||
|
||||
@@ -74,15 +63,9 @@ public:
|
||||
|
||||
bool isSaplingActive();
|
||||
|
||||
void setUsinghushConf(QString confLocation);
|
||||
const QString& gethushdConfLocation() { return _confLocation; }
|
||||
|
||||
void sethushPrice(double p) { hushPrice = p; }
|
||||
double gethushPrice();
|
||||
|
||||
void setPeers(int peers);
|
||||
int getPeers();
|
||||
|
||||
// Static stuff
|
||||
static const QString txidStatusMessage;
|
||||
|
||||
@@ -98,27 +81,18 @@ public:
|
||||
static bool isZAddress(QString addr);
|
||||
static bool isTAddress(QString addr);
|
||||
|
||||
static QString getDecimalString(double amt);
|
||||
static QString getUSDFormat(double bal);
|
||||
|
||||
|
||||
static QString gethushDisplayFormat(double bal);
|
||||
static QString gethushUSDDisplayFormat(double bal);
|
||||
|
||||
static QString getTokenName();
|
||||
static QString getDonationAddr();
|
||||
|
||||
static double getMinerFee();
|
||||
static double getZboardAmount();
|
||||
static QString getZboardAddr();
|
||||
static QString getDefaultServer();
|
||||
static CAmount getMinerFee();
|
||||
|
||||
static int getMaxMobileAppTxns() { return 30; }
|
||||
|
||||
static int getNumberOfDecimalPlaces() {return 8;}
|
||||
|
||||
static bool isValidAddress(QString addr);
|
||||
|
||||
static bool addTohushConf(QString confLocation, QString line);
|
||||
static bool removeFromhushConf(QString confLocation, QString option);
|
||||
|
||||
static QString getChainName() { return QString("main"); }
|
||||
|
||||
static const QString labelRegExp;
|
||||
@@ -134,7 +108,6 @@ private:
|
||||
|
||||
static Settings* instance;
|
||||
|
||||
QString _confLocation;
|
||||
QString _executable;
|
||||
bool _isTestnet = false;
|
||||
bool _isSyncing = false;
|
||||
@@ -142,7 +115,6 @@ private:
|
||||
int _hushdVersion = 0;
|
||||
bool _useEmbedded = false;
|
||||
bool _headless = false;
|
||||
int _peerConnections = 0;
|
||||
|
||||
double hushPrice = 0.0;
|
||||
};
|
||||
|
||||
353
src/settings.ui
@@ -26,11 +26,11 @@
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>hushd connection</string>
|
||||
<string>Connection</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
@@ -43,13 +43,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="minimumSize">
|
||||
@@ -59,69 +52,17 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Host</string>
|
||||
<string>Server</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="hostname">
|
||||
<widget class="QLineEdit" name="txtServer">
|
||||
<property name="placeholderText">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="port">
|
||||
<property name="placeholderText">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RPC Username</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="rpcuser"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RPC Password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="rpcpassword"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2"/>
|
||||
</item>
|
||||
@@ -145,165 +86,7 @@
|
||||
<string>Options</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="10" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Connect to github on startup to check for updates</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Normally, change from t-Addresses goes to another t-Address. Checking this option will send the change to your shielded sapling address instead. Check this option to increase your privacy.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="btnClearSaved">
|
||||
<property name="text">
|
||||
<string>Clear History</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="chkSaveTxs">
|
||||
<property name="text">
|
||||
<string>Remember shielded transactions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Connect to the internet to fetch hush prices</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Allow overriding the default fees when sending transactions. Enabling this option may compromise your privacy since fees are transparent. </string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="chkCheckUpdates">
|
||||
<property name="text">
|
||||
<string>Check github for updates at startup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Shielded transactions are saved locally and shown in the transactions tab. If you uncheck this, shielded transactions will not appear in the transactions tab.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="chkAutoShield">
|
||||
<property name="text">
|
||||
<string>Shield change from t-Addresses to your sapling address</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="0" colspan="2">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<widget class="QLabel" name="lblTor">
|
||||
<property name="text">
|
||||
<string>Connect to the Tor network via SOCKS proxy running on 127.0.0.1:9050. Please note that you'll have to install and run the Tor service externally.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QCheckBox" name="chkTor">
|
||||
<property name="text">
|
||||
<string>Connect via Tor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="chkCustomFees">
|
||||
<property name="text">
|
||||
<string>Allow custom fees</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="chkFetchPrices">
|
||||
<property name="text">
|
||||
<string>Fetch hush / USD prices</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Theme</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="comboBoxTheme">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
@@ -333,6 +116,76 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="chkFetchPrices">
|
||||
<property name="text">
|
||||
<string>Fetch hush / USD prices</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="chkCheckUpdates">
|
||||
<property name="text">
|
||||
<string>Check github for updates at startup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Connect to github on startup to check for updates</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Theme</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Connect to the internet to fetch hush prices</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
@@ -341,37 +194,6 @@
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="chkReindex">
|
||||
<property name="text">
|
||||
<string>Reindex</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Rescan the blockchain for any missing wallet transactions and to correct your wallet balance. This may take several hours. You need to restart silentdragon for this to take effect</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="chkRescan">
|
||||
<property name="text">
|
||||
<string>Rescan</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="Line" name="line_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -385,33 +207,26 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string/>
|
||||
<widget class="Line" name="line_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Rebuild the entire blockchain from the genesis block, by rescanning all the block files. This may take several hours to days, depending on your hardware. You need to restart silentdragon for this to take effect</string>
|
||||
<string>Rescan the blockchain for any missing wallet transactions and to correct your wallet balance. This may take several hours. You need to restart hushWallet for this to take effect</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="Line" name="line_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="chkRescan">
|
||||
<property name="text">
|
||||
<string/>
|
||||
<string>Rescan</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -105,11 +105,11 @@ bool TxTableModel::exportToCsv(QString fileName) const {
|
||||
case Column::Confirmations: return QString::number(dat.confirmations);
|
||||
case Column::Amount: {
|
||||
// Sum up all the amounts
|
||||
double total = 0;
|
||||
CAmount total;
|
||||
for (int i=0; i < dat.items.length(); i++) {
|
||||
total += dat.items[i].amount;
|
||||
total = total + dat.items[i].amount;
|
||||
}
|
||||
return Settings::gethushDisplayFormat(total);
|
||||
return total.toDecimalhushString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,11 +141,11 @@ bool TxTableModel::exportToCsv(QString fileName) const {
|
||||
case Column::Confirmations: return QString("%1 Network Confirmations").arg(QString::number(dat.confirmations));
|
||||
case Column::Amount: {
|
||||
// Sum up all the amounts
|
||||
double total = 0;
|
||||
CAmount total;
|
||||
for (int i=0; i < dat.items.length(); i++) {
|
||||
total += dat.items[i].amount;
|
||||
total = total + dat.items[i].amount;
|
||||
}
|
||||
return Settings::getInstance()->getUSDFormat(total);
|
||||
return total.toDecimalUSDString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -237,9 +237,9 @@ QString TxTableModel::getType(int row) const {
|
||||
QString TxTableModel::getAmt(int row) const {
|
||||
auto dat = modeldata->at(row);
|
||||
|
||||
double total = 0;
|
||||
CAmount total;
|
||||
for (int i=0; i < dat.items.length(); i++) {
|
||||
total += dat.items[i].amount;
|
||||
total = total + dat.items[i].amount;
|
||||
}
|
||||
return Settings::getDecimalString(total);
|
||||
return total.toDecimalString();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "viewalladdresses.h"
|
||||
#include "camount.h"
|
||||
#include "settings.h"
|
||||
|
||||
ViewAllAddressesModel::ViewAllAddressesModel(QTableView *parent, QList<QString> taddrs, Controller* rpc)
|
||||
@@ -22,7 +23,7 @@ QVariant ViewAllAddressesModel::data(const QModelIndex &index, int role) const {
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch(index.column()) {
|
||||
case 0: return address;
|
||||
case 1: return rpc->getModel()->getAllBalances().value(address, 0.0);
|
||||
case 1: return rpc->getModel()->getAllBalances().value(address, CAmount::fromqint64(0)).toDecimalString();
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
|
||||
@@ -658,9 +658,9 @@ void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, st
|
||||
tx.fee = Settings::getMinerFee();
|
||||
|
||||
// Find a from address that has at least the sending amout
|
||||
double amt = sendTx["amount"].toString().toDouble();
|
||||
CAmount amt = CAmount::fromDecimalString(sendTx["amount"].toString());
|
||||
auto allBalances = mainwindow->getRPC()->getModel()->getAllBalances();
|
||||
QList<QPair<QString, double>> bals;
|
||||
QList<QPair<QString, CAmount>> bals;
|
||||
for (auto i : allBalances.keys()) {
|
||||
// Filter out sprout addresses
|
||||
if (Settings::getInstance()->isSproutAddress(i))
|
||||
@@ -669,7 +669,7 @@ void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, st
|
||||
if (allBalances.value(i) < amt)
|
||||
continue;
|
||||
|
||||
bals.append(QPair<QString, double>(i, allBalances.value(i)));
|
||||
bals.append(QPair<QString, CAmount>(i, allBalances.value(i)));
|
||||
}
|
||||
|
||||
if (bals.isEmpty()) {
|
||||
@@ -677,7 +677,7 @@ void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, st
|
||||
return;
|
||||
}
|
||||
|
||||
std::sort(bals.begin(), bals.end(), [=](const QPair<QString, double>a, const QPair<QString, double> b) -> bool {
|
||||
std::sort(bals.begin(), bals.end(), [=](const QPair<QString, CAmount>a, const QPair<QString, CAmount> b) -> bool {
|
||||
// Sort z addresses first
|
||||
return a.first > b.first;
|
||||
});
|
||||
@@ -736,8 +736,8 @@ void AppDataServer::processGetInfo(QJsonObject jobj, MainWindow* mainWindow, std
|
||||
}
|
||||
|
||||
// Max spendable safely from a z address and from any address
|
||||
double maxZSpendable = 0;
|
||||
double maxSpendable = 0;
|
||||
CAmount maxZSpendable;
|
||||
CAmount maxSpendable;
|
||||
for (auto a : mainWindow->getRPC()->getModel()->getAllBalances().keys()) {
|
||||
if (Settings::getInstance()->isSaplingAddress(a)) {
|
||||
if (mainWindow->getRPC()->getModel()->getAllBalances().value(a) > maxZSpendable) {
|
||||
@@ -751,14 +751,14 @@ void AppDataServer::processGetInfo(QJsonObject jobj, MainWindow* mainWindow, std
|
||||
|
||||
setConnectedName(connectedName);
|
||||
|
||||
auto r = QJsonDocument(QJsonObject{
|
||||
auto r = QJsonDocument(QJsonObject {
|
||||
{"version", 1.0},
|
||||
{"command", "getInfo"},
|
||||
{"saplingAddress", mainWindow->getRPC()->getDefaultSaplingAddress()},
|
||||
{"tAddress", mainWindow->getRPC()->getDefaultTAddress()},
|
||||
{"balance", AppDataModel::getInstance()->getTotalBalance()},
|
||||
{"maxspendable", maxSpendable},
|
||||
{"maxzspendable", maxZSpendable},
|
||||
{"balance", AppDataModel::getInstance()->getTotalBalance().toDecimalDouble()},
|
||||
{"maxspendable", maxSpendable.toDecimalDouble()},
|
||||
{"maxzspendable", maxZSpendable.toDecimalDouble()},
|
||||
{"tokenName", Settings::getTokenName()},
|
||||
{"hushprice", Settings::getInstance()->gethushPrice()},
|
||||
{"serverversion", QString(APP_VERSION)}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "camount.h"
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mobileappconnector.h"
|
||||
|
||||
@@ -151,11 +152,11 @@ public:
|
||||
return instance;
|
||||
}
|
||||
|
||||
double getTBalance() { return balTransparent; }
|
||||
double getZBalance() { return balShielded; }
|
||||
double getTotalBalance() { return balTotal; }
|
||||
CAmount getTBalance() { return balTransparent; }
|
||||
CAmount getZBalance() { return balShielded; }
|
||||
CAmount getTotalBalance() { return balTotal; }
|
||||
|
||||
void setBalances(double transparent, double shielded) {
|
||||
void setBalances(CAmount transparent, CAmount shielded) {
|
||||
balTransparent = transparent;
|
||||
balShielded = shielded;
|
||||
balTotal = balTransparent + balShielded;
|
||||
@@ -164,9 +165,9 @@ public:
|
||||
private:
|
||||
AppDataModel() = default; // Private, for singleton
|
||||
|
||||
double balTransparent;
|
||||
double balShielded;
|
||||
double balTotal;
|
||||
CAmount balTransparent;
|
||||
CAmount balShielded;
|
||||
CAmount balTotal;
|
||||
|
||||
QString saplingAddress;
|
||||
|
||||
|
||||