Compare commits
677 Commits
v0.0-beta-
...
v0.11.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f14fde89c | ||
|
|
d8ebafaec0 | ||
|
|
7340371cc9 | ||
|
|
cc17b75a54 | ||
|
|
8f73bac95c | ||
|
|
e4177bb365 | ||
|
|
80a058c954 | ||
|
|
ff1780aeaa | ||
|
|
f1b70d08c6 | ||
|
|
0ae04fde4b | ||
|
|
c64321ebe9 | ||
|
|
34e7eb4e6b | ||
|
|
b888396ab4 | ||
|
|
508546c7c8 | ||
|
|
80618c83fd | ||
|
|
0d991b3792 | ||
|
|
61e8ac5b95 | ||
|
|
aac7fc613a | ||
|
|
e0d99cb1bb | ||
|
|
188eb064f4 | ||
|
|
84d09c85de | ||
|
|
b853380db6 | ||
|
|
ea49e84215 | ||
|
|
23d1d4a958 | ||
|
|
f52990c8e4 | ||
|
|
d69519f0aa | ||
|
|
605f81314a | ||
|
|
8ba9b0e7c7 | ||
|
|
8b94bd80c9 | ||
|
|
1f1d51d8e1 | ||
|
|
11df558f8e | ||
|
|
3c46d6d1bd | ||
|
|
7941f88e53 | ||
|
|
8750cc2c13 | ||
|
|
f932d7a245 | ||
|
|
6d0847c39f | ||
|
|
ba9a99a4c6 | ||
|
|
b1675ab1cd | ||
|
|
327cbd086f | ||
|
|
a681878344 | ||
|
|
9b835599b8 | ||
|
|
5767ad9cd5 | ||
|
|
4c75fe47f9 | ||
|
|
56868c06b5 | ||
|
|
3df70ff98c | ||
|
|
83ea363932 | ||
|
|
6d09555cd4 | ||
|
|
4d9d10013b | ||
|
|
ece743e22a | ||
|
|
86e9f3811b | ||
|
|
2bc86d1d9f | ||
|
|
fc576a8680 | ||
|
|
b8da85d0a4 | ||
|
|
3d0a571cc7 | ||
|
|
7c366ddf04 | ||
|
|
d0f3194574 | ||
|
|
98f768d2a6 | ||
|
|
77cd5a7a62 | ||
|
|
0d1b709def | ||
|
|
5f052964a9 | ||
|
|
39facceee6 | ||
|
|
c84abc7224 | ||
|
|
649f81954e | ||
|
|
1a156b8840 | ||
|
|
f7c883a6c3 | ||
|
|
31f318aaea | ||
|
|
94c92ba73c | ||
|
|
8480c70571 | ||
|
|
ee2b0fa713 | ||
|
|
9f4f2b582b | ||
|
|
d670f6d321 | ||
|
|
4ca5e82fca | ||
|
|
c29ccc13ae | ||
|
|
c04417d37b | ||
|
|
7521472325 | ||
|
|
73ba192a58 | ||
|
|
0fdc21e7fd | ||
|
|
ba0796b9ca | ||
|
|
1ce573afe2 | ||
|
|
234fd1bcda | ||
|
|
3adb29bc16 | ||
|
|
3f7e3ba3c4 | ||
|
|
a7f52db613 | ||
|
|
7f4fec7777 | ||
|
|
995a5e0046 | ||
|
|
13a65505a5 | ||
|
|
105336ba08 | ||
|
|
c39875de44 | ||
|
|
5339fbde8b | ||
|
|
47927e4822 | ||
|
|
c68c317776 | ||
|
|
b2cd48ceaf | ||
|
|
0eaebb01c4 | ||
|
|
c321147e36 | ||
|
|
27349d111d | ||
|
|
602a393d59 | ||
|
|
e9b6c510f4 | ||
|
|
5d78941712 | ||
|
|
fa27982650 | ||
|
|
f3eca6eadb | ||
|
|
009994b212 | ||
|
|
57a282c72a | ||
|
|
96808441cd | ||
|
|
6730b63018 | ||
|
|
7cc924d478 | ||
|
|
8a14e367d8 | ||
|
|
a0e38aafb2 | ||
|
|
4bac8fdb57 | ||
|
|
b41c981454 | ||
|
|
c65ee4e71c | ||
|
|
7d66cc5b25 | ||
|
|
e43b719b19 | ||
|
|
03af06718c | ||
|
|
b4ce56a994 | ||
|
|
92c0e00b12 | ||
|
|
e8bd548219 | ||
|
|
ed17399b74 | ||
|
|
04869f0aac | ||
|
|
16122d6e17 | ||
|
|
73895f5a7b | ||
|
|
535f1fc446 | ||
|
|
5d4f519a40 | ||
|
|
ff9d79da7a | ||
|
|
b8a4dab9b2 | ||
|
|
a492cb9f7e | ||
|
|
5043250a2a | ||
|
|
fe78f20c7c | ||
|
|
ecaa1a8e23 | ||
|
|
9e121fb676 | ||
|
|
62e1dc490f | ||
|
|
9037eed805 | ||
|
|
443eb47824 | ||
|
|
13753052bc | ||
|
|
08b54f69a5 | ||
|
|
037fa32c41 | ||
|
|
8e986b3a2d | ||
|
|
0cb6900295 | ||
|
|
affbb454fa | ||
|
|
a6f13f7ba2 | ||
|
|
8e14b8bc3e | ||
|
|
5cd05a51d4 | ||
|
|
c2c5f0c13d | ||
|
|
f11d2bc702 | ||
|
|
77448a6b73 | ||
|
|
a3e0589a5e | ||
|
|
41b2c282bd | ||
|
|
127790e4a1 | ||
|
|
9dc8879e2c | ||
|
|
72a7f1348f | ||
|
|
cfa2f816a5 | ||
|
|
de4ff2992e | ||
|
|
6beadba9cc | ||
|
|
6a0ed3ceae | ||
|
|
a046163477 | ||
|
|
5ec575b376 | ||
|
|
009362451d | ||
|
|
f6e7b79e81 | ||
|
|
d744d393f9 | ||
|
|
25852b4676 | ||
|
|
336726e82f | ||
|
|
afac71383b | ||
|
|
2ac9e8eabb | ||
|
|
fff5c716c8 | ||
|
|
2e53c524a1 | ||
|
|
da6aad33a4 | ||
|
|
f5450f9205 | ||
|
|
1f23df7e66 | ||
|
|
27e37f153f | ||
|
|
58f24efd39 | ||
|
|
24bd3010bf | ||
|
|
87ea145047 | ||
|
|
310df0befa | ||
|
|
a4a44d7c99 | ||
|
|
f00a181843 | ||
|
|
98b040670c | ||
|
|
f31b27d3fd | ||
|
|
8cd6f3f5b6 | ||
|
|
af1edc0c95 | ||
|
|
45106e5150 | ||
|
|
3a51c4b963 | ||
|
|
8da7c972db | ||
|
|
1c1d15821e | ||
|
|
ef4c2927b4 | ||
|
|
dd7732ce0c | ||
|
|
c750ca9507 | ||
|
|
feabe6713c | ||
|
|
a550c03a0b | ||
|
|
1336055e80 | ||
|
|
115102624e | ||
|
|
5a0adb18d3 | ||
|
|
a055293b52 | ||
|
|
a00c083ece | ||
|
|
22a769341a | ||
|
|
91757b8039 | ||
|
|
74da45766e | ||
|
|
949d85288d | ||
|
|
798b273888 | ||
|
|
e2bfe25b9d | ||
|
|
7f12d4869e | ||
|
|
b2f7058fcf | ||
|
|
06e01e3771 | ||
|
|
cbc9dd07c8 | ||
|
|
6633d309b5 | ||
|
|
1e7fbe5cb0 | ||
|
|
05084422a5 | ||
|
|
57ab7daa03 | ||
|
|
fc0a44cabc | ||
|
|
30e403fe58 | ||
|
|
5297b23248 | ||
|
|
96c8df23a4 | ||
|
|
06b12d167b | ||
|
|
4ca35af11a | ||
|
|
a154eabf87 | ||
|
|
2f5a865028 | ||
|
|
87d444d128 | ||
|
|
10c3b8c116 | ||
|
|
dcc633b716 | ||
|
|
b4f01b9f6a | ||
|
|
f6535354e4 | ||
|
|
60254812c8 | ||
|
|
d1b1823a50 | ||
|
|
fb456fc5fe | ||
|
|
508b512c45 | ||
|
|
b1d24f8aa7 | ||
|
|
6ba2548273 | ||
|
|
615ef5342e | ||
|
|
53e87b4a35 | ||
|
|
716010a869 | ||
|
|
fb3a6182fc | ||
|
|
4ee23b2218 | ||
|
|
d730766479 | ||
|
|
e231a1b63f | ||
|
|
0836bd9cfd | ||
|
|
6e381c3857 | ||
|
|
12573652a0 | ||
|
|
6262770e6e | ||
|
|
7fbd1cf1ca | ||
|
|
88b1403020 | ||
|
|
d782eacfd6 | ||
|
|
379b02c80b | ||
|
|
b3877868a3 | ||
|
|
716106c23e | ||
|
|
c3ae7f8c80 | ||
|
|
d85dfa4fae | ||
|
|
7c5cf985b5 | ||
|
|
5969284de8 | ||
|
|
61266ca17e | ||
|
|
84c8f790b6 | ||
|
|
b2827ca1dd | ||
|
|
8719caad1b | ||
|
|
bd2a336c5e | ||
|
|
46d573e697 | ||
|
|
9c4c34d502 | ||
|
|
413d064127 | ||
|
|
db306ca823 | ||
|
|
b4cab574bc | ||
|
|
f05f0b73c3 | ||
|
|
6fbba9f88c | ||
|
|
b1f5d69ce5 | ||
|
|
55116a0963 | ||
|
|
d759e0ee44 | ||
|
|
f6f8e219e7 | ||
|
|
d884edf136 | ||
|
|
439372ed5e | ||
|
|
476fdd4ebe | ||
|
|
9fb7c19b9b | ||
|
|
caf7b7fc6b | ||
|
|
2ce455940d | ||
|
|
e5719791bd | ||
|
|
57ae6df949 | ||
|
|
9f3bd9d896 | ||
|
|
9e3b3d89b6 | ||
|
|
eb24356a95 | ||
|
|
5952ff96d7 | ||
|
|
89fb48138f | ||
|
|
60890b9185 | ||
|
|
97f9fb6f01 | ||
|
|
a3c9c98652 | ||
|
|
48a7596953 | ||
|
|
93e20be247 | ||
|
|
a0233f103e | ||
|
|
df78427745 | ||
|
|
a32b30e98b | ||
|
|
f0a441301b | ||
|
|
174d6ad019 | ||
|
|
2e8051067f | ||
|
|
deb75afb7e | ||
|
|
62089df6e7 | ||
|
|
2542b14534 | ||
|
|
42fb1ed51d | ||
|
|
23a3b1265a | ||
|
|
1fe0600e1e | ||
|
|
a9e975f2cd | ||
|
|
1d74fa6f47 | ||
|
|
d920b20168 | ||
|
|
ec5c73e8aa | ||
|
|
f3dfd18641 | ||
|
|
3ecffbc767 | ||
|
|
b75fee7a68 | ||
|
|
94ca32a164 | ||
|
|
2839bcc7fb | ||
|
|
91e01d5470 | ||
|
|
760f34579f | ||
|
|
19157590a5 | ||
|
|
172243cdad | ||
|
|
d42d2dd742 | ||
|
|
10b00f8778 | ||
|
|
064c9805f6 | ||
|
|
5f2e5b041c | ||
|
|
7ab5511de3 | ||
|
|
51074a8fe6 | ||
|
|
43a33e717d | ||
|
|
69e037ba4d | ||
|
|
cdb9376b85 | ||
|
|
24c17a9fe3 | ||
|
|
628483c310 | ||
|
|
aeea9ad324 | ||
|
|
8655076b92 | ||
|
|
4310fb096b | ||
|
|
62fe3820e2 | ||
|
|
e4aa338869 | ||
|
|
f22e5fdd7b | ||
|
|
ed28144ae8 | ||
|
|
0090303a18 | ||
|
|
d6dd97f308 | ||
|
|
53d7962eaa | ||
|
|
58e68be613 | ||
|
|
ce8e5fe714 | ||
|
|
577726c184 | ||
|
|
e4a114321f | ||
|
|
2b24c91bc5 | ||
|
|
692f927903 | ||
|
|
35cd788968 | ||
|
|
82cb50994c | ||
|
|
897bc582f0 | ||
|
|
b0d0974561 | ||
|
|
fd4619628c | ||
|
|
5cf84ff1f5 | ||
|
|
7960241306 | ||
|
|
3c8a552522 | ||
|
|
6a666ead39 | ||
|
|
1918c5e24a | ||
|
|
c45cc3de41 | ||
|
|
6364530b86 | ||
|
|
b757cc28b8 | ||
|
|
b8745299ba | ||
|
|
1b021c599b | ||
|
|
4c2f78a78b | ||
|
|
ea1d2c3731 | ||
|
|
a2f01ea541 | ||
|
|
1a1a7a991b | ||
|
|
e3daa4b16e | ||
|
|
c30586ccc8 | ||
|
|
c9825c5c5b | ||
|
|
ab809b0df9 | ||
|
|
5589ef7fc9 | ||
|
|
b611871940 | ||
|
|
27bc424f04 | ||
|
|
f544eceaa5 | ||
|
|
8429cec6c3 | ||
|
|
632d347d07 | ||
|
|
7a79d318a6 | ||
|
|
3273d1f935 | ||
|
|
9f01082937 | ||
|
|
05c15930c3 | ||
|
|
a6f3510ee4 | ||
|
|
10d32032e9 | ||
|
|
9e62e1e097 | ||
|
|
fed4dd4654 | ||
|
|
0f3f6d215c | ||
|
|
bd959085f2 | ||
|
|
630a852669 | ||
|
|
2a8419c7cd | ||
|
|
b43f88cece | ||
|
|
c75d3cf9ec | ||
|
|
7987455fcf | ||
|
|
694352c1df | ||
|
|
03eaaa46e0 | ||
|
|
64d1e1546a | ||
|
|
fb014d8aff | ||
|
|
1ff4e9030b | ||
|
|
4fe6b1fd0b | ||
|
|
27e8090096 | ||
|
|
e3f81b9c49 | ||
|
|
2e3350c060 | ||
|
|
5db9bd9fdd | ||
|
|
223f09dc94 | ||
|
|
01e735cc0e | ||
|
|
bce496b8d1 | ||
|
|
988e299290 | ||
|
|
cc86720936 | ||
|
|
0e8b28b958 | ||
|
|
30cfe1041a | ||
|
|
18eb7a02cc | ||
|
|
e4bb7bed98 | ||
|
|
cebf4a01a8 | ||
|
|
afbfbeaa49 | ||
|
|
339d78c4ab | ||
|
|
62f016387f | ||
|
|
9859f33914 | ||
|
|
4e29c1474e | ||
|
|
30f87a1019 | ||
|
|
9fb884e5a6 | ||
|
|
c9d6267f67 | ||
|
|
9b633824d5 | ||
|
|
573b284017 | ||
|
|
14ea15e870 | ||
|
|
f11ec2d0bd | ||
|
|
36f245e983 | ||
|
|
6e2e8a55c2 | ||
|
|
50ee218198 | ||
|
|
5b1588b077 | ||
|
|
5d6e0f5851 | ||
|
|
2ea54a2401 | ||
|
|
578cafb059 | ||
|
|
9c0002ad9a | ||
|
|
8c17a8c388 | ||
|
|
3d9ffca016 | ||
|
|
c7435c5dfa | ||
|
|
cf364206de | ||
|
|
114ce41fcc | ||
|
|
8dc95a17e6 | ||
|
|
d9a2b1aa60 | ||
|
|
e4314ddb4c | ||
|
|
44bcb3d06c | ||
|
|
e90c18603a | ||
|
|
d5e1d3ea60 | ||
|
|
97bda6d597 | ||
|
|
05ef5eabf6 | ||
|
|
6e966f8ae0 | ||
|
|
2bbb585fc7 | ||
|
|
677432f634 | ||
|
|
67e504288f | ||
|
|
e8875e0e1f | ||
|
|
d354d4aa54 | ||
|
|
d855cb1542 | ||
|
|
d1202e44eb | ||
|
|
08d5730fbe | ||
|
|
92a5781b6a | ||
|
|
9ac8e26a48 | ||
|
|
0b017ff954 | ||
|
|
a34b7c7136 | ||
|
|
be09e3e596 | ||
|
|
ebcab010bb | ||
|
|
e826f7c1ec | ||
|
|
c524e226de | ||
|
|
86a387046f | ||
|
|
75bb620cb6 | ||
|
|
0f69ca4bff | ||
|
|
3f0f942779 | ||
|
|
f738b6ac67 | ||
|
|
fc6a214197 | ||
|
|
4c1bf7dcf8 | ||
|
|
8d35711448 | ||
|
|
1c79aaff87 | ||
|
|
4ff41181dc | ||
|
|
00aa23162c | ||
|
|
1f1aa9859b | ||
|
|
80210376f3 | ||
|
|
df60c8190b | ||
|
|
2ed59f41ed | ||
|
|
ce10016408 | ||
|
|
53c86adbbe | ||
|
|
023d96bc3e | ||
|
|
3adeab87ed | ||
|
|
2d6ddf043e | ||
|
|
a0fcf59348 | ||
|
|
465f6bfe27 | ||
|
|
2ca2376d45 | ||
|
|
6120013ae2 | ||
|
|
65d9bde498 | ||
|
|
6a40d38b93 | ||
|
|
6075592f62 | ||
|
|
fe6a095175 | ||
|
|
c909ab794a | ||
|
|
3759e276b2 | ||
|
|
20517cfd4d | ||
|
|
faacd3d6a1 | ||
|
|
97362504e8 | ||
|
|
5bfa9b5734 | ||
|
|
3ed4dee00e | ||
|
|
54ee0344b8 | ||
|
|
166a285a28 | ||
|
|
69479efcf3 | ||
|
|
27541f6ec9 | ||
|
|
2e8306b341 | ||
|
|
f33a824708 | ||
|
|
c6688dc876 | ||
|
|
de1d7046ee | ||
|
|
0e9ab11213 | ||
|
|
4a216ff786 | ||
|
|
57fa9830b6 | ||
|
|
87f55992f0 | ||
|
|
d589ab4058 | ||
|
|
34415bb660 | ||
|
|
cc06fab125 | ||
|
|
c94bd2ff72 | ||
|
|
20833579e9 | ||
|
|
08ceb5eba0 | ||
|
|
ad58e0008b | ||
|
|
57a556a495 | ||
|
|
ccdea1bf57 | ||
|
|
fdc71d2b18 | ||
|
|
ea7fab6efe | ||
|
|
1869e81883 | ||
|
|
fa4078f38c | ||
|
|
e145793d2f | ||
|
|
36cd7a625f | ||
|
|
3640bedeee | ||
|
|
2901a33698 | ||
|
|
4bcfe63c57 | ||
|
|
02ab113762 | ||
|
|
16be0ee344 | ||
|
|
78302be193 | ||
|
|
c6dc9a20e7 | ||
|
|
756a821f41 | ||
|
|
8a0163f14a | ||
|
|
40540cb38a | ||
|
|
fb743a0532 | ||
|
|
168e3544d0 | ||
|
|
979acf774a | ||
|
|
b80d9498ef | ||
|
|
6965b0af19 | ||
|
|
99230e3ff1 | ||
|
|
739d24efb4 | ||
|
|
f2a583fd49 | ||
|
|
488e4e2b86 | ||
|
|
7e8b6de186 | ||
|
|
6c8e770a61 | ||
|
|
e16180c2a5 | ||
|
|
8060307c62 | ||
|
|
7ab3373335 | ||
|
|
0b41fbc858 | ||
|
|
2586404339 | ||
|
|
eb909e1ae7 | ||
|
|
cb3281dee8 | ||
|
|
9dbbd4c9bc | ||
|
|
93d2eb5e1a | ||
|
|
faeead242c | ||
|
|
4e2e262f6a | ||
|
|
f1327ace32 | ||
|
|
43d5bd3e2d | ||
|
|
be564921d8 | ||
|
|
ef9bf72b52 | ||
|
|
e0e2b40682 | ||
|
|
f4e01e5756 | ||
|
|
501560940b | ||
|
|
a80df427e7 | ||
|
|
3cbad7350b | ||
|
|
58bcc3640c | ||
|
|
04ff16ddb2 | ||
|
|
c5c2a40ef5 | ||
|
|
b3232dc26f | ||
|
|
26be7fbd46 | ||
|
|
0e70e63e0a | ||
|
|
1ef1a140b7 | ||
|
|
a81a071d2d | ||
|
|
7b94a47350 | ||
|
|
bded77a22b | ||
|
|
de14886376 | ||
|
|
9425b77030 | ||
|
|
a52156627d | ||
|
|
ce87a1c4db | ||
|
|
4fb4bde34b | ||
|
|
1acd4a7ac8 | ||
|
|
2d12a3cf3d | ||
|
|
16f5889a15 | ||
|
|
c51a28f206 | ||
|
|
58147a24cf | ||
|
|
cf95742433 | ||
|
|
d4a40499ac | ||
|
|
ecd6c7a0ae | ||
|
|
4cc838f1ff | ||
|
|
8df270cc4b | ||
|
|
1d7a1f6d53 | ||
|
|
ef1d7f92f7 | ||
|
|
2e925b530b | ||
|
|
39f9d5a116 | ||
|
|
8482481478 | ||
|
|
61f4db61ec | ||
|
|
6d73fba14c | ||
|
|
955d13ef0a | ||
|
|
2d907c02f0 | ||
|
|
160e5c480a | ||
|
|
32a81517d6 | ||
|
|
e7b33347e7 | ||
|
|
d8ac731dd2 | ||
|
|
05e2472d93 | ||
|
|
4f44407187 | ||
|
|
2c69d3b726 | ||
|
|
4eedef048d | ||
|
|
adaa8cb806 | ||
|
|
6a19330e55 | ||
|
|
fb8d9bd5dc | ||
|
|
ea8bc5b56d | ||
|
|
d4b3834bce | ||
|
|
7f8d4ac3d2 | ||
|
|
de63e93024 | ||
|
|
977f5125e6 | ||
|
|
7f9cc73485 | ||
|
|
e08871a77e | ||
|
|
98c3d6897d | ||
|
|
98ca4f1a70 | ||
|
|
b538baa8d8 | ||
|
|
ae5c21ef17 | ||
|
|
24ccd27d79 | ||
|
|
15c79df378 | ||
|
|
fd983955b4 | ||
|
|
8f56e98397 | ||
|
|
842e4df223 | ||
|
|
e0be6d45c5 | ||
|
|
0c0de906c2 | ||
|
|
fdf0652e37 | ||
|
|
5981e9537b | ||
|
|
4a2266b295 | ||
|
|
20d3c301e7 | ||
|
|
7cbd61dae2 | ||
|
|
e8a47e322d | ||
|
|
b5ade0d9d1 | ||
|
|
a1c5e7fed2 | ||
|
|
a76067296e | ||
|
|
a8f30212d4 | ||
|
|
ad5115ac3c | ||
|
|
205bfcdd7b | ||
|
|
6034eaffc8 | ||
|
|
593839a374 | ||
|
|
8490c69692 | ||
|
|
a8e90069d6 | ||
|
|
e286bd1422 | ||
|
|
6437723772 | ||
|
|
1532c5638f | ||
|
|
ae537b6764 | ||
|
|
1ced5e34b6 | ||
|
|
3badb12ea3 | ||
|
|
24170f00cc | ||
|
|
b3424f73a8 | ||
|
|
f3e20e746e | ||
|
|
5c1bd85204 | ||
|
|
3c6c65e25e | ||
|
|
ee9888d9b6 | ||
|
|
b02751344a | ||
|
|
0cb9747547 | ||
|
|
145d753b2c | ||
|
|
8f95e95b21 | ||
|
|
e482135ded | ||
|
|
09d252d43b | ||
|
|
dad9c82166 | ||
|
|
6ce83c5ec2 | ||
|
|
ba8decca3f | ||
|
|
427d9e2645 | ||
|
|
84453912b1 | ||
|
|
ab927615d8 | ||
|
|
bb303d0063 | ||
|
|
eff31f07d9 | ||
|
|
2ce0024a10 | ||
|
|
bd07a990fb | ||
|
|
f012e4d968 | ||
|
|
192bfc70b0 | ||
|
|
f2aefeebb3 | ||
|
|
a526619f4b | ||
|
|
94e8f3ac4c | ||
|
|
932d5bee47 | ||
|
|
1cd7dd622f | ||
|
|
10ac65ffb1 | ||
|
|
4406d4bbaa | ||
|
|
c2a57f704b | ||
|
|
fdbd119445 | ||
|
|
80f7b1f96e | ||
|
|
1c5899731c | ||
|
|
d831395013 | ||
|
|
119832a55b | ||
|
|
d8f9e7360f | ||
|
|
3b1ad0be27 | ||
|
|
05434a994f | ||
|
|
f45099b398 | ||
|
|
7573f370b3 | ||
|
|
2eebe67005 |
1
.gitignore
vendored
@@ -2,3 +2,4 @@
|
|||||||
*.user.*
|
*.user.*
|
||||||
translations/*.qm
|
translations/*.qm
|
||||||
build
|
build
|
||||||
|
version.js
|
||||||
|
|||||||
4
.gitmodules
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[submodule "monero"]
|
||||||
|
path = monero
|
||||||
|
url = https://github.com/monero-project/monero
|
||||||
|
ignore = all
|
||||||
@@ -90,7 +90,6 @@ Rectangle {
|
|||||||
height: 20
|
height: 20
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.letterSpacing: -1
|
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
verticalAlignment: Text.AlignBottom
|
verticalAlignment: Text.AlignBottom
|
||||||
@@ -104,7 +103,6 @@ Rectangle {
|
|||||||
height: 20
|
height: 20
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.letterSpacing: -1
|
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
verticalAlignment: Text.AlignBottom
|
verticalAlignment: Text.AlignBottom
|
||||||
@@ -128,7 +126,6 @@ Rectangle {
|
|||||||
height: 20
|
height: 20
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.letterSpacing: -1
|
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
verticalAlignment: Text.AlignBottom
|
verticalAlignment: Text.AlignBottom
|
||||||
@@ -142,7 +139,6 @@ Rectangle {
|
|||||||
height: 20
|
height: 20
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
font.letterSpacing: -1
|
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
verticalAlignment: Text.AlignBottom
|
verticalAlignment: Text.AlignBottom
|
||||||
|
|||||||
2
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2014-2015, The Monero Project
|
Copyright (c) 2014-2017, The Monero Project
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|||||||
137
LeftPanel.qml
@@ -35,9 +35,11 @@ Rectangle {
|
|||||||
id: panel
|
id: panel
|
||||||
|
|
||||||
property alias unlockedBalanceText: unlockedBalanceText.text
|
property alias unlockedBalanceText: unlockedBalanceText.text
|
||||||
|
property alias balanceLabelText: balanceLabel.text
|
||||||
property alias balanceText: balanceText.text
|
property alias balanceText: balanceText.text
|
||||||
property alias networkStatus : networkStatus
|
property alias networkStatus : networkStatus
|
||||||
property alias progressBar : progressBar
|
property alias progressBar : progressBar
|
||||||
|
property alias minutesToUnlockTxt: unlockedBalanceLabel.text
|
||||||
|
|
||||||
signal dashboardClicked()
|
signal dashboardClicked()
|
||||||
signal historyClicked()
|
signal historyClicked()
|
||||||
@@ -60,20 +62,22 @@ Rectangle {
|
|||||||
else if(pos === "TxKey") menuColumn.previousButton = txkeyButton
|
else if(pos === "TxKey") menuColumn.previousButton = txkeyButton
|
||||||
else if(pos === "Sign") menuColumn.previousButton = signButton
|
else if(pos === "Sign") menuColumn.previousButton = signButton
|
||||||
else if(pos === "Settings") menuColumn.previousButton = settingsButton
|
else if(pos === "Settings") menuColumn.previousButton = settingsButton
|
||||||
|
else if(pos === "Advanced") menuColumn.previousButton = advancedButton
|
||||||
|
|
||||||
menuColumn.previousButton.checked = true
|
menuColumn.previousButton.checked = true
|
||||||
}
|
}
|
||||||
|
|
||||||
width: 260
|
width: (isMobile)? appWindow.width : 260
|
||||||
color: "#FFFFFF"
|
color: "#FFFFFF"
|
||||||
|
|
||||||
// Item with monero logo
|
// Item with monero logo
|
||||||
Item {
|
Item {
|
||||||
|
visible: !isMobile
|
||||||
id: logoItem
|
id: logoItem
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: (persistentSettings.customDecorations)? 66 : 36
|
||||||
height: logo.implicitHeight
|
height: logo.implicitHeight
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
@@ -83,6 +87,18 @@ Rectangle {
|
|||||||
source: "images/moneroLogo.png"
|
source: "images/moneroLogo.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: testnetLabel
|
||||||
|
visible: persistentSettings.testnet
|
||||||
|
text: qsTr("Testnet") + translationManager.emptyString
|
||||||
|
anchors.top: logo.bottom
|
||||||
|
anchors.topMargin: 5
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 50
|
||||||
|
font.bold: true
|
||||||
|
color: "red"
|
||||||
|
}
|
||||||
|
|
||||||
/* Disable twitter/news panel
|
/* Disable twitter/news panel
|
||||||
Image {
|
Image {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -100,22 +116,26 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
visible: !isMobile
|
||||||
id: column1
|
id: column1
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: logoItem.bottom
|
anchors.top: logoItem.bottom
|
||||||
anchors.topMargin: 30
|
anchors.topMargin: 26
|
||||||
spacing: 5
|
spacing: 5
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
visible: !isMobile
|
||||||
|
id: balanceLabel
|
||||||
text: qsTr("Balance") + translationManager.emptyString
|
text: qsTr("Balance") + translationManager.emptyString
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 50
|
anchors.leftMargin: 50
|
||||||
tipText: qsTr("Test tip 1<br/><br/>line 2") + translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
visible: !isMobile
|
||||||
Item {
|
Item {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
height: 26
|
height: 26
|
||||||
@@ -128,12 +148,21 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
visible: !isMobile
|
||||||
id: balanceText
|
id: balanceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 26
|
|
||||||
color: "#000000"
|
color: "#000000"
|
||||||
text: "N/A"
|
text: "N/A"
|
||||||
|
// dynamically adjust text size
|
||||||
|
font.pixelSize: {
|
||||||
|
var digits = text.split('.')[0].length
|
||||||
|
var defaultSize = 25;
|
||||||
|
if(digits > 2) {
|
||||||
|
return defaultSize - 1.1*digits
|
||||||
|
}
|
||||||
|
return defaultSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,10 +173,10 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
id: unlockedBalanceLabel
|
||||||
text: qsTr("Unlocked balance") + translationManager.emptyString
|
text: qsTr("Unlocked balance") + translationManager.emptyString
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 50
|
anchors.leftMargin: 50
|
||||||
tipText: qsTr("Test tip 2<br/><br/>line 2") + translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
@@ -155,12 +184,21 @@ Rectangle {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 50
|
anchors.leftMargin: 50
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 18
|
|
||||||
color: "#000000"
|
color: "#000000"
|
||||||
text: "N/A"
|
text: "N/A"
|
||||||
|
// dynamically adjust text size
|
||||||
|
font.pixelSize: {
|
||||||
|
var digits = text.split('.')[0].length
|
||||||
|
var defaultSize = 18;
|
||||||
|
if(digits > 3) {
|
||||||
|
return defaultSize - 0.6*digits
|
||||||
|
}
|
||||||
|
return defaultSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -177,16 +215,26 @@ Rectangle {
|
|||||||
color: "#DBDBDB"
|
color: "#DBDBDB"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: menuRect
|
id: menuRect
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.top: column1.bottom
|
anchors.top: (isMobile)? parent.top : column1.bottom
|
||||||
anchors.topMargin: 50
|
anchors.topMargin: (isMobile)? 0 : 25
|
||||||
color: "#1C1C1C"
|
color: "#1C1C1C"
|
||||||
|
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
contentHeight: 500
|
||||||
|
anchors.fill: parent
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
|
||||||
id: menuColumn
|
id: menuColumn
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -239,6 +287,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
visible: transferButton.present
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
@@ -264,6 +313,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
visible: addressBookButton.present
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
@@ -286,6 +336,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
visible: receiveButton.present
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
@@ -309,6 +360,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
visible: historyButton.present
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
@@ -316,7 +368,29 @@ Rectangle {
|
|||||||
height: 1
|
height: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/* // ------------- Mining tab ---------------
|
// ------------- Advanced tab ---------------
|
||||||
|
MenuButton {
|
||||||
|
id: advancedButton
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
text: qsTr("Advanced") + translationManager.emptyString
|
||||||
|
symbol: qsTr("D") + translationManager.emptyString
|
||||||
|
dotColor: "#FFD781"
|
||||||
|
onClicked: {
|
||||||
|
parent.previousButton.checked = false
|
||||||
|
parent.previousButton = advancedButton
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
visible: advancedButton.present
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.leftMargin: 16
|
||||||
|
color: "#505050"
|
||||||
|
height: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------- Mining tab ---------------
|
||||||
MenuButton {
|
MenuButton {
|
||||||
id: miningButton
|
id: miningButton
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -324,6 +398,7 @@ Rectangle {
|
|||||||
text: qsTr("Mining") + translationManager.emptyString
|
text: qsTr("Mining") + translationManager.emptyString
|
||||||
symbol: qsTr("M") + translationManager.emptyString
|
symbol: qsTr("M") + translationManager.emptyString
|
||||||
dotColor: "#FFD781"
|
dotColor: "#FFD781"
|
||||||
|
under: advancedButton
|
||||||
onClicked: {
|
onClicked: {
|
||||||
parent.previousButton.checked = false
|
parent.previousButton.checked = false
|
||||||
parent.previousButton = miningButton
|
parent.previousButton = miningButton
|
||||||
@@ -332,34 +407,13 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
visible: miningButton.present
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
color: miningButton.checked || settingsButton.checked ? "#1C1C1C" : "#505050"
|
color: miningButton.checked || settingsButton.checked ? "#1C1C1C" : "#505050"
|
||||||
height: 1
|
height: 1
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
// ------------- Advanced tab ---------------
|
|
||||||
MenuButton {
|
|
||||||
id: advancedButton
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
text: qsTr("Advanced") + translationManager.emptyString
|
|
||||||
symbol: qsTr("A") + translationManager.emptyString
|
|
||||||
dotColor: "#AAFFBB"
|
|
||||||
onClicked: {
|
|
||||||
parent.previousButton.checked = false
|
|
||||||
parent.previousButton = advancedButton
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.leftMargin: 16
|
|
||||||
color: "#505050"
|
|
||||||
height: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------- TxKey tab ---------------
|
// ------------- TxKey tab ---------------
|
||||||
MenuButton {
|
MenuButton {
|
||||||
id: txkeyButton
|
id: txkeyButton
|
||||||
@@ -367,7 +421,7 @@ Rectangle {
|
|||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
text: qsTr("Check payment") + translationManager.emptyString
|
text: qsTr("Check payment") + translationManager.emptyString
|
||||||
symbol: qsTr("K") + translationManager.emptyString
|
symbol: qsTr("K") + translationManager.emptyString
|
||||||
dotColor: "#AAFFBB"
|
dotColor: "#FFD781"
|
||||||
under: advancedButton
|
under: advancedButton
|
||||||
onClicked: {
|
onClicked: {
|
||||||
parent.previousButton.checked = false
|
parent.previousButton.checked = false
|
||||||
@@ -376,6 +430,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
visible: txkeyButton.present
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
@@ -390,7 +445,7 @@ Rectangle {
|
|||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
text: qsTr("Sign/verify") + translationManager.emptyString
|
text: qsTr("Sign/verify") + translationManager.emptyString
|
||||||
symbol: qsTr("I") + translationManager.emptyString
|
symbol: qsTr("I") + translationManager.emptyString
|
||||||
dotColor: "#AAFFBB"
|
dotColor: "#FFD781"
|
||||||
under: advancedButton
|
under: advancedButton
|
||||||
onClicked: {
|
onClicked: {
|
||||||
parent.previousButton.checked = false
|
parent.previousButton.checked = false
|
||||||
@@ -399,6 +454,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
visible: signButton.present
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
@@ -419,6 +475,16 @@ Rectangle {
|
|||||||
panel.settingsClicked()
|
panel.settingsClicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Rectangle {
|
||||||
|
visible: settingsButton.present
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.leftMargin: 16
|
||||||
|
color: "#505050"
|
||||||
|
height: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,6 +503,9 @@ Rectangle {
|
|||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// indicate disabled state
|
// indicate disabled state
|
||||||
// Desaturate {
|
// Desaturate {
|
||||||
// anchors.fill: parent
|
// anchors.fill: parent
|
||||||
|
|||||||
14
MainApp.cpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#include "MainApp.h"
|
||||||
|
#include <QCloseEvent>
|
||||||
|
|
||||||
|
bool MainApp::event (QEvent *event)
|
||||||
|
{
|
||||||
|
// Catch application exit event and signal to qml app to handle exit
|
||||||
|
if(event->type() == QEvent::Close) {
|
||||||
|
event->ignore();
|
||||||
|
emit closing();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
18
MainApp.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef MAINAPP_H
|
||||||
|
#define MAINAPP_H
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
class MainApp : public QApplication
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
MainApp(int &argc, char** argv) : QApplication(argc, argv) {};
|
||||||
|
private:
|
||||||
|
bool event(QEvent *e);
|
||||||
|
signals:
|
||||||
|
void closing();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAINAPP_H
|
||||||
|
|
||||||
|
|
||||||
181
MiddlePanel.qml
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
import QtQml 2.0
|
import QtQml 2.0
|
||||||
import QtQuick 2.2
|
import QtQuick 2.2
|
||||||
|
//import QtQuick.Controls 2.0
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
@@ -41,9 +42,13 @@ Rectangle {
|
|||||||
|
|
||||||
property Item currentView
|
property Item currentView
|
||||||
property Item previousView
|
property Item previousView
|
||||||
property bool basicMode : false
|
property bool basicMode : isMobile
|
||||||
|
property string balanceLabelText: qsTr("Balance") + translationManager.emptyString
|
||||||
property string balanceText
|
property string balanceText
|
||||||
|
property string unlockedBalanceLabelText: qsTr("Unlocked Balance") + translationManager.emptyString
|
||||||
property string unlockedBalanceText
|
property string unlockedBalanceText
|
||||||
|
property int minHeight: (appWindow.height > 800) ? appWindow.height : 800
|
||||||
|
// property int headerHeight: header.height
|
||||||
|
|
||||||
property Transfer transferView: Transfer { }
|
property Transfer transferView: Transfer { }
|
||||||
property Receive receiveView: Receive { }
|
property Receive receiveView: Receive { }
|
||||||
@@ -51,6 +56,7 @@ Rectangle {
|
|||||||
property History historyView: History { }
|
property History historyView: History { }
|
||||||
property Sign signView: Sign { }
|
property Sign signView: Sign { }
|
||||||
property Settings settingsView: Settings { }
|
property Settings settingsView: Settings { }
|
||||||
|
property Mining miningView: Mining { }
|
||||||
property AddressBook addressBookView: AddressBook { }
|
property AddressBook addressBookView: AddressBook { }
|
||||||
|
|
||||||
|
|
||||||
@@ -70,7 +76,6 @@ Rectangle {
|
|||||||
previousView = currentView
|
previousView = currentView
|
||||||
if (currentView) {
|
if (currentView) {
|
||||||
stackView.replace(currentView)
|
stackView.replace(currentView)
|
||||||
|
|
||||||
// Component.onCompleted is called before wallet is initilized
|
// Component.onCompleted is called before wallet is initilized
|
||||||
if (typeof currentView.onPageCompleted === "function") {
|
if (typeof currentView.onPageCompleted === "function") {
|
||||||
currentView.onPageCompleted();
|
currentView.onPageCompleted();
|
||||||
@@ -123,27 +128,35 @@ Rectangle {
|
|||||||
name: "History"
|
name: "History"
|
||||||
PropertyChanges { target: root; currentView: historyView }
|
PropertyChanges { target: root; currentView: historyView }
|
||||||
PropertyChanges { target: historyView; model: appWindow.currentWallet ? appWindow.currentWallet.historyModel : null }
|
PropertyChanges { target: historyView; model: appWindow.currentWallet ? appWindow.currentWallet.historyModel : null }
|
||||||
|
PropertyChanges { target: mainFlickable; contentHeight: minHeight }
|
||||||
}, State {
|
}, State {
|
||||||
name: "Transfer"
|
name: "Transfer"
|
||||||
PropertyChanges { target: root; currentView: transferView }
|
PropertyChanges { target: root; currentView: transferView }
|
||||||
|
PropertyChanges { target: mainFlickable; contentHeight: 1000 }
|
||||||
}, State {
|
}, State {
|
||||||
name: "Receive"
|
name: "Receive"
|
||||||
PropertyChanges { target: root; currentView: receiveView }
|
PropertyChanges { target: root; currentView: receiveView }
|
||||||
|
PropertyChanges { target: mainFlickable; contentHeight: minHeight }
|
||||||
}, State {
|
}, State {
|
||||||
name: "TxKey"
|
name: "TxKey"
|
||||||
PropertyChanges { target: root; currentView: txkeyView }
|
PropertyChanges { target: root; currentView: txkeyView }
|
||||||
|
PropertyChanges { target: mainFlickable; contentHeight: minHeight }
|
||||||
}, State {
|
}, State {
|
||||||
name: "AddressBook"
|
name: "AddressBook"
|
||||||
PropertyChanges { target: root; currentView: addressBookView }
|
PropertyChanges { target: root; currentView: addressBookView }
|
||||||
|
PropertyChanges { target: mainFlickable; contentHeight: minHeight }
|
||||||
}, State {
|
}, State {
|
||||||
name: "Sign"
|
name: "Sign"
|
||||||
PropertyChanges { target: root; currentView: signView }
|
PropertyChanges { target: root; currentView: signView }
|
||||||
|
PropertyChanges { target: mainFlickable; contentHeight: minHeight }
|
||||||
}, State {
|
}, State {
|
||||||
name: "Settings"
|
name: "Settings"
|
||||||
PropertyChanges { target: root; currentView: settingsView }
|
PropertyChanges { target: root; currentView: settingsView }
|
||||||
|
PropertyChanges { target: mainFlickable; contentHeight: 1200 }
|
||||||
}, State {
|
}, State {
|
||||||
name: "Mining"
|
name: "Mining"
|
||||||
PropertyChanges { /*TODO*/ }
|
PropertyChanges { target: root; currentView: miningView }
|
||||||
|
PropertyChanges { target: mainFlickable; contentHeight: minHeight }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -169,139 +182,47 @@ Rectangle {
|
|||||||
anchors.topMargin: appWindow.persistentSettings.customDecorations ? 30 : 0
|
anchors.topMargin: appWindow.persistentSettings.customDecorations ? 30 : 0
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
|
Flickable {
|
||||||
// BasicPanel header
|
id: mainFlickable
|
||||||
Rectangle {
|
|
||||||
id: header
|
|
||||||
anchors.leftMargin: 1
|
|
||||||
anchors.rightMargin: 1
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 64
|
|
||||||
color: "#FFFFFF"
|
|
||||||
visible: basicMode
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: logo
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: -5
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: appWindow.persistentSettings.customDecorations ? 20 : 40
|
|
||||||
source: "images/moneroLogo2.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
Grid {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.topMargin: 10
|
|
||||||
width: 256
|
|
||||||
columns: 3
|
|
||||||
|
|
||||||
Text {
|
|
||||||
|
|
||||||
width: 116
|
|
||||||
height: 20
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 12
|
|
||||||
font.letterSpacing: -1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignBottom
|
|
||||||
color: "#535353"
|
|
||||||
text: qsTr("Balance:")
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: balanceText
|
|
||||||
width: 110
|
|
||||||
height: 20
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 18
|
|
||||||
font.letterSpacing: -1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignBottom
|
|
||||||
color: "#000000"
|
|
||||||
text: root.balanceText
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
height: 20
|
|
||||||
width: 20
|
|
||||||
|
|
||||||
Image {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.left: parent.left
|
|
||||||
source: "images/lockIcon.png"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
width: 116
|
|
||||||
height: 20
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 12
|
|
||||||
font.letterSpacing: -1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignBottom
|
|
||||||
color: "#535353"
|
|
||||||
text: qsTr("Unlocked Balance:")
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: availableBalanceText
|
|
||||||
width: 110
|
|
||||||
height: 20
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 14
|
|
||||||
font.letterSpacing: -1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignBottom
|
|
||||||
color: "#000000"
|
|
||||||
text: root.unlockedBalanceText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
height: 1
|
|
||||||
color: "#DBDBDB"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Views container
|
|
||||||
StackView {
|
|
||||||
id: stackView
|
|
||||||
initialItem: transferView
|
|
||||||
anchors.topMargin: 30
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
anchors.margins: 4
|
clip: true
|
||||||
clip: true // otherwise animation will affect left panel
|
// Disabled scrollbars, gives crash on startup on windows
|
||||||
|
// ScrollIndicator.vertical: ScrollIndicator { }
|
||||||
|
// ScrollBar.vertical: ScrollBar { } // uncomment to test
|
||||||
|
|
||||||
delegate: StackViewDelegate {
|
// Views container
|
||||||
pushTransition: StackViewTransition {
|
StackView {
|
||||||
PropertyAnimation {
|
id: stackView
|
||||||
target: enterItem
|
initialItem: transferView
|
||||||
property: "x"
|
// anchors.topMargin: 30
|
||||||
from: 0 - target.width
|
// Layout.fillWidth: true
|
||||||
to: 0
|
// Layout.fillHeight: true
|
||||||
duration: 300
|
anchors.fill:parent
|
||||||
}
|
// anchors.margins: 4
|
||||||
PropertyAnimation {
|
clip: true // otherwise animation will affect left panel
|
||||||
target: exitItem
|
|
||||||
property: "x"
|
delegate: StackViewDelegate {
|
||||||
from: 0
|
pushTransition: StackViewTransition {
|
||||||
to: target.width
|
PropertyAnimation {
|
||||||
duration: 300
|
target: enterItem
|
||||||
|
property: "x"
|
||||||
|
from: 0 - target.width
|
||||||
|
to: 0
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
|
PropertyAnimation {
|
||||||
|
target: exitItem
|
||||||
|
property: "x"
|
||||||
|
from: 0
|
||||||
|
to: target.width
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}// flickable
|
||||||
}
|
}
|
||||||
// border
|
// border
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|||||||
154
README.md
@@ -1,4 +1,6 @@
|
|||||||
Copyright (c) 2014-2016, The Monero Project
|
# Monero GUI
|
||||||
|
|
||||||
|
Copyright (c) 2014-2017, The Monero Project
|
||||||
|
|
||||||
## Development Resources
|
## Development Resources
|
||||||
|
|
||||||
@@ -8,6 +10,11 @@ Copyright (c) 2014-2016, The Monero Project
|
|||||||
- Github: [https://github.com/monero-project/monero-core](https://github.com/monero-project/monero-core)
|
- Github: [https://github.com/monero-project/monero-core](https://github.com/monero-project/monero-core)
|
||||||
- IRC: [#monero-dev on Freenode](irc://chat.freenode.net/#monero-dev)
|
- IRC: [#monero-dev on Freenode](irc://chat.freenode.net/#monero-dev)
|
||||||
|
|
||||||
|
## Vulnerability Response
|
||||||
|
|
||||||
|
- Our [Vulnerability Response Process](https://github.com/monero-project/meta/blob/master/VULNERABILITY_RESPONSE_PROCESS.md) encourages responsible disclosure
|
||||||
|
- We are also available via [HackerOne](https://hackerone.com/monero)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
Monero is a private, secure, untraceable, decentralised digital currency. You are your bank, you control your funds, and nobody can trace your transfers unless you allow them to do so.
|
Monero is a private, secure, untraceable, decentralised digital currency. You are your bank, you control your funds, and nobody can trace your transfers unless you allow them to do so.
|
||||||
@@ -54,7 +61,8 @@ See [LICENSE](LICENSE).
|
|||||||
|
|
||||||
Packages are available for
|
Packages are available for
|
||||||
|
|
||||||
* Arch Linux via AUR: [monero-core-git](https://aur.archlinux.org/packages/monero-core-git/)
|
* Arch Linux via AUR: [monero-wallet-qt](https://aur.archlinux.org/packages/monero-wallet-qt/)
|
||||||
|
* Void Linux: xbps-install -S monero-core
|
||||||
|
|
||||||
Packaging for your favorite distribution would be a welcome contribution!
|
Packaging for your favorite distribution would be a welcome contribution!
|
||||||
|
|
||||||
@@ -62,52 +70,67 @@ Packaging for your favorite distribution would be a welcome contribution!
|
|||||||
|
|
||||||
### On Linux:
|
### On Linux:
|
||||||
|
|
||||||
(Tested on Ubuntu 16.04 i386 and Linux Mint 18 "Sarah" - Cinnamon (64-bit))
|
(Tested on Ubuntu 16.04 x86, 16.10 x64, Gentoo x64 and Linux Mint 18 "Sarah" - Cinnamon x64)
|
||||||
|
|
||||||
1. Install Monero dependencies.
|
1. Install Monero dependencies
|
||||||
|
|
||||||
|
- For Ubuntu and Mint
|
||||||
|
|
||||||
`sudo apt install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev`
|
`sudo apt install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev`
|
||||||
|
|
||||||
2. Grab an up-to-date copy of the monero-core repository.
|
- For Gentoo
|
||||||
|
|
||||||
|
`sudo emerge app-arch/xz-utils app-doc/doxygen dev-cpp/gtest dev-libs/boost dev-libs/expat dev-libs/openssl dev-util/cmake media-gfx/graphviz net-dns/unbound net-libs/ldns net-libs/miniupnpc sys-libs/libunwind`
|
||||||
|
|
||||||
|
2. Grab an up-to-date copy of the monero-core repository
|
||||||
|
|
||||||
`git clone https://github.com/monero-project/monero-core.git`
|
`git clone https://github.com/monero-project/monero-core.git`
|
||||||
|
|
||||||
3. Go into the repository.
|
3. Go into the repository
|
||||||
|
|
||||||
`cd monero-core`
|
`cd monero-core`
|
||||||
|
|
||||||
4. Use the script to compile the Monero libs necessary to run the GUI.
|
4. Install the GUI dependencies
|
||||||
|
|
||||||
`./get_libwallet_api.sh`
|
- For Ubuntu 16.04 x86
|
||||||
|
|
||||||
|
|
||||||
5. Install the GUI dependencies.
|
|
||||||
|
|
||||||
- For Ubuntu 16.04 i386
|
|
||||||
|
|
||||||
`sudo apt-get install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtquick-xmllistmodel qttools5-dev-tools qml-module-qtquick-dialogs`
|
`sudo apt-get install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtquick-xmllistmodel qttools5-dev-tools qml-module-qtquick-dialogs`
|
||||||
|
|
||||||
- For Ubuntu 16.04 x64
|
- For Ubuntu 16.04+ x64
|
||||||
|
|
||||||
`sudo apt-get install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtquick-xmllistmodel qttools5-dev-tools qml-module-qtquick-dialogs qml-module-qt-labs-settings libqt5qml-graphicaleffects`
|
`sudo apt-get install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtquick-xmllistmodel qttools5-dev-tools qml-module-qtquick-dialogs qml-module-qt-labs-settings libqt5qml-graphicaleffects`
|
||||||
|
|
||||||
- For Linux Mint 18 "Sarah" - Cinnamon (64-bit)
|
- For Linux Mint 18 "Sarah" - Cinnamon x64
|
||||||
|
|
||||||
`sudo apt install qml-module-qt-labs-settings qml-module-qtgraphicaleffects`
|
`sudo apt install qml-module-qt-labs-settings qml-module-qtgraphicaleffects`
|
||||||
|
|
||||||
6. Build the GUI.
|
- For Gentoo
|
||||||
|
|
||||||
`qmake`
|
`sudo emerge dev-qt/qtcore:5 dev-qt/qtdeclarative:5 dev-qt/qtquickcontrols:5 dev-qt/qtquickcontrols2:5 dev-qt/qtgraphicaleffects:5`
|
||||||
|
|
||||||
`make`
|
- Optional : To build the flag `WITH_SCANNER`
|
||||||
|
|
||||||
7. Before running the GUI, it's recommended that you have the Monero daemon running in the background.
|
- For Ubuntu and Mint
|
||||||
|
|
||||||
`./monerod`
|
`sudo apt install qtmultimedia5-dev qml-module-qtmultimedia libzbar-dev`
|
||||||
|
|
||||||
8. Run the GUI client.
|
- For Gentoo
|
||||||
|
|
||||||
`./release/bin/monero-core`
|
The *qml* USE flag must be enabled.
|
||||||
|
|
||||||
|
`emerge dev-qt/qtmultimedia:5 media-gfx/zbar`
|
||||||
|
|
||||||
|
5. Build the GUI
|
||||||
|
|
||||||
|
- For Ubuntu and Mint
|
||||||
|
|
||||||
|
`./build.sh`
|
||||||
|
|
||||||
|
- For Gentoo
|
||||||
|
|
||||||
|
`QT_SELECT=5 ./build.sh`
|
||||||
|
|
||||||
|
The executable can be found in the build/release/bin folder.
|
||||||
|
|
||||||
### On OS X:
|
### On OS X:
|
||||||
|
|
||||||
@@ -115,34 +138,35 @@ Packaging for your favorite distribution would be a welcome contribution!
|
|||||||
2. Install [homebrew](http://brew.sh/)
|
2. Install [homebrew](http://brew.sh/)
|
||||||
3. Install [monero](https://github.com/monero-project/monero) dependencies:
|
3. Install [monero](https://github.com/monero-project/monero) dependencies:
|
||||||
|
|
||||||
`brew install boost --c++11`
|
`brew install boost --c++11`
|
||||||
|
|
||||||
`brew install openssl` - to install openssl headers
|
`brew install openssl` - to install openssl headers
|
||||||
|
|
||||||
`brew install pkgconfig`
|
`brew install pkgconfig`
|
||||||
|
|
||||||
`brew install cmake`
|
`brew install cmake`
|
||||||
|
|
||||||
4. Install latest Qt using official installer from [qt.io](https://www.qt.io/download-open-source/) (homebrew version might be outdated).
|
`brew install qt5` (or download QT 5.8+ from [qt.io](https://www.qt.io/download-open-source/))
|
||||||
5. Add Qt bin dir to your path:
|
|
||||||
|
|
||||||
`export PATH=$PATH:$HOME/Qt/5.7/clang_64/bin`
|
If you have an older version of Qt installed via homebrew, you can force it to use 5.x like so:
|
||||||
|
|
||||||
where ```Qt``` is the folder you selected to install Qt.
|
`brew link --force --overwrite qt5`
|
||||||
|
|
||||||
6. Grab an up-to-date copy of the monero-core repository.
|
5. Add the Qt bin directory to your path
|
||||||
|
|
||||||
`git clone https://github.com/monero-project/monero-core.git`
|
Example: `export PATH=$PATH:$HOME/Qt/5.8/clang_64/bin`
|
||||||
|
|
||||||
7. Go into the repository.
|
This is the directory where Qt 5.x is installed on **your** system
|
||||||
|
|
||||||
`cd monero-core`
|
6. Grab an up-to-date copy of the monero-core repository
|
||||||
|
|
||||||
8. Build libwallet
|
`git clone https://github.com/monero-project/monero-core.git`
|
||||||
|
|
||||||
`./get_libwallet_api.sh`
|
7. Go into the repository
|
||||||
|
|
||||||
9. Start the build:
|
`cd monero-core`
|
||||||
|
|
||||||
|
8. Start the build
|
||||||
|
|
||||||
`./build.sh`
|
`./build.sh`
|
||||||
|
|
||||||
@@ -150,7 +174,7 @@ The executable can be found in the `build/release/bin` folder.
|
|||||||
|
|
||||||
**Note:** Workaround for "ERROR: Xcode not set up properly"
|
**Note:** Workaround for "ERROR: Xcode not set up properly"
|
||||||
|
|
||||||
Edit `$HOME/Qt/5.7/clang_64/mkspecs/features/mac/default_pre.prf`
|
Edit `$HOME/Qt/5.8/clang_64/mkspecs/features/mac/default_pre.prf`
|
||||||
|
|
||||||
replace
|
replace
|
||||||
`isEmpty($$list($$system("/usr/bin/xcrun -find xcrun 2>/dev/null")))`
|
`isEmpty($$list($$system("/usr/bin/xcrun -find xcrun 2>/dev/null")))`
|
||||||
@@ -164,50 +188,56 @@ More info: http://stackoverflow.com/a/35098040/1683164
|
|||||||
### On Windows:
|
### On Windows:
|
||||||
|
|
||||||
1. Install [msys2](http://msys2.github.io/), follow the instructions on that page on how to update packages to the latest versions
|
1. Install [msys2](http://msys2.github.io/), follow the instructions on that page on how to update packages to the latest versions
|
||||||
2. Install monero dependencies as described in [monero documentation](https://github.com/monero-project/monero) into msys2 environment.
|
|
||||||
**As we only build application for x86, install only dependencies for x86 architecture (i686 in package name)**
|
|
||||||
|
|
||||||
3. Install git into msys2 environment:
|
2. Install monero dependencies as described in [monero documentation](https://github.com/monero-project/monero) into msys2 environment
|
||||||
|
**As we only build application for x86, install only dependencies for x86 architecture (i686 in package name)**
|
||||||
|
```
|
||||||
|
pacman -S mingw-w64-i686-toolchain make mingw-w64-i686-cmake mingw-w64-i686-boost
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Install git into msys2 environment
|
||||||
|
|
||||||
```
|
```
|
||||||
pacman -S git
|
pacman -S git
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Install Qt5 from [official site](https://www.qt.io/download-open-source/).
|
4. Install Qt5 from [official site](https://www.qt.io/download-open-source/)
|
||||||
- download unified installer, run and select following options:
|
- download unified installer, run and select following options:
|
||||||
- Qt > Qt 5.7 > MinGW 5.3.0 32 bit
|
- Qt > Qt 5.7 > MinGW 5.3.0 32 bit
|
||||||
- Tools > MinGW 5.3.0
|
- Tools > MinGW 5.3.0
|
||||||
- continue with installation
|
- continue with installation
|
||||||
|
|
||||||
5. Open ```mingw``` shell:
|
5. Open ```MinGW-w64 Win32 Shell``` shell
|
||||||
|
|
||||||
```%MSYS_ROOT%\msys2_shell.cmd -mingw32```
|
```%MSYS_ROOT%\msys2_shell.cmd -mingw32```
|
||||||
|
|
||||||
Where ```%MSYS_ROOT%``` will be ```c:\msys32``` if your host OS is x86-based or ```c:\msys64``` if your host OS
|
Where ```%MSYS_ROOT%``` will be ```c:\msys32``` if your host OS is x86-based or ```c:\msys64``` if your host OS
|
||||||
is x64-based
|
is x64-based
|
||||||
|
|
||||||
6. Clone repository:
|
6. Install the latest version of boost, specificly the required static libraries
|
||||||
```
|
```
|
||||||
|
cd
|
||||||
|
wget http://sourceforge.net/projects/boost/files/boost/1.63.0/boost_1_63_0.tar.bz2
|
||||||
|
tar xjf boost_1_63_0.tar.bz2
|
||||||
|
cd boost_1_63_0
|
||||||
|
./bootstrap.sh mingw
|
||||||
|
./b2 --prefix=/mingw32/boost --layout=tagged --without-mpi --without-python toolset=gcc address-model=32 variant=debug,release link=static threading=multi runtime-link=static -j$(nproc) install
|
||||||
|
```
|
||||||
|
|
||||||
|
7. Clone repository
|
||||||
|
```
|
||||||
|
cd
|
||||||
git clone https://github.com/monero-project/monero-core.git
|
git clone https://github.com/monero-project/monero-core.git
|
||||||
```
|
```
|
||||||
|
|
||||||
7. Build libwallet:
|
8. Build the GUI
|
||||||
```
|
```
|
||||||
cd monero-core
|
cd monero-core
|
||||||
./get_libwallet_api.sh
|
export PATH=$(ls -rd /c/Qt/5.[6,7,8]/mingw53_32/bin | head -1):$PATH
|
||||||
|
./build.sh
|
||||||
|
cd build
|
||||||
|
make deploy
|
||||||
```
|
```
|
||||||
close ```mingw``` shell after it done
|
|
||||||
|
|
||||||
8. Build application:
|
The executable can be found in the ```.\release\bin``` directory.
|
||||||
|
|
||||||
- open ```Qt environment``` shell (Qt 5.7 for Desktop (MinGW 5.3.0 32 bit) is shortcut name)
|
|
||||||
- navigate to the project dir and build the app:
|
|
||||||
```
|
|
||||||
cd %MSYS_ROOT%\%USERNAME%\monero-core
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
qmake ..\ -r "CONFIG+=release"
|
|
||||||
mingw32-make release
|
|
||||||
mingw32-make deploy
|
|
||||||
```
|
|
||||||
- grab result binary and dependencies in ```.\release\bin```
|
|
||||||
|
|||||||
53
android/README.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
Copyright (c) 2014-2017, The Monero Project
|
||||||
|
|
||||||
|
|
||||||
|
## Current status : ALPHA
|
||||||
|
|
||||||
|
- Minimum Android 5.0 (api level 21)
|
||||||
|
- Modal dialogs can appear in background giving the feeling that the application is frozen (Work around : turn screen off/on or switch to another app and back)
|
||||||
|
|
||||||
|
## Build using Docker
|
||||||
|
|
||||||
|
# Base environnement
|
||||||
|
|
||||||
|
cd monero/utils/build_scripts
|
||||||
|
docker build -f android32.Dockerfile -t monero-android .
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Build GUI
|
||||||
|
|
||||||
|
cd android/docker
|
||||||
|
docker build -t monero-gui-android .
|
||||||
|
docker create -it --name monero-gui-android monero-gui-android bash
|
||||||
|
|
||||||
|
# Get the apk
|
||||||
|
|
||||||
|
docker cp monero-gui-android:/opt/android/monero-core/build/release/bin/bin/QtApp-debug.apk .
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
- Using ADB (Android debugger bridge) :
|
||||||
|
|
||||||
|
First, see section [Enable adb debugging on your device](https://developer.android.com/studio/command-line/adb.html#Enabling)
|
||||||
|
The only place where we are allowed to play is `/data/local/tmp`. So :
|
||||||
|
|
||||||
|
adb push /opt/android/monero-core/build/release/bin/bin/QtApp-debug.apk /data/local/tmp
|
||||||
|
adb shell pm install -r /data/local/tmp/QtApp-debug.apk
|
||||||
|
|
||||||
|
- Troubleshooting:
|
||||||
|
|
||||||
|
adb devices -l
|
||||||
|
adb logcat
|
||||||
|
|
||||||
|
if using adb inside docker, make sure you did "docker run -v /dev/bus/usb:/dev/bus/usb --privileged"
|
||||||
|
|
||||||
|
- Using a web server
|
||||||
|
|
||||||
|
mkdir /usr/tmp
|
||||||
|
cp QtApp-debug.apk /usr/tmp
|
||||||
|
docker run -d -v /usr/tmp:/usr/share/nginx/html:ro -p 8080:80 nginx
|
||||||
|
|
||||||
|
Now it should be accessible through a web browser at
|
||||||
|
|
||||||
|
http://<your.local.ip>:8080/QtApp-debug.apk
|
||||||
|
|
||||||
108
android/docker/Dockerfile
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
FROM monero-android
|
||||||
|
|
||||||
|
#INSTALL JAVA
|
||||||
|
RUN echo "deb http://ftp.fr.debian.org/debian/ jessie-backports main contrib non-free" >> /etc/apt/sources.list
|
||||||
|
RUN dpkg --add-architecture i386 \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y libc6:i386 libncurses5:i386 libstdc++6:i386 libz1:i386 \
|
||||||
|
&& apt-get install -y -t jessie-backports ca-certificates-java openjdk-8-jdk-headless openjdk-8-jre-headless ant
|
||||||
|
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64
|
||||||
|
ENV PATH $JAVA_HOME/bin:$PATH
|
||||||
|
|
||||||
|
#Get Qt
|
||||||
|
ENV QT_VERSION 5.8
|
||||||
|
|
||||||
|
RUN git clone git://code.qt.io/qt/qt5.git -b ${QT_VERSION} \
|
||||||
|
&& cd qt5 \
|
||||||
|
&& perl init-repository
|
||||||
|
|
||||||
|
## Note: Need to use libc++ but Qt does not provide mkspec for libc++.
|
||||||
|
## Their support of it is quite recent and they claim they don't use it by default
|
||||||
|
## [only because it produces bigger binary objects](https://bugreports.qt.io/browse/QTBUG-50724).
|
||||||
|
|
||||||
|
#Create new mkspec for clang + libc++
|
||||||
|
RUN cp -r qt5/qtbase/mkspecs/android-clang qt5/qtbase/mkspecs/android-clang-libc \
|
||||||
|
&& cd qt5/qtbase/mkspecs/android-clang-libc \
|
||||||
|
&& sed -i '16i ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH' qmake.conf \
|
||||||
|
&& sed -i '17i ANDROID_SOURCES_CXX_STL_INCDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/include' qmake.conf \
|
||||||
|
&& echo "QMAKE_LIBS_PRIVATE = -lc++_shared -llog -lz -lm -ldl -lc -lgcc " >> qmake.conf \
|
||||||
|
&& echo "QMAKE_CFLAGS -= -mfpu=vfp " >> qmake.conf \
|
||||||
|
&& echo "QMAKE_CXXFLAGS -= -mfpu=vfp " >> qmake.conf \
|
||||||
|
&& echo "QMAKE_CFLAGS += -mfpu=vfp4 " >> qmake.conf \
|
||||||
|
&& echo "QMAKE_CXXFLAGS += -mfpu=vfp4 " >> qmake.conf
|
||||||
|
|
||||||
|
ENV ANDROID_API android-21
|
||||||
|
|
||||||
|
#ANDROID SDK TOOLS
|
||||||
|
RUN echo y | $ANDROID_SDK_ROOT/tools/android update sdk --no-ui --all --filter platform-tools
|
||||||
|
RUN echo y | $ANDROID_SDK_ROOT/tools/android update sdk --no-ui --all --filter ${ANDROID_API}
|
||||||
|
RUN echo y | $ANDROID_SDK_ROOT/tools/android update sdk --no-ui --all --filter build-tools-25.0.1
|
||||||
|
|
||||||
|
ENV CLEAN_PATH $JAVA_HOME/bin:/usr/cmake-3.6.3-Linux-x86_64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
|
||||||
|
#build Qt
|
||||||
|
RUN cd qt5 && PATH=${CLEAN_PATH} ./configure -developer-build -release \
|
||||||
|
-xplatform android-clang-libc \
|
||||||
|
-android-ndk-platform ${ANDROID_API} \
|
||||||
|
-android-ndk $ANDROID_NDK_ROOT \
|
||||||
|
-android-sdk $ANDROID_SDK_ROOT \
|
||||||
|
-opensource -confirm-license \
|
||||||
|
-prefix ${WORKDIR}/Qt-${QT_VERSION} \
|
||||||
|
-nomake tests -nomake examples \
|
||||||
|
-skip qtserialport \
|
||||||
|
-skip qtconnectivity \
|
||||||
|
-skip qttranslations \
|
||||||
|
-skip qtgamepad -skip qtscript -skip qtdoc
|
||||||
|
|
||||||
|
# build Qt tools : gnustl_shared.so is hard-coded in androiddeployqt
|
||||||
|
# replace it with libc++_shared.so
|
||||||
|
COPY androiddeployqt.patch qt5/qttools/androiddeployqt.patch
|
||||||
|
RUN cd qt5/qttools \
|
||||||
|
&& git apply androiddeployqt.patch \
|
||||||
|
&& cd .. \
|
||||||
|
&& PATH=${CLEAN_PATH} make -j4 \
|
||||||
|
&& PATH=${CLEAN_PATH} make install
|
||||||
|
|
||||||
|
# Get iconv and ZBar
|
||||||
|
ENV ICONV_VERSION 1.14
|
||||||
|
RUN git clone https://github.com/ZBar/ZBar.git \
|
||||||
|
&& curl -s -O http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz \
|
||||||
|
&& tar -xzf libiconv-${ICONV_VERSION}.tar.gz \
|
||||||
|
&& cd libiconv-${ICONV_VERSION} \
|
||||||
|
&& CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ ./configure --build=x86_64-linux-gnu --host=arm-eabi --prefix=${WORKDIR}/libiconv --disable-rpath
|
||||||
|
|
||||||
|
ENV PATH $ANDROID_SDK_ROOT/tools:$ANDROID_SDK_ROOT/platform-tools:${WORKDIR}/Qt-${QT_VERSION}/bin:$PATH
|
||||||
|
|
||||||
|
#Build libiconv.a and libzbarjni.a
|
||||||
|
COPY android.mk.patch ZBar/android.mk.patch
|
||||||
|
RUN cd ZBar \
|
||||||
|
&& git apply android.mk.patch \
|
||||||
|
&& echo \
|
||||||
|
"APP_ABI := armeabi-v7a \n\
|
||||||
|
APP_STL := c++_shared \n\
|
||||||
|
TARGET_PLATFORM := ${ANDROID_API} \n\
|
||||||
|
TARGET_ARCH_ABI := armeabi-v7a \n\
|
||||||
|
APP_CFLAGS += -target armv7-none-linux-androideabi -fexceptions -fstack-protector-strong -fno-limit-debug-info -mfloat-abi=softfp -mfpu=vfp -fno-builtin-memmove -fno-omit-frame-pointer -fno-stack-protector\n"\
|
||||||
|
>> android/jni/Application.mk \
|
||||||
|
&& cd android \
|
||||||
|
&& android update project --path . -t "${ANDROID_API}" \
|
||||||
|
&& CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ ant -Dndk.dir=${ANDROID_NDK_ROOT} -Diconv.src=${WORKDIR}/libiconv-${ICONV_VERSION} zbar-clean zbar-ndk-build
|
||||||
|
|
||||||
|
#Can't directly call build.sh because of env variables
|
||||||
|
RUN git clone https://github.com/monero-project/monero-core.git \
|
||||||
|
&& cd monero-core \
|
||||||
|
&& git submodule update \
|
||||||
|
&& CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ BOOST_ROOT=/opt/android/boost_1_62_0 BOOST_LIBRARYDIR=${WORKDIR}/boost_${BOOST_VERSION}/android32/lib/ OPENSSL_ROOT_DIR=${WORKDIR}/openssl/ ./get_libwallet_api.sh release-android
|
||||||
|
|
||||||
|
RUN cp openssl/lib* ${ANDROID_NDK_ROOT}/platforms/${ANDROID_API}/arch-arm/usr/lib
|
||||||
|
RUN cp boost_${BOOST_VERSION}/android32/lib/lib* ${ANDROID_NDK_ROOT}/platforms/${ANDROID_API}/arch-arm/usr/lib
|
||||||
|
RUN cp ZBar/android/obj/local/armeabi-v7a/lib* ${ANDROID_NDK_ROOT}/platforms/${ANDROID_API}/arch-arm/usr/lib
|
||||||
|
|
||||||
|
ENV PATH $ANDROID_SDK_ROOT/tools:$ANDROID_SDK_ROOT/platform-tools:${WORKDIR}/Qt-${QT_VERSION}/bin:$CLEAN_PATH
|
||||||
|
|
||||||
|
# NB : zxcvbn-c needs to build a local binary and Qt don't care about these environnement variable
|
||||||
|
RUN cd monero-core \
|
||||||
|
&& CC="gcc" CXX="g++" ./build.sh release-android \
|
||||||
|
&& cd build \
|
||||||
|
&& make deploy
|
||||||
|
|
||||||
61
android/docker/android.mk.patch
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
|
||||||
|
index e442b07..158afd5 100644
|
||||||
|
--- a/android/jni/Android.mk
|
||||||
|
+++ b/android/jni/Android.mk
|
||||||
|
@@ -12,14 +12,18 @@ LOCAL_PATH := $(ICONV_SRC)
|
||||||
|
|
||||||
|
LOCAL_MODULE := libiconv
|
||||||
|
|
||||||
|
+LOCAL_ARM_MODE := arm
|
||||||
|
+LOCAL_CPP_FEATURES := exceptions rtti features
|
||||||
|
LOCAL_CFLAGS := \
|
||||||
|
-Wno-multichar \
|
||||||
|
-D_ANDROID \
|
||||||
|
- -DLIBDIR="c" \
|
||||||
|
+ -DLIBDIR="\".\"" \
|
||||||
|
-DBUILDING_LIBICONV \
|
||||||
|
-DBUILDING_LIBCHARSET \
|
||||||
|
-DIN_LIBRARY
|
||||||
|
|
||||||
|
+LOCAL_CFLAGS += -fno-stack-protector
|
||||||
|
+
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
lib/iconv.c \
|
||||||
|
libcharset/lib/localcharset.c \
|
||||||
|
@@ -30,13 +34,14 @@ LOCAL_C_INCLUDES := \
|
||||||
|
$(ICONV_SRC)/libcharset \
|
||||||
|
$(ICONV_SRC)/libcharset/include
|
||||||
|
|
||||||
|
-include $(BUILD_SHARED_LIBRARY)
|
||||||
|
+include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
|
LOCAL_LDLIBS := -llog -lcharset
|
||||||
|
|
||||||
|
# libzbarjni
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
+
|
||||||
|
LOCAL_PATH := $(MY_LOCAL_PATH)
|
||||||
|
LOCAL_MODULE := zbarjni
|
||||||
|
LOCAL_SRC_FILES := ../../java/zbarjni.c \
|
||||||
|
@@ -71,6 +76,17 @@ LOCAL_C_INCLUDES := ../include \
|
||||||
|
../zbar \
|
||||||
|
$(ICONV_SRC)/include
|
||||||
|
|
||||||
|
-LOCAL_SHARED_LIBRARIES := libiconv
|
||||||
|
+LOCAL_STATIC_LIBRARIES := libiconv
|
||||||
|
+LOCAL_ARM_MODE := arm
|
||||||
|
+LOCAL_CPP_FEATURES := exceptions rtti features
|
||||||
|
+
|
||||||
|
+LOCAL_CFLAGS := \
|
||||||
|
+ -Wno-multichar \
|
||||||
|
+ -D_ANDROID \
|
||||||
|
+ -DLIBDIR="\".\"" \
|
||||||
|
+ -DBUILDING_LIBICONV \
|
||||||
|
+ -DBUILDING_LIBCHARSET \
|
||||||
|
+ -DIN_LIBRARY
|
||||||
|
+
|
||||||
|
|
||||||
|
-include $(BUILD_SHARED_LIBRARY)
|
||||||
|
\ No newline at end of file
|
||||||
|
+include $(BUILD_STATIC_LIBRARY)
|
||||||
62
android/docker/androiddeployqt.patch
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
diff --git a/src/androiddeployqt/main.cpp b/src/androiddeployqt/main.cpp
|
||||||
|
index 8a8e591..71d693e 100644
|
||||||
|
--- a/src/androiddeployqt/main.cpp
|
||||||
|
+++ b/src/androiddeployqt/main.cpp
|
||||||
|
@@ -1122,7 +1122,7 @@ bool updateLibsXml(const Options &options)
|
||||||
|
|
||||||
|
QString libsPath = QLatin1String("libs/") + options.architecture + QLatin1Char('/');
|
||||||
|
|
||||||
|
- QString qtLibs = QLatin1String("<item>gnustl_shared</item>\n");
|
||||||
|
+ QString qtLibs = QLatin1String("<item>c++_shared</item>\n");
|
||||||
|
QString bundledInLibs;
|
||||||
|
QString bundledInAssets;
|
||||||
|
foreach (Options::BundledFile bundledFile, options.bundledFiles) {
|
||||||
|
@@ -2519,6 +2519,39 @@ bool installApk(const Options &options)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+bool copyStl(Options *options)
|
||||||
|
+{
|
||||||
|
+ if (options->deploymentMechanism == Options::Debug && !options->installApk)
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ if (options->verbose)
|
||||||
|
+ fprintf(stdout, "Copying LIBC++ STL library\n");
|
||||||
|
+
|
||||||
|
+ QString filePath = options->ndkPath
|
||||||
|
+ + QLatin1String("/sources/cxx-stl/llvm-libc++")
|
||||||
|
+ + QLatin1String("/libs/")
|
||||||
|
+ + options->architecture
|
||||||
|
+ + QLatin1String("/libc++_shared.so");
|
||||||
|
+ if (!QFile::exists(filePath)) {
|
||||||
|
+ fprintf(stderr, "LIBC STL library does not exist at %s\n", qPrintable(filePath));
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ QString destinationDirectory =
|
||||||
|
+ options->deploymentMechanism == Options::Debug
|
||||||
|
+ ? options->temporaryDirectoryName + QLatin1String("/lib")
|
||||||
|
+ : options->outputDirectory + QLatin1String("/libs/") + options->architecture;
|
||||||
|
+
|
||||||
|
+ if (!copyFileIfNewer(filePath, destinationDirectory
|
||||||
|
+ + QLatin1String("/libc++_shared.so"), options->verbose)) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (options->deploymentMechanism == Options::Debug && !deployToLocalTmp(options, QLatin1String("/lib/libc++_shared.so")))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
bool copyGnuStl(Options *options)
|
||||||
|
{
|
||||||
|
if (options->deploymentMechanism == Options::Debug && !options->installApk)
|
||||||
|
@@ -2870,7 +2903,7 @@ int main(int argc, char *argv[])
|
||||||
|
if (Q_UNLIKELY(options.timing))
|
||||||
|
fprintf(stdout, "[TIMING] %d ms: Read dependencies\n", options.timer.elapsed());
|
||||||
|
|
||||||
|
- if (options.deploymentMechanism != Options::Ministro && !copyGnuStl(&options))
|
||||||
|
+ if (options.deploymentMechanism != Options::Ministro && !copyStl(&options))
|
||||||
|
return CannotCopyGnuStl;
|
||||||
|
|
||||||
|
if (Q_UNLIKELY(options.timing))
|
||||||
69
build.sh
@@ -1,8 +1,44 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
BUILD_TYPE=$1
|
BUILD_TYPE=$1
|
||||||
|
source ./utils.sh
|
||||||
|
platform=$(get_platform)
|
||||||
|
# default build type
|
||||||
if [ -z $BUILD_TYPE ]; then
|
if [ -z $BUILD_TYPE ]; then
|
||||||
BUILD_TYPE=Release
|
BUILD_TYPE=release
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$BUILD_TYPE" == "release" ]; then
|
||||||
|
echo "Building release"
|
||||||
|
CONFIG="CONFIG+=release";
|
||||||
|
BIN_PATH=release/bin
|
||||||
|
elif [ "$BUILD_TYPE" == "release-static" ]; then
|
||||||
|
echo "Building release-static"
|
||||||
|
if [ "$platform" != "darwin" ]; then
|
||||||
|
CONFIG="CONFIG+=release static";
|
||||||
|
else
|
||||||
|
# OS X: build static libwallet but dynamic Qt.
|
||||||
|
echo "OS X: Building Qt project without static flag"
|
||||||
|
CONFIG="CONFIG+=release";
|
||||||
|
fi
|
||||||
|
BIN_PATH=release/bin
|
||||||
|
elif [ "$BUILD_TYPE" == "release-android" ]; then
|
||||||
|
echo "Building release for ANDROID"
|
||||||
|
CONFIG="CONFIG+=release static WITH_SCANNER";
|
||||||
|
ANDROID=true
|
||||||
|
BIN_PATH=release/bin
|
||||||
|
elif [ "$BUILD_TYPE" == "debug-android" ]; then
|
||||||
|
echo "Building debug for ANDROID : ultra INSECURE !!"
|
||||||
|
CONFIG="CONFIG+=debug qml_debug WITH_SCANNER";
|
||||||
|
ANDROID=true
|
||||||
|
BIN_PATH=debug/bin
|
||||||
|
elif [ "$BUILD_TYPE" == "debug" ]; then
|
||||||
|
echo "Building debug"
|
||||||
|
CONFIG="CONFIG+=debug"
|
||||||
|
BIN_PATH=debug/bin
|
||||||
|
else
|
||||||
|
echo "Valid build types are release, release-static, release-android, debug-android and debug"
|
||||||
|
exit 1;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
@@ -12,27 +48,22 @@ ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|||||||
MONERO_DIR=monero
|
MONERO_DIR=monero
|
||||||
MONEROD_EXEC=monerod
|
MONEROD_EXEC=monerod
|
||||||
|
|
||||||
# Build libwallet if monero folder doesnt exist
|
MAKE='make'
|
||||||
if [ ! -d $MONERO_DIR ]; then
|
if [[ $platform == *bsd* ]]; then
|
||||||
$SHELL get_libwallet_api.sh $BUILD_TYPE
|
MAKE='gmake'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# build libwallet
|
||||||
|
./get_libwallet_api.sh $BUILD_TYPE
|
||||||
|
|
||||||
# build zxcvbn
|
# build zxcvbn
|
||||||
make -C src/zxcvbn-c
|
$MAKE -C src/zxcvbn-c || exit
|
||||||
|
|
||||||
if [ ! -d build ]; then mkdir build; fi
|
if [ ! -d build ]; then mkdir build; fi
|
||||||
|
|
||||||
if [ "$BUILD_TYPE" == "Release" ]; then
|
|
||||||
CONFIG="CONFIG+=release";
|
|
||||||
BIN_PATH=release/bin
|
|
||||||
else
|
|
||||||
CONFIG="CONFIG+=debug"
|
|
||||||
BIN_PATH=debug/bin
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Platform indepenent settings
|
# Platform indepenent settings
|
||||||
platform=$(get_platform)
|
if [ "$ANDROID" != true ] && ([ "$platform" == "linux32" ] || [ "$platform" == "linux64" ]); then
|
||||||
if [ "$platform" == "linux32" ] || [ "$platform" == "linux64" ]; then
|
|
||||||
distro=$(lsb_release -is)
|
distro=$(lsb_release -is)
|
||||||
if [ "$distro" == "Ubuntu" ]; then
|
if [ "$distro" == "Ubuntu" ]; then
|
||||||
CONFIG="$CONFIG libunwind_off"
|
CONFIG="$CONFIG libunwind_off"
|
||||||
@@ -47,18 +78,18 @@ fi
|
|||||||
|
|
||||||
# force version update
|
# force version update
|
||||||
get_tag
|
get_tag
|
||||||
echo "var GUI_VERSION = \"$VERSIONTAG\"" > version.js
|
echo "var GUI_VERSION = \"$TAGNAME\"" > version.js
|
||||||
pushd "$MONERO_DIR"
|
pushd "$MONERO_DIR"
|
||||||
get_tag
|
get_tag
|
||||||
popd
|
popd
|
||||||
echo "var GUI_MONERO_VERSION = \"$VERSIONTAG\"" >> version.js
|
echo "var GUI_MONERO_VERSION = \"$TAGNAME\"" >> version.js
|
||||||
|
|
||||||
cd build
|
cd build
|
||||||
qmake ../monero-wallet-gui.pro "$CONFIG"
|
qmake ../monero-wallet-gui.pro "$CONFIG" || exit
|
||||||
make
|
$MAKE || exit
|
||||||
|
|
||||||
# Copy monerod to bin folder
|
# Copy monerod to bin folder
|
||||||
if [ "$platform" != "mingw32" ]; then
|
if [ "$platform" != "mingw32" ] && [ "$ANDROID" != true ]; then
|
||||||
cp ../$MONERO_DIR/bin/$MONEROD_EXEC $BIN_PATH
|
cp ../$MONERO_DIR/bin/$MONEROD_EXEC $BIN_PATH
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,6 @@ ListView {
|
|||||||
anchors.rightMargin: 40
|
anchors.rightMargin: 40
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#545454"
|
color: "#545454"
|
||||||
text: address
|
text: address
|
||||||
}
|
}
|
||||||
@@ -101,7 +100,6 @@ ListView {
|
|||||||
width: 139
|
width: 139
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#535353"
|
color: "#535353"
|
||||||
text: qsTr("Payment ID:") + translationManager.emptyString
|
text: qsTr("Payment ID:") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
@@ -117,7 +115,6 @@ ListView {
|
|||||||
|
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#545454"
|
color: "#545454"
|
||||||
text: paymentId
|
text: paymentId
|
||||||
}
|
}
|
||||||
@@ -125,7 +122,7 @@ ListView {
|
|||||||
ListModel {
|
ListModel {
|
||||||
id: dropModel
|
id: dropModel
|
||||||
ListElement { name: "<b>Copy address to clipboard</b>"; icon: "../images/dropdownCopy.png" }
|
ListElement { name: "<b>Copy address to clipboard</b>"; icon: "../images/dropdownCopy.png" }
|
||||||
ListElement { name: "<b>Send to same destination</b>"; icon: "../images/dropdownSend.png" }
|
ListElement { name: "<b>Send to this address</b>"; icon: "../images/dropdownSend.png" }
|
||||||
// ListElement { name: "<b>Find similar transactions</b>"; icon: "../images/dropdownSearch.png" }
|
// ListElement { name: "<b>Find similar transactions</b>"; icon: "../images/dropdownSearch.png" }
|
||||||
ListElement { name: "<b>Remove from address book</b>"; icon: "../images/dropdownDel.png" }
|
ListElement { name: "<b>Remove from address book</b>"; icon: "../images/dropdownDel.png" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: checkBox
|
id: checkBox
|
||||||
@@ -40,6 +41,7 @@ Item {
|
|||||||
signal clicked()
|
signal clicked()
|
||||||
height: 25
|
height: 25
|
||||||
width: label.x + label.width
|
width: label.x + label.width
|
||||||
|
Layout.minimumWidth: label.x + label.contentWidth
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -74,7 +76,6 @@ Item {
|
|||||||
anchors.leftMargin: 25 + 12
|
anchors.leftMargin: 25 + 12
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: checkBox.fontSize
|
font.pixelSize: checkBox.fontSize
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#525252"
|
color: "#525252"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
156
components/DaemonConsole.qml
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
// Copyright (c) 2014-2015, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import QtQuick.Controls.Styles 1.4
|
||||||
|
import QtQuick.Window 2.0
|
||||||
|
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
Window {
|
||||||
|
id: root
|
||||||
|
modality: Qt.ApplicationModal
|
||||||
|
flags: Qt.Window | Qt.FramelessWindowHint
|
||||||
|
property alias title: dialogTitle.text
|
||||||
|
property alias text: dialogContent.text
|
||||||
|
property alias content: root.text
|
||||||
|
property alias okVisible: okButton.visible
|
||||||
|
property alias textArea: dialogContent
|
||||||
|
property var icon
|
||||||
|
|
||||||
|
// same signals as Dialog has
|
||||||
|
signal accepted()
|
||||||
|
signal rejected()
|
||||||
|
|
||||||
|
|
||||||
|
function open() {
|
||||||
|
show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: implement without hardcoding sizes
|
||||||
|
width: 480
|
||||||
|
height: 280
|
||||||
|
|
||||||
|
// Make window draggable
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
property point lastMousePos: Qt.point(0, 0)
|
||||||
|
onPressed: { lastMousePos = Qt.point(mouseX, mouseY); }
|
||||||
|
onMouseXChanged: root.x += (mouseX - lastMousePos.x)
|
||||||
|
onMouseYChanged: root.y += (mouseY - lastMousePos.y)
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: mainLayout
|
||||||
|
spacing: 10
|
||||||
|
anchors { fill: parent; margins: 35 }
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: column
|
||||||
|
//anchors {fill: parent; margins: 16 }
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: dialogTitle
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
font.pixelSize: 32
|
||||||
|
font.family: "Arial"
|
||||||
|
color: "#555555"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
TextArea {
|
||||||
|
id : dialogContent
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
font.family: "Arial"
|
||||||
|
textFormat: TextEdit.AutoText
|
||||||
|
readOnly: true
|
||||||
|
font.pixelSize: 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ok/Cancel buttons
|
||||||
|
RowLayout {
|
||||||
|
id: buttons
|
||||||
|
spacing: 60
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
id: okButton
|
||||||
|
width: 120
|
||||||
|
fontSize: 14
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
text: qsTr("Close") + translationManager.emptyString
|
||||||
|
onClicked: {
|
||||||
|
root.close()
|
||||||
|
root.accepted()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.LineEdit {
|
||||||
|
id: sendCommandText
|
||||||
|
width: 300
|
||||||
|
placeholderText: qsTr("command + enter (e.g help)") + translationManager.emptyString
|
||||||
|
onAccepted: {
|
||||||
|
if(text.length > 0)
|
||||||
|
daemonManager.sendCommand(text,currentWallet.testnet);
|
||||||
|
text = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status button
|
||||||
|
// MoneroComponents.StandardButton {
|
||||||
|
// id: sendCommandButton
|
||||||
|
// enabled: sendCommandText.text.length > 0
|
||||||
|
// fontSize: 14
|
||||||
|
// shadowReleasedColor: "#FF4304"
|
||||||
|
// shadowPressedColor: "#B32D00"
|
||||||
|
// releasedColor: "#FF6C3C"
|
||||||
|
// pressedColor: "#FF4304"
|
||||||
|
// text: qsTr("Send command")
|
||||||
|
// onClicked: {
|
||||||
|
// daemonManager.sendCommand(sendCommandText.text,currentWallet.testnet);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -39,18 +39,29 @@ Window {
|
|||||||
id: root
|
id: root
|
||||||
modality: Qt.ApplicationModal
|
modality: Qt.ApplicationModal
|
||||||
flags: Qt.Window | Qt.FramelessWindowHint
|
flags: Qt.Window | Qt.FramelessWindowHint
|
||||||
|
property int countDown: 5;
|
||||||
signal rejected()
|
signal rejected()
|
||||||
signal started();
|
signal started();
|
||||||
|
|
||||||
function open() {
|
function open() {
|
||||||
show()
|
show()
|
||||||
|
countDown = 5;
|
||||||
|
timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement without hardcoding sizes
|
// TODO: implement without hardcoding sizes
|
||||||
width: 480
|
width: 480
|
||||||
height: 200
|
height: 200
|
||||||
|
|
||||||
|
// Make window draggable
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
property point lastMousePos: Qt.point(0, 0)
|
||||||
|
onPressed: { lastMousePos = Qt.point(mouseX, mouseY); }
|
||||||
|
onMouseXChanged: root.x += (mouseX - lastMousePos.x)
|
||||||
|
onMouseYChanged: root.y += (mouseY - lastMousePos.y)
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
spacing: 10
|
spacing: 10
|
||||||
@@ -61,15 +72,29 @@ Window {
|
|||||||
//anchors {fill: parent; margins: 16 }
|
//anchors {fill: parent; margins: 16 }
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
Label {
|
Timer {
|
||||||
text: qsTr("Daemon doesn't appear to be running")
|
id: timer
|
||||||
|
interval: 1000;
|
||||||
|
running: false;
|
||||||
|
repeat: true
|
||||||
|
onTriggered: {
|
||||||
|
countDown--;
|
||||||
|
if(countDown < 0){
|
||||||
|
running = false;
|
||||||
|
// Start daemon
|
||||||
|
root.close()
|
||||||
|
appWindow.startDaemon(persistentSettings.daemonFlags);
|
||||||
|
root.started();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Starting Monero daemon in %1 seconds").arg(countDown);
|
||||||
|
font.pixelSize: 18
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.columnSpan: 2
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
font.pixelSize: 24
|
|
||||||
font.family: "Arial"
|
|
||||||
color: "#555555"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -81,57 +106,39 @@ Window {
|
|||||||
|
|
||||||
MoneroComponents.StandardButton {
|
MoneroComponents.StandardButton {
|
||||||
id: okButton
|
id: okButton
|
||||||
width: 120
|
visible:false
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
pressedColor: "#FF4304"
|
pressedColor: "#FF4304"
|
||||||
text: qsTr("Start daemon")
|
text: qsTr("Start daemon (%1)").arg(countDown)
|
||||||
KeyNavigation.tab: cancelButton
|
KeyNavigation.tab: cancelButton
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
timer.stop();
|
||||||
root.close()
|
root.close()
|
||||||
appWindow.startDaemon(daemonFlags.text);
|
appWindow.startDaemon(persistentSettings.daemonFlags);
|
||||||
root.started()
|
root.started()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
MoneroComponents.StandardButton {
|
||||||
id: cancelButton
|
id: cancelButton
|
||||||
width: 120
|
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
pressedColor: "#FF4304"
|
pressedColor: "#FF4304"
|
||||||
text: qsTr("Cancel")
|
text: qsTr("Use custom settings")
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
timer.stop();
|
||||||
root.close()
|
root.close()
|
||||||
root.rejected()
|
root.rejected()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RowLayout {
|
|
||||||
id: advancedRow
|
|
||||||
MoneroComponents.Label {
|
|
||||||
id: daemonFlagsLabel
|
|
||||||
color: "#4A4949"
|
|
||||||
text: qsTr("Daemon startup flags") + translationManager.emptyString
|
|
||||||
fontSize: 16
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.LineEdit {
|
|
||||||
id: daemonFlags
|
|
||||||
Layout.preferredWidth: 200
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: appWindow.persistentSettings.daemonFlags;
|
|
||||||
placeholderText: qsTr("(optional)")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,6 @@ ListView {
|
|||||||
Text {
|
Text {
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#000000"
|
color: "#000000"
|
||||||
text: date
|
text: date
|
||||||
}
|
}
|
||||||
@@ -153,7 +152,6 @@ ListView {
|
|||||||
Text {
|
Text {
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#000000"
|
color: "#000000"
|
||||||
text: time
|
text: time
|
||||||
}
|
}
|
||||||
@@ -175,7 +173,6 @@ ListView {
|
|||||||
Text {
|
Text {
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#000000"
|
color: "#000000"
|
||||||
text: balance
|
text: balance
|
||||||
}
|
}
|
||||||
@@ -208,7 +205,6 @@ ListView {
|
|||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.letterSpacing: -1
|
|
||||||
color: out ? "#FF4F41" : "#36B05B"
|
color: out ? "#FF4F41" : "#36B05B"
|
||||||
text: amount
|
text: amount
|
||||||
}
|
}
|
||||||
@@ -220,7 +216,7 @@ ListView {
|
|||||||
id: dropModel
|
id: dropModel
|
||||||
ListElement { name: "<b>Copy address to clipboard</b>"; icon: "../images/dropdownCopy.png" }
|
ListElement { name: "<b>Copy address to clipboard</b>"; icon: "../images/dropdownCopy.png" }
|
||||||
ListElement { name: "<b>Add to address book</b>"; icon: "../images/dropdownAdd.png" }
|
ListElement { name: "<b>Add to address book</b>"; icon: "../images/dropdownAdd.png" }
|
||||||
ListElement { name: "<b>Send to same destination</b>"; icon: "../images/dropdownSend.png" }
|
ListElement { name: "<b>Send to this address</b>"; icon: "../images/dropdownSend.png" }
|
||||||
ListElement { name: "<b>Find similar transactions</b>"; icon: "../images/dropdownSearch.png" }
|
ListElement { name: "<b>Find similar transactions</b>"; icon: "../images/dropdownSearch.png" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -285,7 +285,6 @@ Item {
|
|||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.letterSpacing: -1
|
|
||||||
font.bold: dayArea.pressed
|
font.bold: dayArea.pressed
|
||||||
text: styleData.date.getDate()
|
text: styleData.date.getDate()
|
||||||
color: {
|
color: {
|
||||||
@@ -322,7 +321,6 @@ Item {
|
|||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 9
|
font.pixelSize: 9
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#535353"
|
color: "#535353"
|
||||||
text: {
|
text: {
|
||||||
var locale = Qt.locale()
|
var locale = Qt.locale()
|
||||||
@@ -339,7 +337,6 @@ Item {
|
|||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#4A4646"
|
color: "#4A4646"
|
||||||
text: styleData.title
|
text: styleData.title
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import moneroComponents.Clipboard 1.0
|
import moneroComponents.Clipboard 1.0
|
||||||
|
import moneroComponents.AddressBookModel 1.0
|
||||||
|
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
@@ -36,6 +37,7 @@ ListView {
|
|||||||
boundsBehavior: ListView.StopAtBounds
|
boundsBehavior: ListView.StopAtBounds
|
||||||
property var previousItem
|
property var previousItem
|
||||||
property int rowSpacing: 12
|
property int rowSpacing: 12
|
||||||
|
property var addressBookModel: null
|
||||||
|
|
||||||
function buildTxDetailsString(tx_id, paymentId, tx_key,tx_note, destinations) {
|
function buildTxDetailsString(tx_id, paymentId, tx_key,tx_note, destinations) {
|
||||||
var trStart = '<tr><td width="85" style="padding-top:5px"><b>',
|
var trStart = '<tr><td width="85" style="padding-top:5px"><b>',
|
||||||
@@ -52,6 +54,15 @@ ListView {
|
|||||||
+ translationManager.emptyString;
|
+ translationManager.emptyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function lookupPaymentID(paymentId) {
|
||||||
|
if (!addressBookModel)
|
||||||
|
return ""
|
||||||
|
var idx = addressBookModel.lookupPaymentID(paymentId)
|
||||||
|
if (idx < 0)
|
||||||
|
return ""
|
||||||
|
idx = addressBookModel.index(idx, 0)
|
||||||
|
return addressBookModel.data(idx, AddressBookModel.AddressBookDescriptionRole)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
footer: Rectangle {
|
footer: Rectangle {
|
||||||
@@ -188,7 +199,6 @@ ListView {
|
|||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#535353"
|
color: "#535353"
|
||||||
text: paymentId !== "" ? qsTr("Payment ID:") + translationManager.emptyString : ""
|
text: paymentId !== "" ? qsTr("Payment ID:") + translationManager.emptyString : ""
|
||||||
}
|
}
|
||||||
@@ -202,11 +212,24 @@ ListView {
|
|||||||
//elide: Text.ElideRight
|
//elide: Text.ElideRight
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize:13
|
font.pixelSize:13
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#545454"
|
color: "#545454"
|
||||||
text: paymentId
|
text: paymentId
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// Address book lookup
|
||||||
|
TextEdit {
|
||||||
|
readOnly: true
|
||||||
|
selectByMouse: true
|
||||||
|
id: addressBookLookupValue
|
||||||
|
width: 136
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
//elide: Text.ElideRight
|
||||||
|
font.family: "Arial"
|
||||||
|
font.pixelSize:13
|
||||||
|
color: "#545454"
|
||||||
|
text: "(" + lookupPaymentID(paymentId) + ")"
|
||||||
|
visible: text !== "()"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Row {
|
Row {
|
||||||
// block height row
|
// block height row
|
||||||
@@ -224,7 +247,6 @@ ListView {
|
|||||||
width: 86
|
width: 86
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#535353"
|
color: "#535353"
|
||||||
text: qsTr("BlockHeight:") + translationManager.emptyString
|
text: qsTr("BlockHeight:") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
@@ -237,9 +259,18 @@ ListView {
|
|||||||
//elide: Text.ElideRight
|
//elide: Text.ElideRight
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
font.letterSpacing: -1
|
color: (confirmations < confirmationsRequired)? "#FF6C3C" : "#545454"
|
||||||
color: "#545454"
|
text: {
|
||||||
text: blockHeight
|
if (!isPending)
|
||||||
|
if(confirmations < confirmationsRequired)
|
||||||
|
return blockHeight + " " + qsTr("(%1/%2 confirmations)").arg(confirmations).arg(confirmationsRequired)
|
||||||
|
else
|
||||||
|
return blockHeight
|
||||||
|
if (!isOut)
|
||||||
|
return qsTr("UNCONFIRMED") + translationManager.emptyString
|
||||||
|
return qsTr("PENDING") + translationManager.emptyString
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +308,6 @@ ListView {
|
|||||||
Text {
|
Text {
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#000000"
|
color: "#000000"
|
||||||
text: date
|
text: date
|
||||||
}
|
}
|
||||||
@@ -285,7 +315,6 @@ ListView {
|
|||||||
Text {
|
Text {
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#000000"
|
color: "#000000"
|
||||||
text: time
|
text: time
|
||||||
}
|
}
|
||||||
@@ -310,7 +339,6 @@ ListView {
|
|||||||
Text {
|
Text {
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#000000"
|
color: "#000000"
|
||||||
text: balance
|
text: balance
|
||||||
}
|
}
|
||||||
@@ -320,7 +348,6 @@ ListView {
|
|||||||
// -- "Amount column
|
// -- "Amount column
|
||||||
Column {
|
Column {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
width: 148
|
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -342,10 +369,10 @@ ListView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
id: amountText
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.letterSpacing: -1
|
|
||||||
color: isOut ? "#FF4F41" : "#36B05B"
|
color: isOut ? "#FF4F41" : "#36B05B"
|
||||||
text: displayAmount
|
text: displayAmount
|
||||||
}
|
}
|
||||||
@@ -371,7 +398,6 @@ ListView {
|
|||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#FF4F41"
|
color: "#FF4F41"
|
||||||
text: fee
|
text: fee
|
||||||
}
|
}
|
||||||
@@ -417,7 +443,7 @@ ListView {
|
|||||||
id: dropModel
|
id: dropModel
|
||||||
ListElement { name: "<b>Copy address to clipboard</b>"; icon: "../images/dropdownCopy.png" }
|
ListElement { name: "<b>Copy address to clipboard</b>"; icon: "../images/dropdownCopy.png" }
|
||||||
ListElement { name: "<b>Add to address book</b>"; icon: "../images/dropdownAdd.png" }
|
ListElement { name: "<b>Add to address book</b>"; icon: "../images/dropdownAdd.png" }
|
||||||
ListElement { name: "<b>Send to same destination</b>"; icon: "../images/dropdownSend.png" }
|
ListElement { name: "<b>Send to this address</b>"; icon: "../images/dropdownSend.png" }
|
||||||
ListElement { name: "<b>Find similar transactions</b>"; icon: "../images/dropdownSearch.png" }
|
ListElement { name: "<b>Find similar transactions</b>"; icon: "../images/dropdownSearch.png" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: item
|
id: item
|
||||||
@@ -35,6 +36,7 @@ Item {
|
|||||||
property alias textFormat: label.textFormat
|
property alias textFormat: label.textFormat
|
||||||
property string tipText: ""
|
property string tipText: ""
|
||||||
property int fontSize: 12
|
property int fontSize: 12
|
||||||
|
property alias wrapMode: label.wrapMode
|
||||||
signal linkActivated()
|
signal linkActivated()
|
||||||
width: icon.x + icon.width
|
width: icon.x + icon.width
|
||||||
height: icon.height
|
height: icon.height
|
||||||
@@ -59,23 +61,23 @@ Item {
|
|||||||
visible: appWindow.whatIsEnable
|
visible: appWindow.whatIsEnable
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
// MouseArea {
|
||||||
anchors.fill: icon
|
// anchors.fill: icon
|
||||||
enabled: appWindow.whatIsEnable
|
// enabled: appWindow.whatIsEnable
|
||||||
hoverEnabled: true
|
// hoverEnabled: true
|
||||||
onEntered: {
|
// onEntered: {
|
||||||
icon.visible = false
|
// icon.visible = false
|
||||||
var pos = appWindow.mapFromItem(icon, 0, -15)
|
// var pos = appWindow.mapFromItem(icon, 0, -15)
|
||||||
tipItem.text = item.tipText
|
// tipItem.text = item.tipText
|
||||||
tipItem.x = pos.x
|
// tipItem.x = pos.x
|
||||||
if(tipItem.height > 30)
|
// if(tipItem.height > 30)
|
||||||
pos.y -= tipItem.height - 28
|
// pos.y -= tipItem.height - 28
|
||||||
tipItem.y = pos.y
|
// tipItem.y = pos.y
|
||||||
tipItem.visible = true
|
// tipItem.visible = true
|
||||||
}
|
// }
|
||||||
onExited: {
|
// onExited: {
|
||||||
icon.visible = Qt.binding(function(){ return appWindow.whatIsEnable; })
|
// icon.visible = Qt.binding(function(){ return appWindow.whatIsEnable; })
|
||||||
tipItem.visible = false
|
// tipItem.visible = false
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,14 +29,18 @@
|
|||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
id: item
|
||||||
property alias placeholderText: input.placeholderText
|
property alias placeholderText: input.placeholderText
|
||||||
property alias text: input.text
|
property alias text: input.text
|
||||||
property alias validator: input.validator
|
property alias validator: input.validator
|
||||||
property alias readOnly : input.readOnly
|
property alias readOnly : input.readOnly
|
||||||
property alias cursorPosition: input.cursorPosition
|
property alias cursorPosition: input.cursorPosition
|
||||||
|
property alias echoMode: input.echoMode
|
||||||
property int fontSize: 18
|
property int fontSize: 18
|
||||||
property bool error: false
|
property bool error: false
|
||||||
|
signal editingFinished()
|
||||||
|
signal accepted();
|
||||||
|
signal textUpdated();
|
||||||
|
|
||||||
height: 37
|
height: 37
|
||||||
|
|
||||||
@@ -67,5 +71,8 @@ Item {
|
|||||||
anchors.leftMargin: 4
|
anchors.leftMargin: 4
|
||||||
anchors.rightMargin: 30
|
anchors.rightMargin: 30
|
||||||
font.pixelSize: parent.fontSize
|
font.pixelSize: parent.fontSize
|
||||||
|
onEditingFinished: item.editingFinished()
|
||||||
|
onAccepted: item.accepted();
|
||||||
|
onTextChanged: item.textUpdated()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ Rectangle {
|
|||||||
|
|
||||||
color: checked ? "#FFFFFF" : "#1C1C1C"
|
color: checked ? "#FFFFFF" : "#1C1C1C"
|
||||||
property bool present: !under || under.checked || checked || under.numSelectedChildren > 0
|
property bool present: !under || under.checked || checked || under.numSelectedChildren > 0
|
||||||
height: present ? ((appWindow.height >= 800) ? 64 : 56) : 0
|
height: present ? ((appWindow.height >= 800) ? 64 : 52) : 0
|
||||||
|
|
||||||
transform: Scale {
|
transform: Scale {
|
||||||
yScale: button.present ? 1 : 0
|
yScale: button.present ? 1 : 0
|
||||||
|
|||||||
119
components/MobileHeader.qml
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
import QtQuick 2.2
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import moneroComponents.Wallet 1.0
|
||||||
|
|
||||||
|
|
||||||
|
// BasicPanel header
|
||||||
|
Rectangle {
|
||||||
|
id: header
|
||||||
|
anchors.leftMargin: 1
|
||||||
|
anchors.rightMargin: 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 64
|
||||||
|
color: "#FFFFFF"
|
||||||
|
// visible: basicMode
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: logo
|
||||||
|
visible: appWindow.width > 460
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.verticalCenterOffset: -5
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: appWindow.persistentSettings.customDecorations ? 20 : 40
|
||||||
|
source: "../images/moneroLogo2.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: icon
|
||||||
|
visible: !logo.visible
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
// anchors.verticalCenterOffset: -5
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: appWindow.persistentSettings.customDecorations ? 20 : 40
|
||||||
|
source: "../images/moneroIcon.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
Grid {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.topMargin: 10
|
||||||
|
width: 256
|
||||||
|
columns: 3
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: balanceLabel
|
||||||
|
width: 116
|
||||||
|
height: 20
|
||||||
|
font.family: "Arial"
|
||||||
|
font.pixelSize: 12
|
||||||
|
font.letterSpacing: -1
|
||||||
|
elide: Text.ElideRight
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
verticalAlignment: Text.AlignBottom
|
||||||
|
color: "#535353"
|
||||||
|
text: leftPanel.balanceLabelText + ":"
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: balanceText
|
||||||
|
width: 110
|
||||||
|
height: 20
|
||||||
|
font.family: "Arial"
|
||||||
|
font.pixelSize: 18
|
||||||
|
font.letterSpacing: -1
|
||||||
|
elide: Text.ElideRight
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
verticalAlignment: Text.AlignBottom
|
||||||
|
color: "#000000"
|
||||||
|
text: leftPanel.balanceText
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
height: 20
|
||||||
|
width: 20
|
||||||
|
|
||||||
|
Image {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
source: "../images/lockIcon.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
width: 116
|
||||||
|
height: 20
|
||||||
|
font.family: "Arial"
|
||||||
|
font.pixelSize: 12
|
||||||
|
font.letterSpacing: -1
|
||||||
|
elide: Text.ElideRight
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
verticalAlignment: Text.AlignBottom
|
||||||
|
color: "#535353"
|
||||||
|
text: qsTr("Unlocked Balance:")
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: availableBalanceText
|
||||||
|
width: 110
|
||||||
|
height: 20
|
||||||
|
font.family: "Arial"
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.letterSpacing: -1
|
||||||
|
elide: Text.ElideRight
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
verticalAlignment: Text.AlignBottom
|
||||||
|
color: "#000000"
|
||||||
|
text: leftPanel.unlockedBalanceText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
height: 1
|
||||||
|
color: "#DBDBDB"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,8 +48,11 @@ Row {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getConnectionStatusString(status) {
|
function getConnectionStatusString(status) {
|
||||||
if (status == Wallet.ConnectionStatus_Connected)
|
if (status == Wallet.ConnectionStatus_Connected) {
|
||||||
|
if(!appWindow.daemonSynced)
|
||||||
|
return qsTr("Synchronizing")
|
||||||
return qsTr("Connected")
|
return qsTr("Connected")
|
||||||
|
}
|
||||||
if (status == Wallet.ConnectionStatus_WrongVersion)
|
if (status == Wallet.ConnectionStatus_WrongVersion)
|
||||||
return qsTr("Wrong version")
|
return qsTr("Wrong version")
|
||||||
if (status == Wallet.ConnectionStatus_Disconnected)
|
if (status == Wallet.ConnectionStatus_Disconnected)
|
||||||
@@ -79,7 +82,7 @@ Row {
|
|||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
color: "#545454"
|
color: "#545454"
|
||||||
text: qsTr("Network status")
|
text: qsTr("Network status") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
|||||||
83
components/Notifier.qml
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
// Copyright (c) 2017, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import moneroComponents.Wallet 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: item
|
||||||
|
property string message: ""
|
||||||
|
property bool active: false
|
||||||
|
height: 120
|
||||||
|
width: 240
|
||||||
|
property int margin: 15
|
||||||
|
x: parent.width - width - margin
|
||||||
|
y: parent.height - height * scale.yScale - margin * scale.yScale
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: "#FF6C3C"
|
||||||
|
border.color: "black"
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
TextArea {
|
||||||
|
id:versionText
|
||||||
|
readOnly: true
|
||||||
|
backgroundVisible: false
|
||||||
|
textFormat: TextEdit.AutoText
|
||||||
|
anchors.fill: parent
|
||||||
|
font.family: "Arial"
|
||||||
|
font.pixelSize: 12
|
||||||
|
textMargin: 20
|
||||||
|
textColor: "white"
|
||||||
|
text: item.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transform: Scale {
|
||||||
|
id: scale
|
||||||
|
yScale: item.active ? 1 : 0
|
||||||
|
|
||||||
|
Behavior on yScale {
|
||||||
|
NumberAnimation { duration: 500; easing.type: Easing.InOutCubic }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: hider
|
||||||
|
interval: 12000; running: false; repeat: false
|
||||||
|
onTriggered: { item.active = false }
|
||||||
|
}
|
||||||
|
|
||||||
|
function show(message) {
|
||||||
|
item.visible = true
|
||||||
|
item.message = message
|
||||||
|
item.active = true
|
||||||
|
hider.running = true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,17 +52,19 @@ Window {
|
|||||||
show()
|
show()
|
||||||
}
|
}
|
||||||
|
|
||||||
function usefulName(path) {
|
|
||||||
// arbitrary "short enough" limit
|
|
||||||
if (path.length < 32)
|
|
||||||
return path
|
|
||||||
return path.replace(/.*[\/\\]/, '').replace(/\.keys$/, '')
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: implement without hardcoding sizes
|
// TODO: implement without hardcoding sizes
|
||||||
width: 480
|
width: 480
|
||||||
height: walletName ? 240 : 200
|
height: walletName ? 240 : 200
|
||||||
|
|
||||||
|
// Make window draggable
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
property point lastMousePos: Qt.point(0, 0)
|
||||||
|
onPressed: { lastMousePos = Qt.point(mouseX, mouseY); }
|
||||||
|
onMouseXChanged: root.x += (mouseX - lastMousePos.x)
|
||||||
|
onMouseYChanged: root.y += (mouseY - lastMousePos.y)
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
spacing: 10
|
spacing: 10
|
||||||
@@ -74,7 +76,7 @@ Window {
|
|||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: root.walletName.length > 0 ? qsTr("Please enter wallet password for:<br>") + usefulName(root.walletName) : qsTr("Please enter wallet password")
|
text: root.walletName.length > 0 ? qsTr("Please enter wallet password for:<br>") + root.walletName : qsTr("Please enter wallet password")
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.columnSpan: 2
|
Layout.columnSpan: 2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -107,12 +109,14 @@ Window {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Keys.onReturnPressed: {
|
Keys.onReturnPressed: {
|
||||||
root.accepted()
|
|
||||||
root.close()
|
root.close()
|
||||||
|
root.accepted()
|
||||||
|
|
||||||
}
|
}
|
||||||
Keys.onEscapePressed: {
|
Keys.onEscapePressed: {
|
||||||
root.rejected()
|
|
||||||
root.close()
|
root.close()
|
||||||
|
root.rejected()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -149,7 +153,7 @@ Window {
|
|||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
pressedColor: "#FF4304"
|
pressedColor: "#FF4304"
|
||||||
text: qsTr("Cancel")
|
text: qsTr("Cancel") + translationManager.emptyString
|
||||||
KeyNavigation.tab: passwordInput
|
KeyNavigation.tab: passwordInput
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.close()
|
root.close()
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ Item {
|
|||||||
|
|
||||||
color: {
|
color: {
|
||||||
if(item.fillLevel < 3) return "#FF6C3C"
|
if(item.fillLevel < 3) return "#FF6C3C"
|
||||||
if(item.fillLevel < 13) return "#FFE00A"
|
if(item.fillLevel < 13) return "#AAFFBB"
|
||||||
return "#36B25C"
|
return "#36B25C"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ Item {
|
|||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: row2
|
id: row2
|
||||||
spacing: ((bar.width - 8) / 2) / 4
|
spacing: bar.width / 14
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: 4
|
model: 4
|
||||||
@@ -125,7 +125,7 @@ Item {
|
|||||||
id: delegateItem2
|
id: delegateItem2
|
||||||
currentX: x + row2.x
|
currentX: x + row2.x
|
||||||
currentIndex: index
|
currentIndex: index
|
||||||
mainTick: currentIndex === 0 || currentIndex === 3 || currentIndex === 13
|
mainTick: currentIndex === 0
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
row.positions[currentIndex] = delegateItem2
|
row.positions[currentIndex] = delegateItem2
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ Item {
|
|||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: row1
|
id: row1
|
||||||
spacing: ((bar.width - 8) / 2) / 10
|
spacing: bar.width / 14
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: 10
|
model: 10
|
||||||
@@ -144,7 +144,7 @@ Item {
|
|||||||
id: delegateItem1
|
id: delegateItem1
|
||||||
currentX: x + row1.x
|
currentX: x + row1.x
|
||||||
currentIndex: index + 4
|
currentIndex: index + 4
|
||||||
mainTick: currentIndex === 0 || currentIndex === 3 || currentIndex === 13
|
mainTick: currentIndex === 13
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
row.positions[currentIndex] = delegateItem1
|
row.positions[currentIndex] = delegateItem1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ Item {
|
|||||||
|
|
||||||
color: {
|
color: {
|
||||||
if(item.fillLevel < 5) return "#FF6C3C"
|
if(item.fillLevel < 5) return "#FF6C3C"
|
||||||
if(item.fillLevel < 13) return "#FFE00A"
|
if(item.fillLevel < 13) return "#AAFFBB"
|
||||||
return "#36B25C"
|
return "#36B25C"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,34 +94,28 @@ Item {
|
|||||||
Text {
|
Text {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 11
|
font.pixelSize: 15
|
||||||
font.letterSpacing: -1
|
|
||||||
font.bold: true
|
|
||||||
color: "#000000"
|
color: "#000000"
|
||||||
x: row.x + (row.positions[0] !== undefined ? row.positions[0].currentX - 3 : 0) - width
|
x: row.x + (row.positions[0] !== undefined ? row.positions[0].currentX - 3 : 0) - width
|
||||||
text: qsTr("LOW") + translationManager.emptyString
|
text: qsTr("Low") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 11
|
font.pixelSize: 15
|
||||||
font.letterSpacing: -1
|
|
||||||
font.bold: true
|
|
||||||
color: "#000000"
|
color: "#000000"
|
||||||
x: row.x + (row.positions[4] !== undefined ? row.positions[4].currentX - 3 : 0) - width
|
x: row.x + (row.positions[4] !== undefined ? row.positions[4].currentX - 3 : 0) - width
|
||||||
text: qsTr("MEDIUM") + translationManager.emptyString
|
text: qsTr("Medium") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 11
|
font.pixelSize: 15
|
||||||
font.letterSpacing: -1
|
|
||||||
font.bold: true
|
|
||||||
color: "#000000"
|
color: "#000000"
|
||||||
x: row.x + (row.positions[13] !== undefined ? row.positions[13].currentX - 3 : 0) - width
|
x: row.x + (row.positions[13] !== undefined ? row.positions[13].currentX - 3 : 0) - width
|
||||||
text: qsTr("HIGH") + translationManager.emptyString
|
text: qsTr("High") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ Window {
|
|||||||
id: messageTitle
|
id: messageTitle
|
||||||
text: "Please wait..."
|
text: "Please wait..."
|
||||||
font {
|
font {
|
||||||
pointSize: 22
|
pixelSize: 22
|
||||||
}
|
}
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||||
@@ -72,7 +72,7 @@ Window {
|
|||||||
Text {
|
Text {
|
||||||
id: heightProgress
|
id: heightProgress
|
||||||
font {
|
font {
|
||||||
pointSize: 18
|
pixelSize: 18
|
||||||
}
|
}
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||||
|
|||||||
@@ -37,12 +37,25 @@ Item {
|
|||||||
visible: false
|
visible: false
|
||||||
//clip: true
|
//clip: true
|
||||||
|
|
||||||
function updateProgress(currentBlock,targetBlock){
|
function updateProgress(currentBlock,targetBlock, blocksToSync){
|
||||||
|
if(targetBlock == 1) {
|
||||||
|
fillLevel = 0
|
||||||
|
progressText.text = qsTr("Establishing connection...");
|
||||||
|
progressBar.visible = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if(targetBlock > 0) {
|
if(targetBlock > 0) {
|
||||||
var progressLevel = ((currentBlock/targetBlock) * 100).toFixed(0);
|
var remaining = targetBlock - currentBlock
|
||||||
|
// wallet sync
|
||||||
|
if(blocksToSync > 0)
|
||||||
|
var progressLevel = (100*(blocksToSync - remaining)/blocksToSync).toFixed(0);
|
||||||
|
// Daemon sync
|
||||||
|
else
|
||||||
|
var progressLevel = (100*(currentBlock/targetBlock)).toFixed(0);
|
||||||
fillLevel = progressLevel
|
fillLevel = progressLevel
|
||||||
progressText.text = qsTr("Synchronizing blocks %1/%2").arg(currentBlock.toFixed(0)).arg(targetBlock.toFixed(0));
|
progressText.text = qsTr("Blocks remaining: %1").arg(remaining.toFixed(0));
|
||||||
item.visible = (currentWallet.connected !== Wallet.ConnectionStatus_Disconnected) && (currentBlock < targetBlock)
|
progressBar.visible = currentBlock < targetBlock
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
141
components/QRCodeScanner.qml
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
// Copyright (c) 2014-2017, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtMultimedia 5.4
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import moneroComponents.QRCodeScanner 1.0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id : root
|
||||||
|
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
z: parent.z+1
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
color: "black"
|
||||||
|
state: "Stopped"
|
||||||
|
|
||||||
|
signal qrcode_decoded(string address, string payment_id, string amount, string tx_description, string recipient_name)
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "Capture"
|
||||||
|
StateChangeScript {
|
||||||
|
script: {
|
||||||
|
root.visible = true
|
||||||
|
camera.captureMode = Camera.CaptureStillImage
|
||||||
|
camera.start()
|
||||||
|
finder.enabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "Stopped"
|
||||||
|
StateChangeScript {
|
||||||
|
script: {
|
||||||
|
camera.stop()
|
||||||
|
root.visible = false
|
||||||
|
finder.enabled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
Camera {
|
||||||
|
id: camera
|
||||||
|
objectName: "qrCameraQML"
|
||||||
|
captureMode: Camera.CaptureStillImage
|
||||||
|
|
||||||
|
focus {
|
||||||
|
focusMode: Camera.FocusContinuous
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QRCodeScanner {
|
||||||
|
id : finder
|
||||||
|
objectName: "QrFinder"
|
||||||
|
onDecoded : {
|
||||||
|
root.qrcode_decoded(address, payment_id, amount, tx_description, recipient_name)
|
||||||
|
root.state = "Stopped"
|
||||||
|
}
|
||||||
|
onNotifyError : {
|
||||||
|
if( warning )
|
||||||
|
messageDialog.icon = StandardIcon.Critical
|
||||||
|
else {
|
||||||
|
messageDialog.icon = StandardIcon.Warning
|
||||||
|
root.state = "Stopped"
|
||||||
|
}
|
||||||
|
messageDialog.text = error
|
||||||
|
messageDialog.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoOutput {
|
||||||
|
id: viewfinder
|
||||||
|
visible: root.state == "Capture"
|
||||||
|
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
z: parent.z+1
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
source: camera
|
||||||
|
autoOrientation: true
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
propagateComposedEvents: true
|
||||||
|
onPressAndHold: {
|
||||||
|
if (camera.lockStatus == Camera.locked)camera.unlock()
|
||||||
|
camera.searchAndLock()
|
||||||
|
}
|
||||||
|
onDoubleClicked: {
|
||||||
|
root.state = "Stopped"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageDialog {
|
||||||
|
id: messageDialog
|
||||||
|
title: "Scanning QrCode"
|
||||||
|
onAccepted: {
|
||||||
|
root.state = "Stopped"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if( QtMultimedia.availableCameras.length == 0) {
|
||||||
|
console.log("No camera available. Disable qrScannerEnabled");
|
||||||
|
appWindow.qrScannerEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -100,7 +100,6 @@ Item {
|
|||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.bold: true
|
font.bold: true
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#4A4747"
|
color: "#4A4747"
|
||||||
text: "NAME"
|
text: "NAME"
|
||||||
}
|
}
|
||||||
@@ -195,7 +194,6 @@ Item {
|
|||||||
anchors.rightMargin: 12
|
anchors.rightMargin: 12
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.bold: true
|
font.bold: true
|
||||||
font.letterSpacing: -1
|
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
color: delegateArea.pressed || parent.isCurrent ? "#FFFFFF" : "#4A4646"
|
color: delegateArea.pressed || parent.isCurrent ? "#FFFFFF" : "#4A4646"
|
||||||
text: name
|
text: name
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: button
|
id: button
|
||||||
@@ -41,6 +42,8 @@ Item {
|
|||||||
property alias text: label.text
|
property alias text: label.text
|
||||||
signal clicked()
|
signal clicked()
|
||||||
|
|
||||||
|
// Dynamic label width
|
||||||
|
Layout.minimumWidth: (label.contentWidth > 80)? label.contentWidth + 20 : 100
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -78,13 +81,12 @@ Item {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
elide: Text.ElideRight
|
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.bold: true
|
font.bold: true
|
||||||
font.letterSpacing: -1
|
|
||||||
font.pixelSize: button.fontSize
|
font.pixelSize: button.fontSize
|
||||||
color: parent.textColor
|
color: parent.textColor
|
||||||
visible: parent.icon === ""
|
visible: parent.icon === ""
|
||||||
|
// font.capitalization : Font.Capitalize
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
|||||||
@@ -45,12 +45,23 @@ Window {
|
|||||||
property alias cancelVisible: cancelButton.visible
|
property alias cancelVisible: cancelButton.visible
|
||||||
property alias okVisible: okButton.visible
|
property alias okVisible: okButton.visible
|
||||||
property alias textArea: dialogContent
|
property alias textArea: dialogContent
|
||||||
|
property alias okText: okButton.text
|
||||||
|
property alias cancelText: cancelButton.text
|
||||||
|
|
||||||
property var icon
|
property var icon
|
||||||
|
|
||||||
// same signals as Dialog has
|
// same signals as Dialog has
|
||||||
signal accepted()
|
signal accepted()
|
||||||
signal rejected()
|
signal rejected()
|
||||||
|
|
||||||
|
// Make window draggable
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
property point lastMousePos: Qt.point(0, 0)
|
||||||
|
onPressed: { lastMousePos = Qt.point(mouseX, mouseY); }
|
||||||
|
onMouseXChanged: root.x += (mouseX - lastMousePos.x)
|
||||||
|
onMouseYChanged: root.y += (mouseY - lastMousePos.y)
|
||||||
|
}
|
||||||
|
|
||||||
function open() {
|
function open() {
|
||||||
show()
|
show()
|
||||||
@@ -98,6 +109,21 @@ Window {
|
|||||||
spacing: 60
|
spacing: 60
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
id: cancelButton
|
||||||
|
width: 120
|
||||||
|
fontSize: 14
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
text: qsTr("Cancel") + translationManager.emptyString
|
||||||
|
onClicked: {
|
||||||
|
root.close()
|
||||||
|
root.rejected()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
MoneroComponents.StandardButton {
|
||||||
id: okButton
|
id: okButton
|
||||||
width: 120
|
width: 120
|
||||||
@@ -114,21 +140,6 @@ Window {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
|
||||||
id: cancelButton
|
|
||||||
width: 120
|
|
||||||
fontSize: 14
|
|
||||||
shadowReleasedColor: "#FF4304"
|
|
||||||
shadowPressedColor: "#B32D00"
|
|
||||||
releasedColor: "#FF6C3C"
|
|
||||||
pressedColor: "#FF4304"
|
|
||||||
text: qsTr("Cancel")
|
|
||||||
onClicked: {
|
|
||||||
root.close()
|
|
||||||
root.rejected()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ Item {
|
|||||||
font.bold: true
|
font.bold: true
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
color: "#FFFFFF"
|
color: "#FFFFFF"
|
||||||
text: repeater.model.get(column.currentIndex).column1
|
text: column.currentIndex < repeater.model.rowCount() ? qsTr(repeater.model.get(column.currentIndex).column1) + translationManager.emptyString : ""
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
@@ -119,7 +119,7 @@ Item {
|
|||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
color: "#FFFFFF"
|
color: "#FFFFFF"
|
||||||
text: repeater.model.get(column.currentIndex).column2
|
text: column.currentIndex < repeater.model.rowCount() ? qsTr(repeater.model.get(column.currentIndex).column2) + translationManager.emptyString : ""
|
||||||
|
|
||||||
property int w: 0
|
property int w: 0
|
||||||
Component.onCompleted: w = implicitWidth
|
Component.onCompleted: w = implicitWidth
|
||||||
@@ -193,6 +193,19 @@ Item {
|
|||||||
Repeater {
|
Repeater {
|
||||||
id: repeater
|
id: repeater
|
||||||
|
|
||||||
|
// Workaround for translations in listElements. All translated strings needs to be listed in this file.
|
||||||
|
property string stringLow: qsTr("Low (x1 fee)") + translationManager.emptyString
|
||||||
|
property string stringMedium: qsTr("Medium (x20 fee)") + translationManager.emptyString
|
||||||
|
property string stringHigh: qsTr("High (x166 fee)") + translationManager.emptyString
|
||||||
|
property string stringSlow: qsTr("Slow (x0.25 fee)") + translationManager.emptyString
|
||||||
|
property string stringDefault: qsTr("Default (x1 fee)") + translationManager.emptyString
|
||||||
|
property string stringFast: qsTr("Fast (x5 fee)") + translationManager.emptyString
|
||||||
|
property string stringFastest: qsTr("Fastest (x41.5 fee)") + translationManager.emptyString
|
||||||
|
property string stringAll: qsTr("All") + translationManager.emptyString
|
||||||
|
property string stringSent: qsTr("Sent") + translationManager.emptyString
|
||||||
|
property string stringReceived: qsTr("Received") + translationManager.emptyString
|
||||||
|
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -210,7 +223,7 @@ Item {
|
|||||||
font.bold: true
|
font.bold: true
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
color: "#FFFFFF"
|
color: "#FFFFFF"
|
||||||
text: column1
|
text: qsTr(column1) + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
|||||||
@@ -177,6 +177,13 @@ Item {
|
|||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: repeater
|
id: repeater
|
||||||
|
|
||||||
|
// Workaround for translations in listElements. All translated strings needs to be listed in this file.
|
||||||
|
property string stringCopy: qsTr("<b>Copy address to clipboard</b>") + translationManager.emptyString
|
||||||
|
property string stringSend: qsTr("<b>Send to this address</b>") + translationManager.emptyString
|
||||||
|
property string stringFind: qsTr("<b>Find similar transactions</b>") + translationManager.emptyString
|
||||||
|
property string stringRemove: qsTr("<b>Remove from address book</b>") + translationManager.emptyString
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
id: delegate
|
id: delegate
|
||||||
property bool containsMouse: index === mouseArea.currentIndex
|
property bool containsMouse: index === mouseArea.currentIndex
|
||||||
@@ -211,7 +218,7 @@ Item {
|
|||||||
onContainsMouseChanged: {
|
onContainsMouseChanged: {
|
||||||
if(containsMouse) {
|
if(containsMouse) {
|
||||||
var pos = rootItem.mapFromItem(delegate, 30, -25)
|
var pos = rootItem.mapFromItem(delegate, 30, -25)
|
||||||
appWindow.toolTip.text = name
|
appWindow.toolTip.text = qsTr(name) + translationManager.emptyString
|
||||||
appWindow.toolTip.x = pos.x - appWindow.toolTip.width
|
appWindow.toolTip.x = pos.x - appWindow.toolTip.width
|
||||||
// if(appWindow.toolTip.height > 30)
|
// if(appWindow.toolTip.height > 30)
|
||||||
// pos.y -= appWindow.toolTip.height - 30
|
// pos.y -= appWindow.toolTip.height - 30
|
||||||
|
|||||||
@@ -60,6 +60,13 @@ Rectangle {
|
|||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: columnsRepeater
|
id: columnsRepeater
|
||||||
|
|
||||||
|
// Workaround for translations in listElements. All translated strings needs to be listed in this file.
|
||||||
|
property string stringPaymentID: qsTr("Payment ID") + translationManager.emptyString
|
||||||
|
property string stringDate: qsTr("Date") + translationManager.emptyString
|
||||||
|
property string stringBlockHeight: qsTr("Block height") + translationManager.emptyString
|
||||||
|
property string stringAmount: qsTr("Amount") + translationManager.emptyString
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
id: delegate
|
id: delegate
|
||||||
property bool desc: false
|
property bool desc: false
|
||||||
@@ -81,7 +88,7 @@ Rectangle {
|
|||||||
return "#FF4304"
|
return "#FF4304"
|
||||||
return index === header.activeSortColumn || delegateArea.containsMouse ? "#FF6C3C" : "#4A4949"
|
return index === header.activeSortColumn || delegateArea.containsMouse ? "#FF6C3C" : "#4A4949"
|
||||||
}
|
}
|
||||||
text: columnName
|
text: qsTr(columnName) + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|||||||
7
components/TextBlock.qml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
TextEdit {
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
readOnly: true
|
||||||
|
selectByMouse: true
|
||||||
|
}
|
||||||
@@ -52,9 +52,8 @@ Item {
|
|||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
color: "#4A4949"
|
color: "#4A4949"
|
||||||
text: {
|
text: {
|
||||||
if(currentIndex === 0) return qsTr("LOW") + translationManager.emptyString
|
if(currentIndex === 0) return qsTr("Normal") + translationManager.emptyString
|
||||||
if(currentIndex === 3) return qsTr("MEDIUM") + translationManager.emptyString
|
if(currentIndex === 13) return qsTr("High") + translationManager.emptyString
|
||||||
if(currentIndex === 13) return qsTr("HIGH") + translationManager.emptyString
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +64,7 @@ Item {
|
|||||||
anchors.topMargin: 14
|
anchors.topMargin: 14
|
||||||
width: 1
|
width: 1
|
||||||
color: "#DBDBDB"
|
color: "#DBDBDB"
|
||||||
height: currentIndex === 8 ? 16 : 8
|
height: 8
|
||||||
visible: !parent.mainTick
|
visible: !parent.mainTick
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ Window {
|
|||||||
lineHeight: 0.7
|
lineHeight: 0.7
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#FFFFFF"
|
color: "#FFFFFF"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,43 +41,42 @@ Rectangle {
|
|||||||
y: -height
|
y: -height
|
||||||
property string title
|
property string title
|
||||||
property alias maximizeButtonVisible: maximizeButton.visible
|
property alias maximizeButtonVisible: maximizeButton.visible
|
||||||
|
z: 1
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
font.family: "Arial"
|
font.family: "Arial"
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
font.letterSpacing: -1
|
|
||||||
color: "#FFFFFF"
|
color: "#FFFFFF"
|
||||||
text: titleBar.title
|
text: titleBar.title
|
||||||
visible: customDecorations
|
visible: customDecorations
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on y {
|
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: goToBasicVersionButton
|
id: goToBasicVersionButton
|
||||||
property bool containsMouse: titleBar.mouseX >= x && titleBar.mouseX <= x + width
|
property bool containsMouse: titleBar.mouseX >= x && titleBar.mouseX <= x + width
|
||||||
property bool checked: false
|
property bool checked: false
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
color: containsMouse || checked ? "#FFE00A" : "#000000"
|
color: basicMouseArea.containsMouse || !leftPanel.visible ? "#FFE00A" : "#000000"
|
||||||
height: 30
|
height: 30
|
||||||
width: height
|
width: height
|
||||||
|
visible: isMobile
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
rotation: parent.checked ? 180 : 0
|
rotation: !leftPanel.visible ? 180 : 0
|
||||||
source: parent.containsMouse || parent.checked ? "../images/goToBasicVersionHovered.png" :
|
source: parent.customDecorations || !leftPanel.visible ? "../images/goToBasicVersionHovered.png" :
|
||||||
"../images/gotoBasicVersion.png"
|
"../images/gotoBasicVersion.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
id: basicMouseArea
|
||||||
|
hoverEnabled: true
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
parent.checked = !parent.checked
|
parent.checked = !parent.checked
|
||||||
titleBar.goToBasicVersion(parent.checked)
|
titleBar.goToBasicVersion(leftPanel.visible)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,121 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
MONERO_URL=https://github.com/monero-project/monero.git
|
MONERO_URL=https://github.com/monero-project/monero.git
|
||||||
MONERO_BRANCH=master
|
MONERO_BRANCH=master
|
||||||
# MONERO_URL=https://github.com/mbg033/monero.git
|
|
||||||
# MONERO_BRANCH=develop
|
|
||||||
# Buidling "debug" build optionally
|
|
||||||
BUILD_TYPE=$1
|
|
||||||
if [ -z $BUILD_TYPE ]; then
|
|
||||||
BUILD_TYPE=Release
|
|
||||||
fi
|
|
||||||
# thanks to SO: http://stackoverflow.com/a/20283965/4118915
|
|
||||||
if test -z "$CPU_CORE_COUNT"; then
|
|
||||||
CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu)
|
|
||||||
fi
|
|
||||||
pushd $(pwd)
|
pushd $(pwd)
|
||||||
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
source $ROOT_DIR/utils.sh
|
source $ROOT_DIR/utils.sh
|
||||||
|
|
||||||
|
|
||||||
INSTALL_DIR=$ROOT_DIR/wallet
|
INSTALL_DIR=$ROOT_DIR/wallet
|
||||||
MONERO_DIR=$ROOT_DIR/monero
|
MONERO_DIR=$ROOT_DIR/monero
|
||||||
|
BUILD_LIBWALLET=false
|
||||||
|
|
||||||
|
# init and update monero submodule
|
||||||
|
if [ ! -d $MONERO_DIR/src ]; then
|
||||||
|
git submodule init monero
|
||||||
|
fi
|
||||||
|
git submodule update --remote
|
||||||
|
git -C $MONERO_DIR fetch
|
||||||
|
git -C $MONERO_DIR checkout release-v0.11.0.0
|
||||||
|
|
||||||
if [ ! -d $MONERO_DIR ]; then
|
# get monero core tag
|
||||||
git clone --depth=1 $MONERO_URL $MONERO_DIR --branch $MONERO_BRANCH --single-branch
|
get_tag
|
||||||
|
# create local monero branch
|
||||||
|
git -C $MONERO_DIR checkout -B $VERSIONTAG
|
||||||
|
|
||||||
|
# Merge monero PR dependencies
|
||||||
|
|
||||||
|
# Workaround for git username requirements
|
||||||
|
# Save current user settings and revert back when we are done with merging PR's
|
||||||
|
OLD_GIT_USER=$(git -C $MONERO_DIR config --local user.name)
|
||||||
|
OLD_GIT_EMAIL=$(git -C $MONERO_DIR config --local user.email)
|
||||||
|
git -C $MONERO_DIR config user.name "Monero GUI"
|
||||||
|
git -C $MONERO_DIR config user.email "gui@monero.local"
|
||||||
|
# check for PR requirements in most recent commit message (i.e requires #xxxx)
|
||||||
|
for PR in $(git log --format=%B -n 1 | grep -io "requires #[0-9]*" | sed 's/[^0-9]*//g'); do
|
||||||
|
echo "Merging monero push request #$PR"
|
||||||
|
# fetch pull request and merge
|
||||||
|
git -C $MONERO_DIR fetch origin pull/$PR/head:PR-$PR
|
||||||
|
git -C $MONERO_DIR merge --quiet PR-$PR -m "Merge monero PR #$PR"
|
||||||
|
BUILD_LIBWALLET=true
|
||||||
|
done
|
||||||
|
|
||||||
|
# revert back to old git config
|
||||||
|
$(git -C $MONERO_DIR config user.name "$OLD_GIT_USER")
|
||||||
|
$(git -C $MONERO_DIR config user.email "$OLD_GIT_EMAIL")
|
||||||
|
|
||||||
|
# Build libwallet if it doesnt exist
|
||||||
|
if [ ! -f $MONERO_DIR/lib/libwallet_merged.a ]; then
|
||||||
|
echo "libwallet_merged.a not found - Building libwallet"
|
||||||
|
BUILD_LIBWALLET=true
|
||||||
|
# Build libwallet if no previous version file exists
|
||||||
|
elif [ ! -f $MONERO_DIR/version.sh ]; then
|
||||||
|
echo "monero/version.h not found - Building libwallet"
|
||||||
|
BUILD_LIBWALLET=true
|
||||||
|
## Compare previously built version with submodule + merged PR's version.
|
||||||
else
|
else
|
||||||
cd $MONERO_DIR;
|
source $MONERO_DIR/version.sh
|
||||||
git checkout $MONERO_BRANCH
|
# compare submodule version with latest build
|
||||||
git pull;
|
pushd "$MONERO_DIR"
|
||||||
|
get_tag
|
||||||
|
popd
|
||||||
|
echo "latest libwallet version: $GUI_MONERO_VERSION"
|
||||||
|
echo "Installed libwallet version: $VERSIONTAG"
|
||||||
|
# check if recent
|
||||||
|
if [ "$VERSIONTAG" != "$GUI_MONERO_VERSION" ]; then
|
||||||
|
echo "Building new libwallet version $GUI_MONERO_VERSION"
|
||||||
|
BUILD_LIBWALLET=true
|
||||||
|
else
|
||||||
|
echo "latest libwallet ($GUI_MONERO_VERSION) is already built. Remove monero/lib/libwallet_merged.a to force rebuild"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$BUILD_LIBWALLET" != true ]; then
|
||||||
|
# exit this script
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "GUI_MONERO_VERSION=\"$VERSIONTAG\"" > $MONERO_DIR/version.sh
|
||||||
|
|
||||||
|
## Continue building libwallet
|
||||||
|
|
||||||
|
# default build type
|
||||||
|
BUILD_TYPE=$1
|
||||||
|
if [ -z $BUILD_TYPE ]; then
|
||||||
|
BUILD_TYPE=release
|
||||||
|
fi
|
||||||
|
|
||||||
|
STATIC=false
|
||||||
|
ANDROID=false
|
||||||
|
if [ "$BUILD_TYPE" == "release" ]; then
|
||||||
|
echo "Building libwallet release"
|
||||||
|
CMAKE_BUILD_TYPE=Release
|
||||||
|
elif [ "$BUILD_TYPE" == "release-static" ]; then
|
||||||
|
echo "Building libwallet release-static"
|
||||||
|
CMAKE_BUILD_TYPE=Release
|
||||||
|
STATIC=true
|
||||||
|
elif [ "$BUILD_TYPE" == "release-android" ]; then
|
||||||
|
echo "Building libwallet release-static for ANDROID"
|
||||||
|
CMAKE_BUILD_TYPE=Release
|
||||||
|
STATIC=true
|
||||||
|
ANDROID=true
|
||||||
|
elif [ "$BUILD_TYPE" == "debug-android" ]; then
|
||||||
|
echo "Building libwallet debug-static for ANDROID"
|
||||||
|
CMAKE_BUILD_TYPE=Debug
|
||||||
|
STATIC=true
|
||||||
|
ANDROID=true
|
||||||
|
elif [ "$BUILD_TYPE" == "debug" ]; then
|
||||||
|
echo "Building libwallet debug"
|
||||||
|
CMAKE_BUILD_TYPE=Debug
|
||||||
|
else
|
||||||
|
echo "Valid build types are release, release-static, release-android, debug-android and debug"
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo "cleaning up existing monero build dir, libs and includes"
|
echo "cleaning up existing monero build dir, libs and includes"
|
||||||
rm -fr $MONERO_DIR/build
|
#rm -fr $MONERO_DIR/build
|
||||||
rm -fr $MONERO_DIR/lib
|
rm -fr $MONERO_DIR/lib
|
||||||
rm -fr $MONERO_DIR/include
|
rm -fr $MONERO_DIR/include
|
||||||
rm -fr $MONERO_DIR/bin
|
rm -fr $MONERO_DIR/bin
|
||||||
@@ -46,38 +128,84 @@ pushd $MONERO_DIR/build/release
|
|||||||
platform=$(get_platform)
|
platform=$(get_platform)
|
||||||
# default make executable
|
# default make executable
|
||||||
make_exec="make"
|
make_exec="make"
|
||||||
|
|
||||||
|
## OS X
|
||||||
if [ "$platform" == "darwin" ]; then
|
if [ "$platform" == "darwin" ]; then
|
||||||
# Do something under Mac OS X platform
|
|
||||||
echo "Configuring build for MacOS.."
|
echo "Configuring build for MacOS.."
|
||||||
cmake -D CMAKE_BUILD_TYPE=$BUILD_TYPE -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
if [ "$STATIC" == true ]; then
|
||||||
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
else
|
||||||
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
fi
|
||||||
|
|
||||||
|
## LINUX 64
|
||||||
elif [ "$platform" == "linux64" ]; then
|
elif [ "$platform" == "linux64" ]; then
|
||||||
# Do something under GNU/Linux platform
|
|
||||||
echo "Configuring build for Linux x64"
|
echo "Configuring build for Linux x64"
|
||||||
cmake -D CMAKE_BUILD_TYPE=$BUILD_TYPE -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D BUILD_GUI_DEPS=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
if [ "$ANDROID" == true ]; then
|
||||||
|
echo "Configuring build for Android on Linux host"
|
||||||
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="armv7-a" -D ANDROID=true -D BUILD_GUI_DEPS=ON -D USE_LTO=OFF -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
elif [ "$STATIC" == true ]; then
|
||||||
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
else
|
||||||
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_GUI_DEPS=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
fi
|
||||||
|
|
||||||
|
## LINUX 32
|
||||||
elif [ "$platform" == "linux32" ]; then
|
elif [ "$platform" == "linux32" ]; then
|
||||||
# Do something under GNU/Linux platform
|
|
||||||
echo "Configuring build for Linux i686"
|
echo "Configuring build for Linux i686"
|
||||||
cmake -D CMAKE_BUILD_TYPE=$BUILD_TYPE -D STATIC=ON -D ARCH="i686" -D BUILD_64=OFF -D BUILD_GUI_DEPS=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
if [ "$STATIC" == true ]; then
|
||||||
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="i686" -D BUILD_64=OFF -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
else
|
||||||
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_GUI_DEPS=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
fi
|
||||||
|
|
||||||
|
## LINUX ARMv7
|
||||||
|
elif [ "$platform" == "linuxarmv7" ]; then
|
||||||
|
echo "Configuring build for Linux armv7"
|
||||||
|
if [ "$STATIC" == true ]; then
|
||||||
|
cmake -D BUILD_TESTS=OFF -D ARCH="armv7-a" -D STATIC=ON -D BUILD_64=OFF -D BUILD_GUI_DEPS=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
else
|
||||||
|
cmake -D BUILD_TESTS=OFF -D ARCH="armv7-a" -D -D BUILD_64=OFF -D BUILD_GUI_DEPS=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
fi
|
||||||
|
|
||||||
|
## LINUX other
|
||||||
elif [ "$platform" == "linux" ]; then
|
elif [ "$platform" == "linux" ]; then
|
||||||
echo "Configuring build for Linux general"
|
echo "Configuring build for Linux general"
|
||||||
cmake -D CMAKE_BUILD_TYPE=$BUILD_TYPE -D STATIC=ON -D BUILD_GUI_DEPS=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
if [ "$STATIC" == true ]; then
|
||||||
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
else
|
||||||
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_GUI_DEPS=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
fi
|
||||||
|
|
||||||
|
## Windows 64
|
||||||
|
## Windows is always static to work outside msys2
|
||||||
elif [ "$platform" == "mingw64" ]; then
|
elif [ "$platform" == "mingw64" ]; then
|
||||||
# Do something under Windows NT platform
|
# Do something under Windows NT platform
|
||||||
echo "Configuring build for MINGW64.."
|
echo "Configuring build for MINGW64.."
|
||||||
BOOST_ROOT=/mingw64/boost
|
BOOST_ROOT=/mingw64/boost
|
||||||
cmake -D CMAKE_BUILD_TYPE=$BUILD_TYPE -D STATIC=ON -D BOOST_ROOT="$BOOST_ROOT" -D ARCH="x86-64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D BOOST_ROOT="$BOOST_ROOT" -D ARCH="x86-64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" ../..
|
||||||
|
|
||||||
|
## Windows 32
|
||||||
elif [ "$platform" == "mingw32" ]; then
|
elif [ "$platform" == "mingw32" ]; then
|
||||||
# Do something under Windows NT platform
|
# Do something under Windows NT platform
|
||||||
echo "Configuring build for MINGW32.."
|
echo "Configuring build for MINGW32.."
|
||||||
BOOST_ROOT=/mingw32/boost
|
BOOST_ROOT=/mingw32/boost
|
||||||
cmake -D CMAKE_BUILD_TYPE=$BUILD_TYPE -D STATIC=ON -D Boost_DEBUG=ON -D BOOST_ROOT="$BOOST_ROOT" -D ARCH="i686" -D BUILD_64=OFF -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D Boost_DEBUG=ON -D BOOST_ROOT="$BOOST_ROOT" -D ARCH="i686" -D BUILD_64=OFF -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" ../..
|
||||||
make_exec="mingw32-make"
|
make_exec="mingw32-make"
|
||||||
else
|
else
|
||||||
echo "Unsupported platform: $platform"
|
echo "Unknown platform, configuring general build"
|
||||||
popd
|
if [ "$STATIC" == true ]; then
|
||||||
exit 1
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D BUILD_GUI_DEPS=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
else
|
||||||
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_GUI_DEPS=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# set CPU core count
|
||||||
|
# thanks to SO: http://stackoverflow.com/a/20283965/4118915
|
||||||
|
if test -z "$CPU_CORE_COUNT"; then
|
||||||
|
CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu)
|
||||||
|
fi
|
||||||
|
|
||||||
# Build libwallet_merged
|
# Build libwallet_merged
|
||||||
pushd $MONERO_DIR/build/release/src/wallet
|
pushd $MONERO_DIR/build/release/src/wallet
|
||||||
@@ -88,25 +216,26 @@ popd
|
|||||||
|
|
||||||
# Build monerod
|
# Build monerod
|
||||||
# win32 need to build daemon manually with msys2 toolchain
|
# win32 need to build daemon manually with msys2 toolchain
|
||||||
if [ "$platform" != "mingw32" ]; then
|
if [ "$platform" != "mingw32" ] && [ "$ANDROID" != true ]; then
|
||||||
pushd $MONERO_DIR/build/release/src/daemon
|
pushd $MONERO_DIR/build/release/src/daemon
|
||||||
eval make -j$CPU_CORE_COUNT
|
eval make -j$CPU_CORE_COUNT
|
||||||
eval make install -j$CPU_CORE_COUNT
|
eval make install -j$CPU_CORE_COUNT
|
||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# build install epee
|
||||||
|
eval make -C $MONERO_DIR/build/release/contrib/epee all install
|
||||||
|
|
||||||
# unbound is one more dependency. can't be merged to the wallet_merged
|
# install easylogging
|
||||||
# since filename conflict (random.c.obj)
|
eval make -C $MONERO_DIR/build/release/external/easylogging++ all install
|
||||||
# for Linux, we use libunbound shipped with the system, so we don't need to build it
|
|
||||||
|
# Install libunwind
|
||||||
|
echo "Installing libunbound..."
|
||||||
|
pushd $MONERO_DIR/build/release/external/unbound
|
||||||
|
# no need to make, it was already built as dependency for libwallet
|
||||||
|
# make -j$CPU_CORE_COUNT
|
||||||
|
$make_exec install -j$CPU_CORE_COUNT
|
||||||
|
popd
|
||||||
|
|
||||||
if [ "$platform" != "linux32" ] && [ "$platform" != "linux64" ]; then
|
|
||||||
echo "Building libunbound..."
|
|
||||||
pushd $MONERO_DIR/build/release/external/unbound
|
|
||||||
# no need to make, it was already built as dependency for libwallet
|
|
||||||
# make -j$CPU_CORE_COUNT
|
|
||||||
$make_exec install -j$CPU_CORE_COUNT
|
|
||||||
popd
|
|
||||||
fi
|
|
||||||
|
|
||||||
popd
|
popd
|
||||||
5
installers/windows/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# The subdirectory with the individual GUI Wallet files
|
||||||
|
bin/
|
||||||
|
|
||||||
|
# The subdirectory with the generated installer "mysetup.exe"
|
||||||
|
Output/
|
||||||
BIN
installers/windows/FinishImage.bmp
Normal file
|
After Width: | Height: | Size: 151 KiB |
31
installers/windows/LICENSE
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
Copyright (c) 2014-2017, The Monero Project
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
Parts of the project are originally copyright (c) 2012-2013 The Cryptonote
|
||||||
|
developers
|
||||||
371
installers/windows/Monero.iss
Normal file
@@ -0,0 +1,371 @@
|
|||||||
|
; Monero Helium Hydra GUI Wallet Installer for Windows
|
||||||
|
; Copyright (c) 2014-2017, The Monero Project
|
||||||
|
; See LICENSE
|
||||||
|
|
||||||
|
[Setup]
|
||||||
|
AppName=Monero GUI Wallet
|
||||||
|
; For InnoSetup this is the property that uniquely identifies the application as such
|
||||||
|
; Thus it's important to keep this stable over releases
|
||||||
|
; With a different "AppName" InnoSetup would treat a mere update as a completely new application and thus mess up
|
||||||
|
|
||||||
|
AppVersion=0.11.1.0
|
||||||
|
DefaultDirName={pf}\Monero GUI Wallet
|
||||||
|
DefaultGroupName=Monero GUI Wallet
|
||||||
|
UninstallDisplayIcon={app}\monero-wallet-gui.exe
|
||||||
|
PrivilegesRequired=admin
|
||||||
|
ArchitecturesInstallIn64BitMode=x64
|
||||||
|
ArchitecturesAllowed=x64
|
||||||
|
WizardSmallImageFile=WizardSmallImage.bmp
|
||||||
|
WizardImageFile=WelcomeImage.bmp
|
||||||
|
DisableWelcomePage=no
|
||||||
|
LicenseFile=LICENSE
|
||||||
|
|
||||||
|
|
||||||
|
[Languages]
|
||||||
|
Name: "en"; MessagesFile: "compiler:Default.isl"
|
||||||
|
; Without localized versions of special forms, messages etc. of the installer, and without translated ReadMe's
|
||||||
|
; it probably does not make much sense to offer other install-time languages beside English
|
||||||
|
; Name: "fr"; MessagesFile: "compiler:Languages\French.isl"
|
||||||
|
; Name: "it"; MessagesFile: "compiler:Languages\Italian.isl"
|
||||||
|
; Name: "jp"; MessagesFile: "compiler:Languages\Japanese.isl"
|
||||||
|
; Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"
|
||||||
|
; Name: "pt"; MessagesFile: "compiler:Languages\Portuguese.isl"
|
||||||
|
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Source: "ReadMe.htm"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "FinishImage.bmp"; Flags: dontcopy
|
||||||
|
|
||||||
|
; Monero GUI wallet
|
||||||
|
Source: "bin\monero-wallet-gui.exe"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Monero GUI wallet log file
|
||||||
|
; The GUI wallet does not have the "--log-file" command-line option of the CLI wallet and insists to put the .log beside the .exe
|
||||||
|
; so pre-create the file and give the necessary permissions to the wallet to write into it
|
||||||
|
Source: "monero-wallet-gui.log"; DestDir: "{app}"; Flags: comparetimestamp; Permissions: users-modify
|
||||||
|
|
||||||
|
; Monero CLI wallet
|
||||||
|
Source: "bin\monero-wallet-cli.exe"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Monero wallet RPC interface implementation
|
||||||
|
Source: "bin\monero-wallet-rpc.exe"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Monero daemon
|
||||||
|
Source: "bin\monerod.exe"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Monero daemon wrapped in a batch file that stops before the text window closes, to see any error messages
|
||||||
|
Source: "monero-daemon.bat"; DestDir: "{app}"; Flags: comparetimestamp;
|
||||||
|
|
||||||
|
; Monero blockchain utilities
|
||||||
|
Source: "bin\monero-blockchain-export.exe"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\monero-blockchain-import.exe"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; was present in 0.10.3.1, not present anymore in 0.11.1.0
|
||||||
|
; Source: "bin\monero-utils-deserialize.exe"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Various .qm files for translating the wallet UI "on the fly" into all supported languages
|
||||||
|
Source: "bin\translations\*"; DestDir: "{app}\translations"; Flags: recursesubdirs comparetimestamp
|
||||||
|
|
||||||
|
; Core Qt runtime
|
||||||
|
Source: "bin\Qt5Core.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\Qt5Gui.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\Qt5Multimedia.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\Qt5MultimediaQuick_p.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\Qt5Network.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\Qt5Qml.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\Qt5Quick.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\Qt5Svg.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\Qt5Widgets.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\Qt5XmlPatterns.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Qt QML elements like the local files selector "FolderListModel" and "Settings"
|
||||||
|
Source: "bin\Qt\*"; DestDir: "{app}\Qt"; Flags: recursesubdirs comparetimestamp
|
||||||
|
|
||||||
|
; Qt audio support
|
||||||
|
Source: "bin\audio\*"; DestDir: "{app}\audio"; Flags: recursesubdirs comparetimestamp
|
||||||
|
|
||||||
|
; Qt bearer / network connection management
|
||||||
|
Source: "bin\bearer\*"; DestDir: "{app}\bearer"; Flags: recursesubdirs comparetimestamp
|
||||||
|
|
||||||
|
; Qt Windows platform plugin
|
||||||
|
Source: "bin\platforms\qwindows.dll"; DestDir: "{app}\platforms"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Qt support for SVG icons
|
||||||
|
Source: "bin\iconengines\*"; DestDir: "{app}\iconengines"; Flags: recursesubdirs comparetimestamp
|
||||||
|
|
||||||
|
; Qt support for various image formats (JPEG, BMP, SVG etc)
|
||||||
|
Source: "bin\imageformats\*"; DestDir: "{app}\imageformats"; Flags: recursesubdirs comparetimestamp
|
||||||
|
|
||||||
|
; Qt multimedia support
|
||||||
|
Source: "bin\QtMultimedia\*"; DestDir: "{app}\QtMultimedia"; Flags: recursesubdirs comparetimestamp
|
||||||
|
Source: "bin\mediaservice\*"; DestDir: "{app}\mediaservice"; Flags: recursesubdirs comparetimestamp
|
||||||
|
|
||||||
|
; Qt support for "m3u" playlists
|
||||||
|
; candidate for elimination? Don't think the GUI wallet needs such playlists
|
||||||
|
Source: "bin\playlistformats\*"; DestDir: "{app}\playlistformats"; Flags: recursesubdirs comparetimestamp
|
||||||
|
|
||||||
|
; Qt graphical effects as part of the core runtime, effects like blurring and blending
|
||||||
|
Source: "bin\QtGraphicalEffects\*"; DestDir: "{app}\QtGraphicalEffects"; Flags: recursesubdirs comparetimestamp
|
||||||
|
|
||||||
|
; Some more Qt graphical effects
|
||||||
|
; "private" as a name for this directory looks a little strange. Historical reasons?
|
||||||
|
Source: "bin\private\*"; DestDir: "{app}\private"; Flags: recursesubdirs comparetimestamp
|
||||||
|
|
||||||
|
; Qt QML files
|
||||||
|
Source: "bin\QtQml\*"; DestDir: "{app}\QtQml"; Flags: recursesubdirs comparetimestamp
|
||||||
|
|
||||||
|
; Qt Quick files
|
||||||
|
Source: "bin\QtQuick\*"; DestDir: "{app}\QtQuick"; Flags: recursesubdirs comparetimestamp
|
||||||
|
Source: "bin\QtQuick.2\*"; DestDir: "{app}\QtQuick.2"; Flags: recursesubdirs comparetimestamp
|
||||||
|
|
||||||
|
; Qt Quick 2D Renderer fallback for systems / environments with "low-level graphics" i.e. without 3D support
|
||||||
|
Source: "bin\scenegraph\*"; DestDir: "{app}\scenegraph"; Flags: recursesubdirs comparetimestamp
|
||||||
|
Source: "bin\start-low-graphics-mode.bat"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Mesa, open-source OpenGL implementation; part of "low-level graphics" support
|
||||||
|
Source: "bin\opengl32sw.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Left out subdirectory "qmltooling" with the Qt QML debugger: Probably not relevant in an end-user package
|
||||||
|
|
||||||
|
; Microsoft Direct3D runtime
|
||||||
|
Source: "bin\D3Dcompiler_47.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; bzip2 support
|
||||||
|
Source: "bin\libbz2-1.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; ANGLE ("Almost Native Graphics Layer Engine") support, as used by Qt
|
||||||
|
Source: "bin\libEGL.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\libGLESV2.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; FreeType font engine, as used by Qt
|
||||||
|
Source: "bin\libfreetype-6.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; GCC runtime, x64 version
|
||||||
|
Source: "bin\libgcc_s_seh-1.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; GLib, low level core library e.g. for GNOME and GTK+
|
||||||
|
; Really needed under Windows?
|
||||||
|
Source: "bin\libglib-2.0-0.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Graphite font support
|
||||||
|
; Really needed?
|
||||||
|
Source: "bin\libgraphite2.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; HarfBuzz OpenType text shaping engine
|
||||||
|
; Really needed?
|
||||||
|
Source: "bin\libharfbuzz-0.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; LibIconv, conversions between character encodings
|
||||||
|
Source: "bin\libiconv-2.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Part of cygwin? Needed by Qt somehow?
|
||||||
|
Source: "bin\libicudt57.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\libicuin57.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\libicuuc57.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Library for native language support, part of GNU gettext
|
||||||
|
Source: "bin\libintl-8.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; JasPer, support for JPEG-2000
|
||||||
|
; was present in 0.10.3.1, not present anymore in 0.11.1.0
|
||||||
|
; Source: "bin\libjasper-1.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; libjpeg, C library for reading and writing JPEG image files
|
||||||
|
Source: "bin\libjpeg-8.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; Little CMS, color management system
|
||||||
|
Source: "bin\liblcms2-2.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; XZ Utils, LZMA compression library
|
||||||
|
Source: "bin\liblzma-5.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; MNG / Portable Network Graphics ("animated PNG")
|
||||||
|
Source: "bin\libmng-2.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; PCRE, Perl Compatible Regular Expressions
|
||||||
|
Source: "bin\libpcre-1.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
Source: "bin\libpcre16-0.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; libpng, the official PNG reference library
|
||||||
|
Source: "bin\libpng16-16.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; libstdc++, GNU Standard C++ Library
|
||||||
|
Source: "bin\libstdc++-6.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; LibTIFF, TIFF Library and Utilities
|
||||||
|
Source: "bin\libtiff-5.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; C++ threading support
|
||||||
|
Source: "bin\libwinpthread-1.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
; zlib compression library
|
||||||
|
Source: "bin\zlib1.dll"; DestDir: "{app}"; Flags: comparetimestamp
|
||||||
|
|
||||||
|
|
||||||
|
[Tasks]
|
||||||
|
Name: desktopicon; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:";
|
||||||
|
|
||||||
|
|
||||||
|
[Run]
|
||||||
|
Filename: "{app}\ReadMe.htm"; Description: "Show ReadMe"; Flags: postinstall shellexec skipifsilent
|
||||||
|
|
||||||
|
; DON'T offer to run the wallet right away, let the people read about initial blockchain download first in the ReadMe
|
||||||
|
; Filename: "{app}\monero-wallet-gui.exe"; Description: "Run GUI Wallet now"; Flags: postinstall nowait skipifsilent
|
||||||
|
|
||||||
|
|
||||||
|
[Code]
|
||||||
|
var
|
||||||
|
BlockChainDirPage: TInputDirWizardPage;
|
||||||
|
blockChainDefaultDir: String;
|
||||||
|
|
||||||
|
procedure InitializeWizard;
|
||||||
|
var s: String;
|
||||||
|
width: Integer;
|
||||||
|
begin
|
||||||
|
// Large image for the "Welcome" page, with page reconfigured
|
||||||
|
WizardForm.WelcomeLabel1.Visible := false;
|
||||||
|
WizardForm.WelcomeLabel2.Visible := false;
|
||||||
|
WizardForm.WizardBitmapImage.Height := 300;
|
||||||
|
WizardForm.WizardBitmapImage.Width := 500;
|
||||||
|
|
||||||
|
// Image for the "Finnish" screen, in standard WizardBitmapImage size of 164 x 314
|
||||||
|
ExtractTemporaryFile('FinishImage.bmp');
|
||||||
|
WizardForm.WizardBitmapImage2.Bitmap.LoadFromFile(ExpandConstant('{tmp}\FinishImage.bmp'));
|
||||||
|
|
||||||
|
// Additional wizard page for entering a special blockchain location
|
||||||
|
blockChainDefaultDir := ExpandConstant('{commonappdata}\bitmonero');
|
||||||
|
s := 'The default folder to store the Monero blockchain is ' + blockChainDefaultDir;
|
||||||
|
s := s + '. As this will need more than 30 GB of free space, you may want to use a folder on a different drive.';
|
||||||
|
s := s + ' If yes, specify that folder here.';
|
||||||
|
|
||||||
|
BlockChainDirPage := CreateInputDirPage(wpSelectDir,
|
||||||
|
'Select Blockchain Directory', 'Where should the blockchain be installed?',
|
||||||
|
s,
|
||||||
|
False, '');
|
||||||
|
BlockChainDirPage.Add('');
|
||||||
|
|
||||||
|
BlockChainDirPage.Values[0] := GetPreviousData('BlockChainDir', '');
|
||||||
|
if BlockChainDirPage.Values[0] = '' then begin
|
||||||
|
// Unfortunately 'TInputDirWizardDirPage' does not allow empty field
|
||||||
|
BlockChainDirPage.Values[0] := blockChainDefaultDir;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure RegisterPreviousData(PreviousDataKey: Integer);
|
||||||
|
begin
|
||||||
|
// Store the selected folder for further reinstall/upgrade
|
||||||
|
SetPreviousData(PreviousDataKey, 'BlockChainDir', BlockChainDirPage.Values[0]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function BlockChainDir(Param: String) : String;
|
||||||
|
// Directory of the blockchain
|
||||||
|
var s: String;
|
||||||
|
begin
|
||||||
|
s := BlockChainDirPage.Values[0];
|
||||||
|
Result := s;
|
||||||
|
// No quotes for folder name with blanks as this is never used as part of a command line
|
||||||
|
end;
|
||||||
|
|
||||||
|
function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo,
|
||||||
|
MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
|
||||||
|
var s: String;
|
||||||
|
begin
|
||||||
|
// Fill the 'Ready Memo' with the normal settings and the custom settings
|
||||||
|
s := '';
|
||||||
|
s := s + MemoDirInfo + NewLine + NewLine;
|
||||||
|
|
||||||
|
s := s + 'Blockchain folder' + NewLine;
|
||||||
|
s := s + Space + BlockChainDir('') + NewLine;
|
||||||
|
|
||||||
|
Result := s;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function DaemonLog(Param: String) : String;
|
||||||
|
// Full filename of the log of the daemon
|
||||||
|
begin
|
||||||
|
Result := BlockChainDir('') + '\bitmonero.log';
|
||||||
|
// No quotes for filename with blanks as this is never used as part of a command line
|
||||||
|
end;
|
||||||
|
|
||||||
|
function DaemonFlags(Param: String): String;
|
||||||
|
// Flags to add to the shortcut to the daemon
|
||||||
|
var s: String;
|
||||||
|
begin
|
||||||
|
s := BlockChainDir('');
|
||||||
|
if s = blockChainDefaultDir then begin
|
||||||
|
// No need to add the default dir as flags for the daemon
|
||||||
|
s := '';
|
||||||
|
end;
|
||||||
|
if Pos(' ', s) > 0 then begin
|
||||||
|
// Quotes needed for filename with blanks
|
||||||
|
s := '"' + s + '"';
|
||||||
|
end;
|
||||||
|
if s <> '' then begin
|
||||||
|
s := '--data-dir ' + s;
|
||||||
|
end;
|
||||||
|
Result := s;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CurStepChanged(CurStep: TSetupStep);
|
||||||
|
var s: TArrayOfString;
|
||||||
|
begin
|
||||||
|
if CurStep = ssPostInstall then begin
|
||||||
|
// Re-build "monero-daemon.bat" according to actual install and blockchain directory used
|
||||||
|
SetArrayLength(s, 3);
|
||||||
|
s[0] := 'REM Execute the Monero daemon and then stay with window open after it exits';
|
||||||
|
s[1] := '"' + ExpandConstant('{app}\monerod.exe') + '" ' + DaemonFlags('');
|
||||||
|
s[2] := 'PAUSE';
|
||||||
|
SaveStringsToFile(ExpandConstant('{app}\monero-daemon.bat'), s, false);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function InitializeUninstall(): Boolean;
|
||||||
|
var s: String;
|
||||||
|
begin
|
||||||
|
s := 'Please note: Uninstall will not delete any downloaded blockchain. ';
|
||||||
|
s := s + 'If you do not need it anymore you have to delete it manually.';
|
||||||
|
s := s + #13#10#13#10 + 'Uninstall will not delete any wallets that you created either.';
|
||||||
|
MsgBox(s, mbInformation, MB_OK);
|
||||||
|
Result := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
[Icons]
|
||||||
|
; Icons in the "Monero GUI Wallet" program group
|
||||||
|
; Windows will almost always display icons in alphabetical order, per level, so specify the text accordingly
|
||||||
|
Name: "{group}\GUI Wallet"; Filename: "{app}\monero-wallet-gui.exe"
|
||||||
|
Name: "{group}\Uninstall GUI Wallet"; Filename: "{uninstallexe}"
|
||||||
|
|
||||||
|
; Sub-folder "Utilities";
|
||||||
|
; Note that Windows 10, unlike Windows 7, ignores such sub-folders completely
|
||||||
|
; and insists on displaying ALL icons on one single level
|
||||||
|
Name: "{group}\Utilities\Monero Daemon"; Filename: "{app}\monerod.exe"; Parameters: {code:DaemonFlags}
|
||||||
|
Name: "{group}\Utilities\Read Me"; Filename: "{app}\ReadMe.htm"
|
||||||
|
|
||||||
|
; CLI wallet: Needs a working directory ("Start in:") set in the icon, because with no such directory set
|
||||||
|
; it tries to create new wallets without a path given in the probably non-writable program folder and will abort with an error
|
||||||
|
Name: "{group}\Utilities\Textual (CLI) Wallet"; Filename: "{app}\monero-wallet-cli.exe"; WorkingDir: "{userdocs}\Monero\wallets"
|
||||||
|
|
||||||
|
; Icons for troubleshooting problems / testing / debugging
|
||||||
|
; To show that they are in some way different (not for everyday use), make them visually different
|
||||||
|
; from the others by text, and make them sort at the end by the help of "x" in front
|
||||||
|
Name: "{group}\Utilities\x (Check Blockchain Folder)"; Filename: "{win}\Explorer.exe"; Parameters: {code:BlockChainDir}
|
||||||
|
Name: "{group}\Utilities\x (Check Daemon Log)"; Filename: "Notepad"; Parameters: {code:DaemonLog}
|
||||||
|
Name: "{group}\Utilities\x (Check Default Wallet Folder)"; Filename: "{win}\Explorer.exe"; Parameters: "{userdocs}\Monero\wallets"
|
||||||
|
Name: "{group}\Utilities\x (Check GUI Wallet Log)"; Filename: "Notepad"; Parameters: "{app}\monero-wallet-gui.log"
|
||||||
|
Name: "{group}\Utilities\x (Try Daemon, Exit Confirm)"; Filename: "{app}\monero-daemon.bat"
|
||||||
|
Name: "{group}\Utilities\x (Try GUI Wallet Low Graphics Mode)"; Filename: "{app}\start-low-graphics-mode.bat"
|
||||||
|
Name: "{group}\Utilities\x (Try Kill Daemon)"; Filename: "Taskkill.exe"; Parameters: "/IM monerod.exe /T /F"
|
||||||
|
|
||||||
|
; Desktop icons, optional with the help of the "Task" section
|
||||||
|
Name: "{userdesktop}\GUI Wallet"; Filename: "{app}\monero-wallet-gui.exe"; Tasks: desktopicon
|
||||||
|
|
||||||
|
|
||||||
|
[Registry]
|
||||||
|
; Store any special flags for the daemon in the registry location where the GUI wallet will take it from
|
||||||
|
; So if the wallet is used to start the daemon instead of the separate icon the wallet will pass the correct flags
|
||||||
|
; Side effect, mostly positive: The uninstaller will clean the registry
|
||||||
|
Root: HKCU; Subkey: "Software\monero-project"; Flags: uninsdeletekeyifempty
|
||||||
|
Root: HKCU; Subkey: "Software\monero-project\monero-core"; Flags: uninsdeletekey
|
||||||
|
Root: HKCU; Subkey: "Software\monero-project\monero-core"; ValueType: string; ValueName: "daemonFlags"; ValueData: {code:DaemonFlags};
|
||||||
|
|
||||||
44
installers/windows/README.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Monero GUI Wallet Windows Installer #
|
||||||
|
|
||||||
|
Copyright (c) 2014-2017, The Monero Project
|
||||||
|
|
||||||
|
## Introduction ##
|
||||||
|
|
||||||
|
This is a *Inno Setup* script `Monero.iss` plus some related files
|
||||||
|
that allows you to build a standalone Windows installer (.exe) for
|
||||||
|
the GUI wallet that comes with the Helium Hydra release of Monero.
|
||||||
|
|
||||||
|
This turns the GUI wallet into a more or less standard Windows program,
|
||||||
|
by default installed into a subdirectory of `C:\Program Files`, a
|
||||||
|
program group with some icons in the *Start* menu, and automatic
|
||||||
|
uninstall support. It helps lowering the "barrier to entry"
|
||||||
|
somewhat, especially for less technically experienced users of
|
||||||
|
Monero.
|
||||||
|
|
||||||
|
As the setup script in file [Monero.iss](Monero.iss) has to list every
|
||||||
|
single file of the GUI wallet package to install by name,
|
||||||
|
this version of the script only works with exactly the GUI wallet
|
||||||
|
for Monero release *Helium Hydra* that you find on
|
||||||
|
[the official download page](https://getmonero.org/downloads/).
|
||||||
|
|
||||||
|
But of course it will be easy to modify the script for future
|
||||||
|
versions of the GUI wallet.
|
||||||
|
|
||||||
|
## License ##
|
||||||
|
|
||||||
|
See [LICENSE](LICENSE).
|
||||||
|
|
||||||
|
## Building ##
|
||||||
|
|
||||||
|
You can only build on Windows, and the result is always a
|
||||||
|
Windows .exe file that can act as a standalone installer for the
|
||||||
|
Helium Hydra GUI wallet.
|
||||||
|
|
||||||
|
The build steps in detail:
|
||||||
|
|
||||||
|
1. Install *Inno Setup*. You can get it from [here](http://www.jrsoftware.org/isdl.php)
|
||||||
|
2. Get the Inno Setup script plus related files by cloning the whole [monero-core GitHub repository](https://github.com/monero-project/monero-core); you will only need the files in the installer directory `installers\windows` however
|
||||||
|
3. The setup script is written to take the GUI wallet files from a subdirectory named `bin`; so create `installers\windows\bin`, get the zip file of the GUI wallet from [here](https://getmonero.org/downloads/), unpack it somewhere, and copy all the files and subdirectories in the `monero-gui-0.11.1.0` directory to this `bin` subdirectory
|
||||||
|
4. Start Inno Setup, load `Monero.iss` and compile it
|
||||||
|
5. The result i.e. the finished installer will be the file `mysetup.exe` in the `installers\windows\Output` subdirectory
|
||||||
|
|
||||||
181
installers/windows/ReadMe.htm
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Monero Helium Hydra GUI Wallet</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body style="font-family: Arial, Helvetica, sans-serif">
|
||||||
|
<h1>Monero Helium Hydra GUI Wallet</h1>
|
||||||
|
|
||||||
|
<p>Copyright (c) 2014-2017, The Monero Project<br>
|
||||||
|
Date: September 19, 2017</p>
|
||||||
|
|
||||||
|
<h2>Preface</h2>
|
||||||
|
|
||||||
|
<p>This ReadMe does not aim to be a complete introduction to Monero. If you are new to Monero or even to
|
||||||
|
cryptocurrencies in general you find a good introduction on reddit at
|
||||||
|
<a href="https://www.reddit.com/r/Monero/comments/5zgail/rmonero_newcomers_please_read_everything_you_need/">Newcomers Please Read. Everything You Need To Know</a>.
|
||||||
|
You also find a lot of good tutorials on <a href="https://www.monero.how/">Monero.How</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>Please note that Monero and its software are constantly evolving and progressing; it probably won't take
|
||||||
|
long for some of the information here to become outdated.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Content of the Package</h2>
|
||||||
|
|
||||||
|
<p>You just installed the <i>Monero GUI wallet</i> for Windows, release Helium Hydra, more exact version 0.11.1.0.
|
||||||
|
The wallet enables you to send and receive Moneroj in a secure and very private way.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>Also included is the <i>Monero daemon</i>, so you have everything now to run a so-called <i>full node</i>
|
||||||
|
and become part of the network of nodes that manages the Monero blockchain; you don't need to install additional
|
||||||
|
packages in order to start.</p>
|
||||||
|
|
||||||
|
<p>For checking whether there are already newer versions of this package you can go to the
|
||||||
|
<a href="https://getmonero.org/downloads/">Downloads</a> page on <a href="https://getmonero.org/home">getmonero.org</a>,
|
||||||
|
the official Monero site.</p>
|
||||||
|
|
||||||
|
<h2>Upgrading</h2>
|
||||||
|
|
||||||
|
<p>If you have already a release of the GUI wallet software on your computer that was installed with the help
|
||||||
|
of this installer (in an earlier version), upgrading is easy: Just run the new installer; there is no need to
|
||||||
|
uninstall the old Monero release first.</p>
|
||||||
|
|
||||||
|
<p>But if you run a release of the GUI wallet software that you downloaded as a .zip file and unzipped into a
|
||||||
|
folder, if you "installed it manually" so to say, don't try to upgrade by pointing the installer to that folder,
|
||||||
|
because this might lead to problems e.g. if you try to uninstall everything later.</p>
|
||||||
|
|
||||||
|
<p>It's better to let the installer put the software into another folder and then delete the old folder, either
|
||||||
|
outright or after moving away any additional files that you may have stored there. (If you did not change
|
||||||
|
default locations for wallets and the blockchain, you don't have to worry about them, they won't be in that
|
||||||
|
particular folder, but elsewhere "in safety".)</p>
|
||||||
|
|
||||||
|
<h2>Access to the Blockchain</h2>
|
||||||
|
|
||||||
|
<p>Any Monero wallet needs access to the <i>blockchain</i>, the ongoing ledger of all Monero transactions. For the
|
||||||
|
GUI wallet there are two principal ways to get that access: You can let Monero sync with the network
|
||||||
|
i.e. let it download the blockchain and store it locally on your computer, or you can configure your wallet to
|
||||||
|
access a remote <i>open node</i> to get indirect access to the blockchain.</p>
|
||||||
|
|
||||||
|
<p>Working with your own copy of the blockchain is <b>preferred</b>: It strengthens the Monero network, and it
|
||||||
|
provides the most security and privacy possible for you.</p>
|
||||||
|
|
||||||
|
<p>However if your Internet access makes it difficult to run a full node, or if you have simply no room to store
|
||||||
|
the blockchain locally (over 30 GB in fall 2017, and of course growing), you can compromise and try to connect
|
||||||
|
to a remote node. One way of finding such a node is checking
|
||||||
|
<a href="https://moneroworld.com/pages/nodes.html">this page</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Initial Blockchain Download</h2>
|
||||||
|
|
||||||
|
<p>Please do read the following <b>before</b> jumping right in and starting the GUI wallet:</p>
|
||||||
|
|
||||||
|
<p>If you decide to work with your own copy of the blockchain, which you should whenever possible, you have to
|
||||||
|
download it first; it's not part of the installed package.
|
||||||
|
Beside the GUI wallet there is second program, the so-called <i>Monero daemon</i>, which will carry out that download.
|
||||||
|
You find it in the <i>Utilities</i> sub-folder of the program group.</p>
|
||||||
|
|
||||||
|
<p>Depending on your Internet access and the speed of your computer this can take
|
||||||
|
<b>several hours</b>, in some cases <b>more than a day</b>. Furthermore there are unfortunate cases where the
|
||||||
|
download gets stuck somehow or doesn't work at all, e.g. because a firewall prevents access to other nodes of the
|
||||||
|
Monero network.</p>
|
||||||
|
|
||||||
|
<p>The GUI wallet can start the daemon for you, but that way you will not see much during initial blockchain
|
||||||
|
download, especially you probably won't see any error messages in case something goes wrong. By starting the
|
||||||
|
daemon yourself "by hand" using the <i>Monero Daemon</i> icon in the <i>Utilities</i> sub-folder of the
|
||||||
|
Monero program group you will see it running and displaying messages in a separate window.</p>
|
||||||
|
|
||||||
|
<p>If all goes well the daemon will finally display a message like this:
|
||||||
|
<i>You are now synchronized with the network.</i></p>
|
||||||
|
|
||||||
|
<p><b>Then</b> you are ready for sure to start your Monero adventures by starting the GUI wallet.</p>
|
||||||
|
|
||||||
|
<h2>Allowing Other Nodes to Connect to Your Node</h2>
|
||||||
|
|
||||||
|
<p>When the Monero daemon downloads the blockchain it does so by connecting to other nodes of the network.</p>
|
||||||
|
|
||||||
|
<p>If you allow incoming TCP/IP connections to port 18080 on your computer and let your daemon run for extended
|
||||||
|
periods of time you can "return the favor" and help others in turn to get access to Monero. However, depending on
|
||||||
|
your Internet connection, firewall, modem, router, ISP etc. this might not be possible, and opening a port in such
|
||||||
|
a way usually requires some technical knowledge.</p>
|
||||||
|
|
||||||
|
<p>If you want to try you may start e.g. with
|
||||||
|
<a href="https://monero.stackexchange.com/questions/2479/how-do-i-enable-incoming-connections-eli5">this Monero Stack Exchange</a>
|
||||||
|
question.</p>
|
||||||
|
|
||||||
|
<h2>Troubleshooting</h2>
|
||||||
|
|
||||||
|
<p>The Monero software and especially the GUI wallet are "work in progress", and sometimes things go wrong.</p>
|
||||||
|
|
||||||
|
<p>Please note that despite any technical problems that you may encounter your moneroj are almost always safe: You may
|
||||||
|
not be able to move them or you even may not see how many you currently have, but you most probably won't loose any.
|
||||||
|
But do remember that the seed needed to re-create the wallet <b>is</b> critical, however: <b>Never loose your
|
||||||
|
seed!</b></p>
|
||||||
|
|
||||||
|
<p>In the <i>Utilities</i> sub-folder there are several more icons that may help you to solve problems.
|
||||||
|
These are the icons with a <i>x</i> in front and the name <i>(in parenthesis)</i> to make them visually stand
|
||||||
|
apart from the "normal" ones because you will probably only need them in case of trouble, but not during normal
|
||||||
|
usage of Monero.</p>
|
||||||
|
|
||||||
|
<p>Here an overview and short info what each icon does:</p>
|
||||||
|
|
||||||
|
<table cellpadding="3" border="1">
|
||||||
|
<tr>
|
||||||
|
<td><i>x (Try GUI Wallet Low Graphics Mode)</i></td>
|
||||||
|
<td>Run the GUI wallet in a mode that allows for low-graphics
|
||||||
|
environments, e.g. systems with very simple non-hardware-accelerated or emulated / virtualized video cards;
|
||||||
|
also try if the display is simply slow or lags
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><i>x (Try Daemon, Exit Confirm)</i></td>
|
||||||
|
<td>
|
||||||
|
Run the Monero daemon in a window that does not automatically close if
|
||||||
|
the daemon should exit because of a fatal error; useful in cases where the normal daemon icon
|
||||||
|
just leads to a window that closes right away
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><i>x (Try Kill Daemon)</i></td>
|
||||||
|
<td>
|
||||||
|
Kill any running daemon (technically, any process called <i>monerod.exe</i>), whether
|
||||||
|
with or without any visible window, for starting "with a clean slate"; easier than
|
||||||
|
killing such tasks with the help of the Windows Task Manager
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><i>x (Check GUI Wallet Log)</i></td>
|
||||||
|
<td>Open the log with status and error messages of the GUI wallet program in Notepad;
|
||||||
|
experienced people have a chance to diagnose technical problems with the wallet,
|
||||||
|
usually by looking at the last few lines of this log</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><i>x (Check Daemon Log)</i></td>
|
||||||
|
<td>
|
||||||
|
Open the log with status and error messages of the daemon in Notepad; again, the last few
|
||||||
|
lines of this (possible very long) log are usually the most important for troubleshooting
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><i>x (Check Default Wallet Folder)</i></td>
|
||||||
|
<td>
|
||||||
|
Open the standard wallet folder in Windows Explorer; useful e.g. if you want to backup
|
||||||
|
your wallets
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td><i>x (Check Blockchain Folder)</i></td>
|
||||||
|
<td>
|
||||||
|
Open the folder containing the blockchain in Windows Explorer
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
installers/windows/WelcomeImage.bmp
Normal file
|
After Width: | Height: | Size: 440 KiB |
BIN
installers/windows/WizardSmallImage.bmp
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
3
installers/windows/monero-daemon.bat
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
REM Execute the Monero daemon and then stay with window open after it exits
|
||||||
|
"C:\Program Files\Monero Core\monerod.exe"
|
||||||
|
PAUSE
|
||||||
1
installers/windows/monero-wallet-gui.log
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-----
|
||||||
41
ios_get_libwallet.api.sh
Executable file
@@ -0,0 +1,41 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
if [ -z $BUILD_TYPE ]; then
|
||||||
|
BUILD_TYPE=release
|
||||||
|
fi
|
||||||
|
|
||||||
|
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
if [ -z $BOOST_LIBRARYDIR ]; then
|
||||||
|
BOOST_LIBRARYDIR=${ROOT_DIR}/../ofxiOSBoost/build/ios/prefix/lib
|
||||||
|
fi
|
||||||
|
if [ -z $BOOST_INCLUDEDIR ]; then
|
||||||
|
BOOST_INCLUDEDIR=${ROOT_DIR}/../ofxiOSBoost/build/ios/prefix/include
|
||||||
|
fi
|
||||||
|
if [ -z $OPENSSL_INCLUDE_DIR ]; then
|
||||||
|
OPENSSL_INCLUDE_DIR=${ROOT_DIR}/../openssl/1.0.2j/include
|
||||||
|
fi
|
||||||
|
if [ -z $OPENSSL_ROOT_DIR ]; then
|
||||||
|
OPENSSL_ROOT_DIR=${ROOT_DIR}/../openssl/1.0.2j
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Building IOS armv7"
|
||||||
|
rm -r monero/build
|
||||||
|
mkdir -p monero/build/release
|
||||||
|
pushd monero/build/release
|
||||||
|
cmake -D IOS=ON -D ARCH=armv7 -D BOOST_LIBRARYDIR=${BOOST_INCLUDEDIR} -D BOOST_INCLUDEDIR=${BOOST_INCLUDEDIR} -D OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR} -D OPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR} -D CMAKE_BUILD_TYPE=debug -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="/Users/jacob/crypto/monero-core/monero" ../..
|
||||||
|
make -j4 && make install
|
||||||
|
popd
|
||||||
|
echo "Building IOS arm64"
|
||||||
|
rm -r monero/build
|
||||||
|
mkdir -p monero/build/release
|
||||||
|
pushd monero/build/release
|
||||||
|
cmake -D IOS=ON -D ARCH=arm64 -D BOOST_LIBRARYDIR=${BOOST_INCLUDEDIR} -D BOOST_INCLUDEDIR=${BOOST_INCLUDEDIR} -D OPENSSL_INCLUDE_DIR=${OPENSSL_INCLUDE_DIR} -D OPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR} -D CMAKE_BUILD_TYPE=debug -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="/Users/jacob/crypto/monero-core/monero" ../..
|
||||||
|
make -j4 && make install
|
||||||
|
popd
|
||||||
|
|
||||||
|
echo "Creating fat library for armv7 and arm64"
|
||||||
|
pushd monero
|
||||||
|
mkdir -p lib-ios
|
||||||
|
lipo -create lib-armv7/libwallet_merged.a lib-arm64/libwallet_merged.a -output lib-ios/libwallet_merged.a
|
||||||
|
lipo -create lib-armv7/libunbound.a lib-arm64/libunbound.a -output lib-ios/libunbound.a
|
||||||
|
lipo -create lib-armv7/libepee.a lib-arm64/libepee.a -output lib-ios/libepee.a
|
||||||
|
popd
|
||||||
BIN
lang/flags/croatia.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
lang/flags/esperanto.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
lang/flags/finland.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
lang/flags/france.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
lang/flags/indonesia.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
lang/flags/israel.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
lang/flags/japan.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
lang/flags/netherlands.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
lang/flags/poland.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
lang/flags/romania.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
lang/flags/south_korea.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
lang/flags/spain.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
lang/flags/sweden.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
lang/flags/taiwan.png
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
@@ -3,22 +3,39 @@
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
List of available languages for your wallet's seed:
|
List of available languages for your wallet's seed:
|
||||||
0 : English
|
0 : Deutsch (German)
|
||||||
1 : Spanish
|
1 : English
|
||||||
2 : German
|
2 : Español (Spanish)
|
||||||
3 : Italian
|
3 : Français (French)
|
||||||
4 : Portuguese
|
4 : Italiano (Italian)
|
||||||
5 : Russian
|
5 : Nederlands (Dutch)
|
||||||
6 : Japanese
|
6 : Português (Portuguese)
|
||||||
|
7 : русский язык (Russian)
|
||||||
|
8 : 日本語 (Japanese)
|
||||||
|
9 : 简体中文 (中国) (Simplified Chinese (Mainland))
|
||||||
-->
|
-->
|
||||||
<language display_name="English (US)" locale="en_US" wallet_language="English" flag="/lang/flags/usa.png" qs="none"/>
|
<language display_name="English (US)" locale="en_US" wallet_language="English" flag="/lang/flags/usa.png" qs="none"/>
|
||||||
<!-- <language display_name="English (GB)" locale="en_GB" wallet_language="English" flag="/lang/flags/uk.png" qs="none"/>
|
<!-- <language display_name="English (GB)" locale="en_GB" wallet_language="English" flag="/lang/flags/uk.png" qs="none"/> -->
|
||||||
<language display_name="English (ZA)" locale="en_SA" wallet_language="English" flag="/lang/flags/rpa.png" qs="none"/>
|
<!-- <language display_name="English (ZA)" locale="en_SA" wallet_language="English" flag="/lang/flags/rpa.png" qs="none"/> -->
|
||||||
<language display_name="Russian" locale="ru_RU" wallet_language="Russian" flag="/lang/flags/russia.png" qs="none"/>
|
<!-- <language display_name="العربية (PS)" locale="ar_PS" wallet_language="English" flag="/lang/flags/palestine.png" qs="none"/> -->
|
||||||
<language display_name="Arabic (PS)" locale="ar_PS" wallet_language="English" flag="/lang/flags/palestine.png" qs="none"/>
|
<language display_name="Deutsch" locale="de_DE" wallet_language="Deutsch" flag="/lang/flags/german.png" qs="none"/>
|
||||||
<language display_name="Hindi" locale="hi_IN" wallet_language="English" flag="/lang/flags/india.png" qs="none"/>
|
<language display_name="Esperanto" locale="eo" wallet_language="English" flag="/lang/flags/esperanto.png" qs="none"/>
|
||||||
<language display_name="Italian" locale="it_IT" wallet_language="Italian" flag="/lang/flags/italy.png" qs="none"/>
|
<language display_name="Español" locale="es_ES" wallet_language="Español" flag="/lang/flags/spain.png" qs="none"/>
|
||||||
<language display_name="German" locale="de_DE" wallet_language="German" flag="/lang/flags/german.png" qs="none"/>
|
<!-- <language display_name="Suomen kieli" locale="fi" wallet_language="English" flag="/lang/flags/finland.png" qs="none"/> -->
|
||||||
<language display_name="Mandarin" locale="zh_CN" wallet_language="English" flag="/lang/flags/china.png" qs="none"/>
|
<language display_name="Français" locale="fr_FR" wallet_language="Français" flag="/lang/flags/france.png" qs="none"/>
|
||||||
<language display_name="Portuguese (BR)" locale="pt_BR" wallet_language="Portuguese" flag="/lang/flags/brazil.png" qs="none"/> -->
|
<language display_name="Swedish" locale="sv_SE" wallet_language="English" flag="/lang/flags/sweden.png" qs="none"/>
|
||||||
|
<!-- <language display_name="Hrvatski" locale="hr_HR" wallet_language="English" flag="/lang/flags/croatia.png" qs="none"/> -->
|
||||||
|
<!-- <language display_name="हिन्दी" locale="hi_IN" wallet_language="English" flag="/lang/flags/india.png" qs="none"/> -->
|
||||||
|
<language display_name="Bahasa Indonesia" locale="id_ID" wallet_language="English" flag="/lang/flags/indonesia.png" qs="none"/>
|
||||||
|
<language display_name="Italiano" locale="it_IT" wallet_language="Italiano" flag="/lang/flags/italy.png" qs="none"/>
|
||||||
|
<language display_name="日本語" locale="ja_JP" wallet_language="日本語" flag="/lang/flags/japan.png" qs="none"/>
|
||||||
|
<language display_name="Nederlands" locale="nl_NL" wallet_language="Nederlands" flag="/lang/flags/netherlands.png" qs="none"/>
|
||||||
|
<!-- <language display_name="Polski" locale="pl_PL" wallet_language="English" flag="/lang/flags/poland.png" qs="none"/> -->
|
||||||
|
<language display_name="Português (BR)" locale="pt-br_BR" wallet_language="Português" flag="/lang/flags/brazil.png" qs="none"/>
|
||||||
|
<language display_name="Русский язык" locale="ru_RU" wallet_language="русский язык" flag="/lang/flags/russia.png" qs="none"/>
|
||||||
|
<language display_name="简体中文 (中国)" locale="zh-cn_CN" wallet_language="简体中文 (中国)" flag="/lang/flags/china.png" qs="none"/>
|
||||||
|
<language display_name="繁體中文 (台灣)" locale="zh-tw_CN" wallet_language="English" flag="/lang/flags/taiwan.png" qs="none"/>
|
||||||
|
<language display_name="עברית" locale="he_HE" wallet_language="English" flag="/lang/flags/israel.png" qs="none"/>
|
||||||
|
<language display_name="한국어" locale="ko_KO" wallet_language="English" flag="/lang/flags/south_korea.png" qs="none"/>
|
||||||
|
<language display_name="Română" locale="ro_RO" wallet_language="English" flag="/lang/flags/romania.png" qs="none"/>
|
||||||
</languages>
|
</languages>
|
||||||
|
|||||||
@@ -9,14 +9,36 @@ GUI_EXEC=$2
|
|||||||
|
|
||||||
platform=$(get_platform)
|
platform=$(get_platform)
|
||||||
|
|
||||||
|
if [[ "$platform" == "linux64" ]]; then
|
||||||
|
PLAT_DIR="/usr/lib/x86_64-linux-gnu"
|
||||||
|
elif [[ "$platform" == "linux32" ]]; then
|
||||||
|
PLAT_DIR="/usr/lib/i386-linux-gnu"
|
||||||
|
elif [[ "$platform" == "linuxarmv7" ]]; then
|
||||||
|
PLAT_DIR="/usr/lib/arm-linux-gnueabihf"
|
||||||
|
elif [[ "$platform" == "linuxarmv8" ]]; then
|
||||||
|
PLAT_DIR="/usr/lib/aarch64-linux-gnu"
|
||||||
|
else
|
||||||
|
PLAT_DIR="/usr/lib"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$QT_DIR" ]; then
|
||||||
|
QT_DIR=$PLAT_DIR/qt5
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$QTXML_DIR" ]; then
|
||||||
|
QTXML_DIR=$PLAT_DIR
|
||||||
|
fi
|
||||||
|
|
||||||
# Copy dependencies
|
# Copy dependencies
|
||||||
EXCLUDE='libstdc++|libgcc_s.so|libc.so|libpthread'
|
EXCLUDE='libstdc++|libgcc_s.so|libc.so|libpthread'
|
||||||
cp -rv /usr/lib/x86_64-linux-gnu/qt5/qml $TARGET
|
INCLUDE='libunbound'
|
||||||
cp -rv /usr/lib/x86_64-linux-gnu/qt5/plugins $TARGET
|
cp -rv $QT_DIR/qml $TARGET || exit
|
||||||
mkdir -p $TARGET/libs
|
cp -rv $QT_DIR/plugins $TARGET || exit
|
||||||
ldd $TARGET/$GUI_EXEC | grep "=> /" | awk '{print $3}' | grep -Ev $EXCLUDE | xargs -I '{}' cp -v '{}' $TARGET/libs
|
mkdir -p $TARGET/libs || exit
|
||||||
ldd $TARGET/plugins/platforms/libqxcb.so| grep "=> /" | awk '{print $3}' | grep -Ev $EXCLUDE | xargs -I '{}' cp -v '{}' $TARGET/libs
|
#ldd $TARGET/$GUI_EXEC | grep "=> /" | awk '{print $3}' | grep $INCLUDE | xargs -I '{}' cp -v '{}' $TARGET/libs || exit
|
||||||
cp -v /usr/lib/x86_64-linux-gnu/libQt5XmlPatterns.so.5 $TARGET/libs
|
#ldd $TARGET/$GUI_EXEC | grep "=> /" | awk '{print $3}' | grep -Ev $EXCLUDE | xargs -I '{}' cp -v '{}' $TARGET/libs || exit
|
||||||
|
#ldd $TARGET/plugins/platforms/libqxcb.so| grep "=> /" | awk '{print $3}' | grep -Ev $EXCLUDE | xargs -I '{}' cp -v '{}' $TARGET/libs || exit
|
||||||
|
#cp -v $QTXML_DIR/libQt5XmlPatterns.so.5 $TARGET/libs || exit
|
||||||
|
|
||||||
# Create start script
|
# Create start script
|
||||||
cat > $TARGET/start-gui.sh <<EOL
|
cat > $TARGET/start-gui.sh <<EOL
|
||||||
@@ -24,5 +46,9 @@ cat > $TARGET/start-gui.sh <<EOL
|
|||||||
export LD_LIBRARY_PATH=\`pwd\`/libs
|
export LD_LIBRARY_PATH=\`pwd\`/libs
|
||||||
export QT_PLUGIN_PATH=\`pwd\`/plugins
|
export QT_PLUGIN_PATH=\`pwd\`/plugins
|
||||||
export QML2_IMPORT_PATH=\`pwd\`/qml
|
export QML2_IMPORT_PATH=\`pwd\`/qml
|
||||||
./$GUI_EXEC
|
# make it so that it can be called from anywhere and also through soft links
|
||||||
|
SCRIPT_DIR="\$(dirname "\$(test -L "\${BASH_SOURCE[0]}" && readlink "\${BASH_SOURCE[0]}" || echo "\${BASH_SOURCE[0]}")")"
|
||||||
|
"\$SCRIPT_DIR"/$GUI_EXEC
|
||||||
EOL
|
EOL
|
||||||
|
|
||||||
|
chmod +x $TARGET/start-gui.sh
|
||||||
|
|||||||
80
main.cpp
@@ -40,19 +40,45 @@
|
|||||||
#include "Wallet.h"
|
#include "Wallet.h"
|
||||||
#include "QRCodeImageProvider.h"
|
#include "QRCodeImageProvider.h"
|
||||||
#include "PendingTransaction.h"
|
#include "PendingTransaction.h"
|
||||||
|
#include "UnsignedTransaction.h"
|
||||||
#include "TranslationManager.h"
|
#include "TranslationManager.h"
|
||||||
#include "TransactionInfo.h"
|
#include "TransactionInfo.h"
|
||||||
#include "TransactionHistory.h"
|
#include "TransactionHistory.h"
|
||||||
#include "model/TransactionHistoryModel.h"
|
#include "model/TransactionHistoryModel.h"
|
||||||
#include "model/TransactionHistorySortFilterModel.h"
|
#include "model/TransactionHistorySortFilterModel.h"
|
||||||
#include "daemon/DaemonManager.h"
|
|
||||||
#include "AddressBook.h"
|
#include "AddressBook.h"
|
||||||
#include "model/AddressBookModel.h"
|
#include "model/AddressBookModel.h"
|
||||||
|
#include "wallet/wallet2_api.h"
|
||||||
|
#include "MainApp.h"
|
||||||
|
|
||||||
|
// IOS exclusions
|
||||||
|
#ifndef Q_OS_IOS
|
||||||
|
#include "daemon/DaemonManager.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_SCANNER
|
||||||
|
#include "QrCodeScanner.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||||
|
{
|
||||||
|
// Send all message types to logger
|
||||||
|
Monero::Wallet::debug(msg.toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QApplication app(argc, argv);
|
// // Enable high DPI scaling on windows & linux
|
||||||
|
//#if !defined(Q_OS_ANDROID) && QT_VERSION >= 0x050600
|
||||||
|
// QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
|
// qDebug() << "High DPI auto scaling - enabled";
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
// Log settings
|
||||||
|
Monero::Wallet::init(argv[0], "monero-wallet-gui");
|
||||||
|
// qInstallMessageHandler(messageHandler);
|
||||||
|
|
||||||
|
MainApp app(argc, argv);
|
||||||
|
|
||||||
qDebug() << "app startd";
|
qDebug() << "app startd";
|
||||||
|
|
||||||
@@ -72,6 +98,9 @@ int main(int argc, char *argv[])
|
|||||||
qmlRegisterUncreatableType<PendingTransaction>("moneroComponents.PendingTransaction", 1, 0, "PendingTransaction",
|
qmlRegisterUncreatableType<PendingTransaction>("moneroComponents.PendingTransaction", 1, 0, "PendingTransaction",
|
||||||
"PendingTransaction can't be instantiated directly");
|
"PendingTransaction can't be instantiated directly");
|
||||||
|
|
||||||
|
qmlRegisterUncreatableType<UnsignedTransaction>("moneroComponents.UnsignedTransaction", 1, 0, "UnsignedTransaction",
|
||||||
|
"UnsignedTransaction can't be instantiated directly");
|
||||||
|
|
||||||
qmlRegisterUncreatableType<WalletManager>("moneroComponents.WalletManager", 1, 0, "WalletManager",
|
qmlRegisterUncreatableType<WalletManager>("moneroComponents.WalletManager", 1, 0, "WalletManager",
|
||||||
"WalletManager can't be instantiated directly");
|
"WalletManager can't be instantiated directly");
|
||||||
|
|
||||||
@@ -91,10 +120,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
qmlRegisterUncreatableType<TransactionInfo>("moneroComponents.TransactionInfo", 1, 0, "TransactionInfo",
|
qmlRegisterUncreatableType<TransactionInfo>("moneroComponents.TransactionInfo", 1, 0, "TransactionInfo",
|
||||||
"TransactionHistory can't be instantiated directly");
|
"TransactionHistory can't be instantiated directly");
|
||||||
|
#ifndef Q_OS_IOS
|
||||||
qmlRegisterUncreatableType<DaemonManager>("moneroComponents.DaemonManager", 1, 0, "DaemonManager",
|
qmlRegisterUncreatableType<DaemonManager>("moneroComponents.DaemonManager", 1, 0, "DaemonManager",
|
||||||
"DaemonManager can't be instantiated directly");
|
"DaemonManager can't be instantiated directly");
|
||||||
|
#endif
|
||||||
qmlRegisterUncreatableType<AddressBookModel>("moneroComponents.AddressBookModel", 1, 0, "AddressBookModel",
|
qmlRegisterUncreatableType<AddressBookModel>("moneroComponents.AddressBookModel", 1, 0, "AddressBookModel",
|
||||||
"AddressBookModel can't be instantiated directly");
|
"AddressBookModel can't be instantiated directly");
|
||||||
|
|
||||||
@@ -105,6 +134,10 @@ int main(int argc, char *argv[])
|
|||||||
qRegisterMetaType<TransactionInfo::Direction>();
|
qRegisterMetaType<TransactionInfo::Direction>();
|
||||||
qRegisterMetaType<TransactionHistoryModel::TransactionInfoRole>();
|
qRegisterMetaType<TransactionHistoryModel::TransactionInfoRole>();
|
||||||
|
|
||||||
|
#ifdef WITH_SCANNER
|
||||||
|
qmlRegisterType<QrCodeScanner>("moneroComponents.QRCodeScanner", 1, 0, "QRCodeScanner");
|
||||||
|
#endif
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
|
|
||||||
OSCursor cursor;
|
OSCursor cursor;
|
||||||
@@ -118,9 +151,14 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
engine.addImageProvider(QLatin1String("qrcode"), new QRCodeImageProvider());
|
engine.addImageProvider(QLatin1String("qrcode"), new QRCodeImageProvider());
|
||||||
const QStringList arguments = QCoreApplication::arguments();
|
const QStringList arguments = QCoreApplication::arguments();
|
||||||
|
|
||||||
|
engine.rootContext()->setContextProperty("mainApp", &app);
|
||||||
|
|
||||||
|
// Exclude daemon manager from IOS
|
||||||
|
#ifndef Q_OS_IOS
|
||||||
DaemonManager * daemonManager = DaemonManager::instance(&arguments);
|
DaemonManager * daemonManager = DaemonManager::instance(&arguments);
|
||||||
QObject::connect(&app, SIGNAL(aboutToQuit()), daemonManager, SLOT(closing()));
|
|
||||||
engine.rootContext()->setContextProperty("daemonManager", daemonManager);
|
engine.rootContext()->setContextProperty("daemonManager", daemonManager);
|
||||||
|
#endif
|
||||||
|
|
||||||
// export to QML monero accounts root directory
|
// export to QML monero accounts root directory
|
||||||
// wizard is talking about where
|
// wizard is talking about where
|
||||||
@@ -128,13 +166,23 @@ int main(int argc, char *argv[])
|
|||||||
// backups - I reckon we save that in My Documents\Monero Accounts\ on
|
// backups - I reckon we save that in My Documents\Monero Accounts\ on
|
||||||
// Windows, ~/Monero Accounts/ on nix / osx
|
// Windows, ~/Monero Accounts/ on nix / osx
|
||||||
bool isWindows = false;
|
bool isWindows = false;
|
||||||
|
bool isIOS = false;
|
||||||
|
bool isMac = false;
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
isWindows = true;
|
isWindows = true;
|
||||||
QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
|
QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
|
||||||
|
#elif defined(Q_OS_IOS)
|
||||||
|
isIOS = true;
|
||||||
|
QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
|
||||||
#elif defined(Q_OS_UNIX)
|
#elif defined(Q_OS_UNIX)
|
||||||
QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::HomeLocation);
|
QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::HomeLocation);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
isMac = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
engine.rootContext()->setContextProperty("isWindows", isWindows);
|
engine.rootContext()->setContextProperty("isWindows", isWindows);
|
||||||
|
engine.rootContext()->setContextProperty("isIOS", isIOS);
|
||||||
|
|
||||||
if (!moneroAccountsRootDir.empty()) {
|
if (!moneroAccountsRootDir.empty()) {
|
||||||
QString moneroAccountsDir = moneroAccountsRootDir.at(0) + "/Monero/wallets";
|
QString moneroAccountsDir = moneroAccountsRootDir.at(0) + "/Monero/wallets";
|
||||||
@@ -153,15 +201,33 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
engine.rootContext()->setContextProperty("defaultAccountName", accountName);
|
engine.rootContext()->setContextProperty("defaultAccountName", accountName);
|
||||||
engine.rootContext()->setContextProperty("applicationDirectory", QApplication::applicationDirPath());
|
engine.rootContext()->setContextProperty("applicationDirectory", QApplication::applicationDirPath());
|
||||||
|
|
||||||
|
bool builtWithScanner = false;
|
||||||
|
#ifdef WITH_SCANNER
|
||||||
|
builtWithScanner = true;
|
||||||
|
#endif
|
||||||
|
engine.rootContext()->setContextProperty("builtWithScanner", builtWithScanner);
|
||||||
|
|
||||||
|
// Load main window (context properties needs to be defined obove this line)
|
||||||
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
|
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
|
||||||
QObject *rootObject = engine.rootObjects().first();
|
QObject *rootObject = engine.rootObjects().first();
|
||||||
|
|
||||||
|
#ifdef WITH_SCANNER
|
||||||
|
QObject *qmlCamera = rootObject->findChild<QObject*>("qrCameraQML");
|
||||||
|
if( qmlCamera ){
|
||||||
|
qDebug() << "QrCodeScanner : object found";
|
||||||
|
QCamera *camera_ = qvariant_cast<QCamera*>(qmlCamera->property("mediaObject"));
|
||||||
|
QObject *qmlFinder = rootObject->findChild<QObject*>("QrFinder");
|
||||||
|
qobject_cast<QrCodeScanner*>(qmlFinder)->setSource(camera_);
|
||||||
|
} else {
|
||||||
|
qDebug() << "QrCodeScanner : something went wrong !";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QObject::connect(eventFilter, SIGNAL(sequencePressed(QVariant,QVariant)), rootObject, SLOT(sequencePressed(QVariant,QVariant)));
|
QObject::connect(eventFilter, SIGNAL(sequencePressed(QVariant,QVariant)), rootObject, SLOT(sequencePressed(QVariant,QVariant)));
|
||||||
QObject::connect(eventFilter, SIGNAL(sequenceReleased(QVariant,QVariant)), rootObject, SLOT(sequenceReleased(QVariant,QVariant)));
|
QObject::connect(eventFilter, SIGNAL(sequenceReleased(QVariant,QVariant)), rootObject, SLOT(sequenceReleased(QVariant,QVariant)));
|
||||||
QObject::connect(eventFilter, SIGNAL(mousePressed(QVariant,QVariant,QVariant)), rootObject, SLOT(mousePressed(QVariant,QVariant,QVariant)));
|
QObject::connect(eventFilter, SIGNAL(mousePressed(QVariant,QVariant,QVariant)), rootObject, SLOT(mousePressed(QVariant,QVariant,QVariant)));
|
||||||
QObject::connect(eventFilter, SIGNAL(mouseReleased(QVariant,QVariant,QVariant)), rootObject, SLOT(mouseReleased(QVariant,QVariant,QVariant)));
|
QObject::connect(eventFilter, SIGNAL(mouseReleased(QVariant,QVariant,QVariant)), rootObject, SLOT(mouseReleased(QVariant,QVariant,QVariant)));
|
||||||
|
|
||||||
//WalletManager::instance()->setLogLevel(WalletManager::LogLevel_Max);
|
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|||||||
1
monero
Submodule
@@ -9,10 +9,11 @@ CONFIG += c++11
|
|||||||
# cleaning "auto-generated" bitmonero directory on "make distclean"
|
# cleaning "auto-generated" bitmonero directory on "make distclean"
|
||||||
QMAKE_DISTCLEAN += -r $$WALLET_ROOT
|
QMAKE_DISTCLEAN += -r $$WALLET_ROOT
|
||||||
|
|
||||||
INCLUDEPATH += $$WALLET_ROOT/include \
|
INCLUDEPATH += $$WALLET_ROOT/include \
|
||||||
$$PWD/src/libwalletqt \
|
$$PWD/src/libwalletqt \
|
||||||
$$PWD/src/QR-Code-generator \
|
$$PWD/src/QR-Code-generator \
|
||||||
$$PWD/src
|
$$PWD/src \
|
||||||
|
$$WALLET_ROOT/src
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
filter.h \
|
filter.h \
|
||||||
@@ -32,11 +33,11 @@ HEADERS += \
|
|||||||
src/QR-Code-generator/BitBuffer.hpp \
|
src/QR-Code-generator/BitBuffer.hpp \
|
||||||
src/QR-Code-generator/QrCode.hpp \
|
src/QR-Code-generator/QrCode.hpp \
|
||||||
src/QR-Code-generator/QrSegment.hpp \
|
src/QR-Code-generator/QrSegment.hpp \
|
||||||
src/daemon/DaemonManager.h \
|
|
||||||
src/model/AddressBookModel.h \
|
src/model/AddressBookModel.h \
|
||||||
src/libwalletqt/AddressBook.h \
|
src/libwalletqt/AddressBook.h \
|
||||||
src/zxcvbn-c/zxcvbn.h
|
src/zxcvbn-c/zxcvbn.h \
|
||||||
|
src/libwalletqt/UnsignedTransaction.h \
|
||||||
|
MainApp.h
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
SOURCES += main.cpp \
|
||||||
filter.cpp \
|
filter.cpp \
|
||||||
@@ -55,10 +56,16 @@ SOURCES += main.cpp \
|
|||||||
src/QR-Code-generator/BitBuffer.cpp \
|
src/QR-Code-generator/BitBuffer.cpp \
|
||||||
src/QR-Code-generator/QrCode.cpp \
|
src/QR-Code-generator/QrCode.cpp \
|
||||||
src/QR-Code-generator/QrSegment.cpp \
|
src/QR-Code-generator/QrSegment.cpp \
|
||||||
src/daemon/DaemonManager.cpp \
|
|
||||||
src/model/AddressBookModel.cpp \
|
src/model/AddressBookModel.cpp \
|
||||||
src/libwalletqt/AddressBook.cpp \
|
src/libwalletqt/AddressBook.cpp \
|
||||||
src/zxcvbn-c/zxcvbn.c
|
src/zxcvbn-c/zxcvbn.c \
|
||||||
|
src/libwalletqt/UnsignedTransaction.cpp \
|
||||||
|
MainApp.cpp
|
||||||
|
|
||||||
|
!ios {
|
||||||
|
HEADERS += src/daemon/DaemonManager.h
|
||||||
|
SOURCES += src/daemon/DaemonManager.cpp
|
||||||
|
}
|
||||||
|
|
||||||
lupdate_only {
|
lupdate_only {
|
||||||
SOURCES = *.qml \
|
SOURCES = *.qml \
|
||||||
@@ -68,35 +75,116 @@ SOURCES = *.qml \
|
|||||||
wizard/*js
|
wizard/*js
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ios:armv7 {
|
||||||
|
message("target is armv7")
|
||||||
|
LIBS += \
|
||||||
|
-L$$PWD/../ofxiOSBoost/build/libs/boost/lib/armv7 \
|
||||||
|
}
|
||||||
|
ios:arm64 {
|
||||||
|
message("target is arm64")
|
||||||
|
LIBS += \
|
||||||
|
-L$$PWD/../ofxiOSBoost/build/libs/boost/lib/arm64 \
|
||||||
|
}
|
||||||
|
!ios {
|
||||||
LIBS += -L$$WALLET_ROOT/lib \
|
LIBS += -L$$WALLET_ROOT/lib \
|
||||||
-lwallet_merged \
|
-lwallet_merged \
|
||||||
|
-lepee \
|
||||||
|
-lunbound \
|
||||||
|
-leasylogging \
|
||||||
|
-lreadline \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ios {
|
||||||
|
message("Host is IOS")
|
||||||
|
|
||||||
|
QMAKE_LFLAGS += -v
|
||||||
|
QMAKE_IOS_DEVICE_ARCHS = arm64
|
||||||
|
CONFIG += arm64
|
||||||
|
LIBS += -L$$WALLET_ROOT/lib-ios \
|
||||||
|
-lwallet_merged \
|
||||||
|
-lepee \
|
||||||
-lunbound
|
-lunbound
|
||||||
|
|
||||||
|
LIBS+= \
|
||||||
|
-L$$PWD/../OpenSSL-for-iPhone/lib \
|
||||||
|
-L$$PWD/../ofxiOSBoost/build/libs/boost/lib/arm64 \
|
||||||
|
-lboost_serialization \
|
||||||
|
-lboost_thread \
|
||||||
|
-lboost_system \
|
||||||
|
-lboost_date_time \
|
||||||
|
-lboost_filesystem \
|
||||||
|
-lboost_regex \
|
||||||
|
-lboost_chrono \
|
||||||
|
-lboost_program_options \
|
||||||
|
-lssl \
|
||||||
|
-lcrypto \
|
||||||
|
-ldl
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIG(WITH_SCANNER) {
|
||||||
|
if( greaterThan(QT_MINOR_VERSION, 5) ) {
|
||||||
|
message("using camera scanner")
|
||||||
|
QT += multimedia
|
||||||
|
DEFINES += "WITH_SCANNER"
|
||||||
|
INCLUDEPATH += $$PWD/src/QR-Code-scanner
|
||||||
|
HEADERS += \
|
||||||
|
src/QR-Code-scanner/QrScanThread.h \
|
||||||
|
src/QR-Code-scanner/QrCodeScanner.h
|
||||||
|
SOURCES += \
|
||||||
|
src/QR-Code-scanner/QrScanThread.cpp \
|
||||||
|
src/QR-Code-scanner/QrCodeScanner.cpp
|
||||||
|
android {
|
||||||
|
INCLUDEPATH += $$PWD/../ZBar/include
|
||||||
|
LIBS += -lzbarjni -liconv
|
||||||
|
} else {
|
||||||
|
LIBS += -lzbar
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message("Skipping camera scanner because of Incompatible Qt Version !")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# currently we only support x86 build as qt.io only provides prebuilt qt for x86 mingw
|
# currently we only support x86 build as qt.io only provides prebuilt qt for x86 mingw
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
|
|
||||||
# Win64 Host settings
|
# QMAKE_HOST.arch is unreliable, will allways report 32bit if mingw32 shell is run.
|
||||||
contains(QMAKE_HOST.arch, x86_64) {
|
# Obtaining arch through uname should be reliable. This also fixes building the project in Qt creator without changes.
|
||||||
message("Host is 64bit")
|
MSYS_HOST_ARCH = $$system(uname -a | grep -o "x86_64")
|
||||||
MSYS_PATH=c:/msys64/mingw32
|
|
||||||
|
|
||||||
# boost root path
|
# WIN64 Host settings
|
||||||
BOOST_PATH=c:/msys64/mingw64/boost
|
contains(MSYS_HOST_ARCH, x86_64) {
|
||||||
|
message("Host is 64bit")
|
||||||
|
MSYS_ROOT_PATH=c:/msys64
|
||||||
|
|
||||||
# WIN32 Host settings
|
# WIN32 Host settings
|
||||||
} else {
|
} else {
|
||||||
message("Host is 32bit")
|
message("Host is 32bit")
|
||||||
MSYS_PATH=c:/msys32/mingw32
|
MSYS_ROOT_PATH=c:/msys32
|
||||||
|
|
||||||
# boost root path
|
|
||||||
BOOST_PATH=c:/msys32/mingw32/boost
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# WIN64 Target settings
|
||||||
|
contains(QMAKE_HOST.arch, x86_64) {
|
||||||
|
MSYS_MINGW_PATH=/mingw64
|
||||||
|
|
||||||
|
# WIN32 Target settings
|
||||||
|
} else {
|
||||||
|
MSYS_MINGW_PATH=/mingw32
|
||||||
|
}
|
||||||
|
|
||||||
|
MSYS_PATH=$$MSYS_ROOT_PATH$$MSYS_MINGW_PATH
|
||||||
|
|
||||||
|
# boost root path
|
||||||
|
BOOST_PATH=$$MSYS_PATH/boost
|
||||||
|
BOOST_MINGW_PATH=$$MSYS_MINGW_PATH/boost
|
||||||
|
|
||||||
LIBS+=-L$$MSYS_PATH/lib
|
LIBS+=-L$$MSYS_PATH/lib
|
||||||
|
LIBS+=-L$$MSYS_MINGW_PATH/lib
|
||||||
LIBS+=-L$$BOOST_PATH/lib
|
LIBS+=-L$$BOOST_PATH/lib
|
||||||
|
LIBS+=-L$$BOOST_MINGW_PATH/lib
|
||||||
|
|
||||||
LIBS+= \
|
LIBS+= \
|
||||||
-Wl,-Bstatic \
|
-Wl,-Bstatic \
|
||||||
@@ -129,7 +217,18 @@ win32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
linux {
|
linux {
|
||||||
LIBS+= -Wl,-Bstatic
|
CONFIG(static) {
|
||||||
|
message("using static libraries")
|
||||||
|
LIBS+= -Wl,-Bstatic
|
||||||
|
QMAKE_LFLAGS += -static-libgcc -static-libstdc++
|
||||||
|
# contains(QT_ARCH, x86_64) {
|
||||||
|
LIBS+= -lunbound
|
||||||
|
# }
|
||||||
|
} else {
|
||||||
|
# On some distro's we need to add dynload
|
||||||
|
LIBS+= -ldl
|
||||||
|
}
|
||||||
|
|
||||||
LIBS+= \
|
LIBS+= \
|
||||||
-lboost_serialization \
|
-lboost_serialization \
|
||||||
-lboost_thread \
|
-lboost_thread \
|
||||||
@@ -140,9 +239,13 @@ linux {
|
|||||||
-lboost_chrono \
|
-lboost_chrono \
|
||||||
-lboost_program_options \
|
-lboost_program_options \
|
||||||
-lssl \
|
-lssl \
|
||||||
-lcrypto \
|
-lcrypto
|
||||||
-Wl,-Bdynamic \
|
|
||||||
-ldl
|
if(!android) {
|
||||||
|
LIBS+= \
|
||||||
|
-Wl,-Bdynamic \
|
||||||
|
-lGL
|
||||||
|
}
|
||||||
# currently monero has an issue with "static" build and linunwind-dev,
|
# currently monero has an issue with "static" build and linunwind-dev,
|
||||||
# so we link libunwind-dev only for non-Ubuntu distros
|
# so we link libunwind-dev only for non-Ubuntu distros
|
||||||
CONFIG(libunwind_off) {
|
CONFIG(libunwind_off) {
|
||||||
@@ -154,6 +257,11 @@ linux {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macx {
|
macx {
|
||||||
|
# mixing static and shared libs are not supported on mac
|
||||||
|
# CONFIG(static) {
|
||||||
|
# message("using static libraries")
|
||||||
|
# LIBS+= -Wl,-Bstatic
|
||||||
|
# }
|
||||||
LIBS+= \
|
LIBS+= \
|
||||||
-L/usr/local/lib \
|
-L/usr/local/lib \
|
||||||
-L/usr/local/opt/openssl/lib \
|
-L/usr/local/opt/openssl/lib \
|
||||||
@@ -175,17 +283,28 @@ macx {
|
|||||||
|
|
||||||
# translation stuff
|
# translation stuff
|
||||||
TRANSLATIONS = \ # English is default language, no explicit translation file
|
TRANSLATIONS = \ # English is default language, no explicit translation file
|
||||||
|
$$PWD/translations/monero-core.ts \ # translation source (copy this file when creating a new translation)
|
||||||
$$PWD/translations/monero-core_ar.ts \ # Arabic
|
$$PWD/translations/monero-core_ar.ts \ # Arabic
|
||||||
$$PWD/translations/monero-core_de.ts \ # Deutsch
|
$$PWD/translations/monero-core_pt-br.ts \ # Portuguese (Brazil)
|
||||||
|
$$PWD/translations/monero-core_de.ts \ # German
|
||||||
|
$$PWD/translations/monero-core_eo.ts \ # Esperanto
|
||||||
$$PWD/translations/monero-core_es.ts \ # Spanish
|
$$PWD/translations/monero-core_es.ts \ # Spanish
|
||||||
|
$$PWD/translations/monero-core_fi.ts \ # Finnish
|
||||||
$$PWD/translations/monero-core_fr.ts \ # French
|
$$PWD/translations/monero-core_fr.ts \ # French
|
||||||
$$PWD/translations/monero-core_hr.ts \ # Croatian
|
$$PWD/translations/monero-core_hr.ts \ # Croatian
|
||||||
$$PWD/translations/monero-core_in.ts \ # Hindi
|
$$PWD/translations/monero-core_id.ts \ # Indonesian
|
||||||
|
$$PWD/translations/monero-core_hi.ts \ # Hindi
|
||||||
$$PWD/translations/monero-core_it.ts \ # Italian
|
$$PWD/translations/monero-core_it.ts \ # Italian
|
||||||
$$PWD/translations/monero-core_ja.ts \ # Japanese
|
$$PWD/translations/monero-core_ja.ts \ # Japanese
|
||||||
|
$$PWD/translations/monero-core_nl.ts \ # Dutch
|
||||||
$$PWD/translations/monero-core_pl.ts \ # Polish
|
$$PWD/translations/monero-core_pl.ts \ # Polish
|
||||||
$$PWD/translations/monero-core_ru.ts \ # Russian
|
$$PWD/translations/monero-core_ru.ts \ # Russian
|
||||||
$$PWD/translations/monero-core_zh.ts \ # Chineese
|
$$PWD/translations/monero-core_sv.ts \ # Swedish
|
||||||
|
$$PWD/translations/monero-core_zh-cn.ts \ # Chinese (Simplified-China)
|
||||||
|
$$PWD/translations/monero-core_zh-tw.ts \ # Chinese (Traditional-Taiwan)
|
||||||
|
$$PWD/translations/monero-core_he.ts \ # Hebrew
|
||||||
|
$$PWD/translations/monero-core_ko.ts \ # Korean
|
||||||
|
$$PWD/translations/monero-core_ro.ts \ # Romanian
|
||||||
|
|
||||||
CONFIG(release, debug|release) {
|
CONFIG(release, debug|release) {
|
||||||
DESTDIR = release/bin
|
DESTDIR = release/bin
|
||||||
@@ -195,7 +314,7 @@ CONFIG(release, debug|release) {
|
|||||||
} else {
|
} else {
|
||||||
DESTDIR = debug/bin
|
DESTDIR = debug/bin
|
||||||
LANGUPD_OPTIONS =
|
LANGUPD_OPTIONS =
|
||||||
LANGREL_OPTIONS = -markuntranslated "MISS_TR "
|
# LANGREL_OPTIONS = -markuntranslated "MISS_TR "
|
||||||
}
|
}
|
||||||
|
|
||||||
TARGET_FULL_PATH = $$OUT_PWD/$$DESTDIR
|
TARGET_FULL_PATH = $$OUT_PWD/$$DESTDIR
|
||||||
@@ -207,32 +326,36 @@ macx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
!ios {
|
||||||
|
isEmpty(QMAKE_LUPDATE) {
|
||||||
|
win32:LANGUPD = $$[QT_INSTALL_BINS]\lupdate.exe
|
||||||
|
else:LANGUPD = $$[QT_INSTALL_BINS]/lupdate
|
||||||
|
}
|
||||||
|
|
||||||
isEmpty(QMAKE_LUPDATE) {
|
isEmpty(QMAKE_LRELEASE) {
|
||||||
win32:LANGUPD = $$[QT_INSTALL_BINS]\lupdate.exe
|
win32:LANGREL = $$[QT_INSTALL_BINS]\lrelease.exe
|
||||||
else:LANGUPD = $$[QT_INSTALL_BINS]/lupdate
|
else:LANGREL = $$[QT_INSTALL_BINS]/lrelease
|
||||||
|
}
|
||||||
|
|
||||||
|
langupd.command = \
|
||||||
|
$$LANGUPD $$LANGUPD_OPTIONS $$shell_path($$_PRO_FILE) -ts $$_PRO_FILE_PWD/$$TRANSLATIONS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
langrel.depends = langupd
|
||||||
|
langrel.input = TRANSLATIONS
|
||||||
|
langrel.output = $$TRANSLATION_TARGET_DIR/${QMAKE_FILE_BASE}.qm
|
||||||
|
langrel.commands = \
|
||||||
|
$$LANGREL $$LANGREL_OPTIONS ${QMAKE_FILE_IN} -qm $$TRANSLATION_TARGET_DIR/${QMAKE_FILE_BASE}.qm
|
||||||
|
langrel.CONFIG += no_link
|
||||||
|
|
||||||
|
QMAKE_EXTRA_TARGETS += langupd deploy deploy_win
|
||||||
|
QMAKE_EXTRA_COMPILERS += langrel
|
||||||
}
|
}
|
||||||
|
|
||||||
isEmpty(QMAKE_LRELEASE) {
|
|
||||||
win32:LANGREL = $$[QT_INSTALL_BINS]\lrelease.exe
|
|
||||||
else:LANGREL = $$[QT_INSTALL_BINS]/lrelease
|
|
||||||
}
|
|
||||||
|
|
||||||
langupd.command = \
|
|
||||||
$$LANGUPD $$LANGUPD_OPTIONS $$shell_path($$_PRO_FILE) -ts $$_PRO_FILE_PWD/$$TRANSLATIONS
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
langrel.depends = langupd
|
|
||||||
langrel.input = TRANSLATIONS
|
|
||||||
langrel.output = $$TRANSLATION_TARGET_DIR/${QMAKE_FILE_BASE}.qm
|
|
||||||
langrel.commands = \
|
|
||||||
$$LANGREL $$LANGREL_OPTIONS ${QMAKE_FILE_IN} -qm $$TRANSLATION_TARGET_DIR/${QMAKE_FILE_BASE}.qm
|
|
||||||
langrel.CONFIG += no_link
|
|
||||||
|
|
||||||
QMAKE_EXTRA_TARGETS += langupd deploy deploy_win
|
|
||||||
QMAKE_EXTRA_COMPILERS += langrel
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Update: no issues with the "slow link process" anymore,
|
# Update: no issues with the "slow link process" anymore,
|
||||||
@@ -243,6 +366,7 @@ QMAKE_EXTRA_COMPILERS += langrel
|
|||||||
PRE_TARGETDEPS += langupd compiler_langrel_make_all
|
PRE_TARGETDEPS += langupd compiler_langrel_make_all
|
||||||
|
|
||||||
RESOURCES += qml.qrc
|
RESOURCES += qml.qrc
|
||||||
|
CONFIG += qtquickcompiler
|
||||||
|
|
||||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||||
QML_IMPORT_PATH =
|
QML_IMPORT_PATH =
|
||||||
@@ -261,10 +385,13 @@ win32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
linux {
|
linux:!android {
|
||||||
deploy.commands += $$escape_expand(\n\t) $$PWD/linuxdeploy_helper.sh $$DESTDIR $$TARGET
|
deploy.commands += $$escape_expand(\n\t) $$PWD/linuxdeploy_helper.sh $$DESTDIR $$TARGET
|
||||||
}
|
}
|
||||||
|
|
||||||
|
android{
|
||||||
|
deploy.commands += make install INSTALL_ROOT=$$DESTDIR && androiddeployqt --input android-libmonero-wallet-gui.so-deployment-settings.json --output $$DESTDIR --deployment bundled --android-platform android-21 --jdk /usr/lib/jvm/java-8-openjdk-amd64 -qmldir=$$PWD
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
OTHER_FILES += \
|
OTHER_FILES += \
|
||||||
@@ -272,7 +399,9 @@ OTHER_FILES += \
|
|||||||
$$TRANSLATIONS
|
$$TRANSLATIONS
|
||||||
|
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
notes.txt
|
notes.txt \
|
||||||
|
monero/src/wallet/CMakeLists.txt \
|
||||||
|
components/MobileHeader.qml
|
||||||
|
|
||||||
|
|
||||||
# windows application icon
|
# windows application icon
|
||||||
|
|||||||
12
oshelper.cpp
@@ -1,6 +1,8 @@
|
|||||||
#include "oshelper.h"
|
#include "oshelper.h"
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
OSHelper::OSHelper(QObject *parent) : QObject(parent)
|
OSHelper::OSHelper(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
@@ -18,6 +20,16 @@ QString OSHelper::temporaryFilename() const
|
|||||||
return tempFileName;
|
return tempFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OSHelper::removeTemporaryWallet(const QString &fileName) const
|
||||||
|
{
|
||||||
|
// Temporary files should be deleted automatically by default, in case they wouldn't, we delete them manually as well
|
||||||
|
bool cache_deleted = QFile::remove(fileName);
|
||||||
|
bool address_deleted = QFile::remove(fileName + ".address.txt");
|
||||||
|
bool keys_deleted = QFile::remove(fileName +".keys");
|
||||||
|
|
||||||
|
return cache_deleted && address_deleted && keys_deleted;
|
||||||
|
}
|
||||||
|
|
||||||
QString OSHelper::temporaryPath() const
|
QString OSHelper::temporaryPath() const
|
||||||
{
|
{
|
||||||
return QDir::tempPath();
|
return QDir::tempPath();
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public:
|
|||||||
|
|
||||||
Q_INVOKABLE QString temporaryFilename() const;
|
Q_INVOKABLE QString temporaryFilename() const;
|
||||||
Q_INVOKABLE QString temporaryPath() const;
|
Q_INVOKABLE QString temporaryPath() const;
|
||||||
|
Q_INVOKABLE bool removeTemporaryWallet(const QString &walletName) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
import "../components"
|
import "../components"
|
||||||
import moneroComponents.AddressBook 1.0
|
import moneroComponents.AddressBook 1.0
|
||||||
import moneroComponents.AddressBookModel 1.0
|
import moneroComponents.AddressBookModel 1.0
|
||||||
@@ -57,20 +58,39 @@ Rectangle {
|
|||||||
anchors.top: newEntryText.bottom
|
anchors.top: newEntryText.bottom
|
||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
text: qsTr("Address")
|
text: qsTr("Address") + translationManager.emptyString
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString
|
}
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
id: qrfinderButton
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 17
|
||||||
|
anchors.topMargin: 5
|
||||||
|
anchors.top: addressLabel.bottom
|
||||||
|
text: qsTr("QRCODE") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
visible : appWindow.qrScannerEnabled
|
||||||
|
enabled : visible
|
||||||
|
width: visible ? 60 : 0
|
||||||
|
onClicked: {
|
||||||
|
cameraUi.state = "Capture"
|
||||||
|
cameraUi.qrcode_decoded.connect(updateFromQrCode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LineEdit {
|
LineEdit {
|
||||||
id: addressLine
|
id: addressLine
|
||||||
anchors.left: parent.left
|
anchors.left: qrfinderButton.right
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: addressLabel.bottom
|
anchors.top: addressLabel.bottom
|
||||||
anchors.leftMargin: 17
|
|
||||||
anchors.rightMargin: 17
|
anchors.rightMargin: 17
|
||||||
anchors.topMargin: 5
|
anchors.topMargin: 5
|
||||||
error: true;
|
error: true;
|
||||||
|
placeholderText: qsTr("4...") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
@@ -81,8 +101,6 @@ Rectangle {
|
|||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
text: qsTr("Payment ID <font size='2'>(Optional)</font>") + translationManager.emptyString
|
text: qsTr("Payment ID <font size='2'>(Optional)</font>") + translationManager.emptyString
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
tipText: qsTr("<b>Payment ID</b><br/><br/>A unique user name used in<br/>the address book. It is not a<br/>transfer of information sent<br/>during the transfer")
|
|
||||||
+ translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LineEdit {
|
LineEdit {
|
||||||
@@ -93,6 +111,7 @@ Rectangle {
|
|||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
anchors.rightMargin: 17
|
anchors.rightMargin: 17
|
||||||
anchors.topMargin: 5
|
anchors.topMargin: 5
|
||||||
|
placeholderText: qsTr("Paste 64 hexadecimal characters") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
@@ -101,9 +120,8 @@ Rectangle {
|
|||||||
anchors.top: paymentIdLine.bottom
|
anchors.top: paymentIdLine.bottom
|
||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
text: qsTr("Description <font size='2'>(Local database)</font>") + translationManager.emptyString
|
text: qsTr("Description <font size='2'>(Optional)</font>") + translationManager.emptyString
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
tipText: qsTr("<b>Tip test test</b><br/><br/>test line 2") + translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LineEdit {
|
LineEdit {
|
||||||
@@ -114,44 +132,49 @@ Rectangle {
|
|||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
anchors.rightMargin: 17
|
anchors.rightMargin: 17
|
||||||
anchors.topMargin: 5
|
anchors.topMargin: 5
|
||||||
|
placeholderText: qsTr("Give this entry a name or description") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
StandardButton {
|
|
||||||
|
RowLayout {
|
||||||
id: addButton
|
id: addButton
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: descriptionLine.bottom
|
anchors.top: descriptionLine.bottom
|
||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
width: 60
|
|
||||||
|
|
||||||
shadowReleasedColor: "#FF4304"
|
StandardButton {
|
||||||
shadowPressedColor: "#B32D00"
|
shadowReleasedColor: "#FF4304"
|
||||||
releasedColor: "#FF6C3C"
|
shadowPressedColor: "#B32D00"
|
||||||
pressedColor: "#FF4304"
|
releasedColor: "#FF6C3C"
|
||||||
text: qsTr("ADD")
|
pressedColor: "#FF4304"
|
||||||
enabled: checkInformation(addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
|
text: qsTr("Add") + translationManager.emptyString
|
||||||
|
enabled: checkInformation(addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (!currentWallet.addressBook.addRow(addressLine.text.trim(), paymentIdLine.text.trim(), descriptionLine.text)) {
|
if (!currentWallet.addressBook.addRow(addressLine.text.trim(), paymentIdLine.text.trim(), descriptionLine.text)) {
|
||||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
// TODO: check currentWallet.addressBook.errorString() instead.
|
// TODO: check currentWallet.addressBook.errorString() instead.
|
||||||
if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Address)
|
if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Address)
|
||||||
informationPopup.text = qsTr("Invalid address")
|
informationPopup.text = qsTr("Invalid address") + translationManager.emptyString
|
||||||
else if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Payment_Id)
|
else if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Payment_Id)
|
||||||
informationPopup.text = qsTr("Invalid Payment ID")
|
informationPopup.text = currentWallet.addressBook.errorString()
|
||||||
else
|
else
|
||||||
informationPopup.text = qsTr("Can't create entry")
|
informationPopup.text = qsTr("Can't create entry") + translationManager.emptyString
|
||||||
|
|
||||||
informationPopup.onCloseCallback = null
|
informationPopup.onCloseCallback = null
|
||||||
informationPopup.open();
|
informationPopup.open();
|
||||||
} else {
|
} else {
|
||||||
addressLine.text = "";
|
addressLine.text = "";
|
||||||
paymentIdLine.text = "";
|
paymentIdLine.text = "";
|
||||||
descriptionLine.text = "";
|
descriptionLine.text = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: expandItem
|
id: expandItem
|
||||||
property bool expanded: false
|
property bool expanded: false
|
||||||
@@ -275,5 +298,13 @@ Rectangle {
|
|||||||
root.model = currentWallet.addressBookModel;
|
root.model = currentWallet.addressBookModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateFromQrCode(address, payment_id, amount, tx_description, recipient_name) {
|
||||||
|
console.log("updateFromQrCode")
|
||||||
|
addressLine.text = address
|
||||||
|
paymentIdLine.text = payment_id
|
||||||
|
//amountLine.text = amount
|
||||||
|
descriptionLine.text = recipient_name + " " + tx_description
|
||||||
|
cameraUi.qrcode_decoded.disconnect(updateFromQrCode)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ Rectangle {
|
|||||||
|
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
visible: !isMobile
|
||||||
id: filterHeaderText
|
id: filterHeaderText
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -135,6 +136,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
visible: !isMobile
|
||||||
id: selectedAmount
|
id: selectedAmount
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
@@ -142,7 +144,6 @@ Rectangle {
|
|||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
text: getSelectedAmount()
|
text: getSelectedAmount()
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
tipText: qsTr("<b>Total amount of selected payments</b>") + translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -156,7 +157,6 @@ Rectangle {
|
|||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
text: qsTr("Address")
|
text: qsTr("Address")
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LineEdit {
|
LineEdit {
|
||||||
@@ -172,6 +172,7 @@ Rectangle {
|
|||||||
|
|
||||||
// Filter by string
|
// Filter by string
|
||||||
LineEdit {
|
LineEdit {
|
||||||
|
visible: !isMobile
|
||||||
id: searchLine
|
id: searchLine
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -196,7 +197,6 @@ Rectangle {
|
|||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
text: qsTr("Description <font size='2'>(Local database)</font>") + translationManager.emptyString
|
text: qsTr("Description <font size='2'>(Local database)</font>") + translationManager.emptyString
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
tipText: qsTr("<b>Tip tekst test</b><br/><br/>test line 2") + translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LineEdit {
|
LineEdit {
|
||||||
@@ -213,6 +213,7 @@ Rectangle {
|
|||||||
|
|
||||||
// DateFrom picker
|
// DateFrom picker
|
||||||
Label {
|
Label {
|
||||||
|
visible: !isMobile
|
||||||
id: dateFromText
|
id: dateFromText
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: searchLine.bottom // descriptionLine.bottom
|
anchors.top: searchLine.bottom // descriptionLine.bottom
|
||||||
@@ -221,10 +222,10 @@ Rectangle {
|
|||||||
width: 156
|
width: 156
|
||||||
text: qsTr("Date from") + translationManager.emptyString
|
text: qsTr("Date from") + translationManager.emptyString
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DatePicker {
|
DatePicker {
|
||||||
|
visible: !isMobile
|
||||||
id: fromDatePicker
|
id: fromDatePicker
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: dateFromText.bottom
|
anchors.top: dateFromText.bottom
|
||||||
@@ -239,17 +240,18 @@ Rectangle {
|
|||||||
|
|
||||||
// DateTo picker
|
// DateTo picker
|
||||||
Label {
|
Label {
|
||||||
|
visible: !isMobile
|
||||||
id: dateToText
|
id: dateToText
|
||||||
anchors.left: dateFromText.right
|
anchors.left: dateFromText.right
|
||||||
anchors.top: searchLine.bottom //descriptionLine.bottom
|
anchors.top: searchLine.bottom //descriptionLine.bottom
|
||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
text: qsTr("To")
|
text: qsTr("To") + translationManager.emptyString
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DatePicker {
|
DatePicker {
|
||||||
|
visible: !isMobile
|
||||||
id: toDatePicker
|
id: toDatePicker
|
||||||
anchors.left: fromDatePicker.right
|
anchors.left: fromDatePicker.right
|
||||||
anchors.top: dateToText.bottom
|
anchors.top: dateToText.bottom
|
||||||
@@ -265,12 +267,13 @@ Rectangle {
|
|||||||
|
|
||||||
|
|
||||||
StandardButton {
|
StandardButton {
|
||||||
|
visible: !isMobile
|
||||||
id: filterButton
|
id: filterButton
|
||||||
anchors.bottom: toDatePicker.bottom
|
anchors.bottom: toDatePicker.bottom
|
||||||
anchors.left: toDatePicker.right
|
anchors.left: toDatePicker.right
|
||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
width: 60
|
width: 60
|
||||||
text: qsTr("FILTER")
|
text: qsTr("Filter") + translationManager.emptyString
|
||||||
shadowReleasedColor: "#4D0051"
|
shadowReleasedColor: "#4D0051"
|
||||||
shadowPressedColor: "#2D002F"
|
shadowPressedColor: "#2D002F"
|
||||||
releasedColor: "#6B0072"
|
releasedColor: "#6B0072"
|
||||||
@@ -306,8 +309,9 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CheckBox {
|
CheckBox {
|
||||||
|
visible: !isMobile
|
||||||
id: advancedFilteringCheckBox
|
id: advancedFilteringCheckBox
|
||||||
text: qsTr("Advanced filtering")
|
text: qsTr("Advanced filtering") + translationManager.emptyString
|
||||||
anchors.left: filterButton.right
|
anchors.left: filterButton.right
|
||||||
anchors.bottom: filterButton.bottom
|
anchors.bottom: filterButton.bottom
|
||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
@@ -320,6 +324,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
visible: !isMobile
|
||||||
id: transactionTypeText
|
id: transactionTypeText
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: fromDatePicker.bottom
|
anchors.top: fromDatePicker.bottom
|
||||||
@@ -328,18 +333,18 @@ Rectangle {
|
|||||||
width: 156
|
width: 156
|
||||||
text: qsTr("Type of transaction") + translationManager.emptyString
|
text: qsTr("Type of transaction") + translationManager.emptyString
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
id: transactionsModel
|
id: transactionsModel
|
||||||
ListElement { column1: "ALL"; column2: ""; value: TransactionInfo.Direction_Both }
|
ListElement { column1: "All"; column2: ""; value: TransactionInfo.Direction_Both }
|
||||||
ListElement { column1: "SENT"; column2: ""; value: TransactionInfo.Direction_Out }
|
ListElement { column1: "Sent"; column2: ""; value: TransactionInfo.Direction_Out }
|
||||||
ListElement { column1: "RECEIVED"; column2: ""; value: TransactionInfo.Direction_In }
|
ListElement { column1: "Received"; column2: ""; value: TransactionInfo.Direction_In }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StandardDropdown {
|
StandardDropdown {
|
||||||
|
visible: !isMobile
|
||||||
id: transactionTypeDropdown
|
id: transactionTypeDropdown
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: transactionTypeText.bottom
|
anchors.top: transactionTypeText.bottom
|
||||||
@@ -355,6 +360,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
visible: !isMobile
|
||||||
id: amountFromText
|
id: amountFromText
|
||||||
anchors.left: transactionTypeText.right
|
anchors.left: transactionTypeText.right
|
||||||
anchors.top: fromDatePicker.bottom
|
anchors.top: fromDatePicker.bottom
|
||||||
@@ -363,10 +369,10 @@ Rectangle {
|
|||||||
width: 156
|
width: 156
|
||||||
text: qsTr("Amount from") + translationManager.emptyString
|
text: qsTr("Amount from") + translationManager.emptyString
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LineEdit {
|
LineEdit {
|
||||||
|
visible: !isMobile
|
||||||
id: amountFromLine
|
id: amountFromLine
|
||||||
anchors.left: transactionTypeDropdown.right
|
anchors.left: transactionTypeDropdown.right
|
||||||
anchors.top: amountFromText.bottom
|
anchors.top: amountFromText.bottom
|
||||||
@@ -387,18 +393,19 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
visible: !isMobile
|
||||||
id: amountToText
|
id: amountToText
|
||||||
anchors.left: amountFromText.right
|
anchors.left: amountFromText.right
|
||||||
anchors.top: fromDatePicker.bottom
|
anchors.top: fromDatePicker.bottom
|
||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
width: 156
|
width: 156
|
||||||
text: qsTr("To")
|
text: qsTr("To") + translationManager.emptyString
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LineEdit {
|
LineEdit {
|
||||||
|
visible: !isMobile
|
||||||
id: amountToLine
|
id: amountToLine
|
||||||
anchors.left: amountFromLine.right
|
anchors.left: amountFromLine.right
|
||||||
anchors.top: amountToText.bottom
|
anchors.top: amountToText.bottom
|
||||||
@@ -420,6 +427,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
visible: !isMobile
|
||||||
id: expandItem
|
id: expandItem
|
||||||
property bool expanded: false
|
property bool expanded: false
|
||||||
|
|
||||||
@@ -449,16 +457,17 @@ Rectangle {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: tableRect
|
id: tableRect
|
||||||
property int expandedHeight: parent.height - filterHeaderText.y - filterHeaderText.height - 17
|
property int expandedHeight: parent.height - filterHeaderText.y - filterHeaderText.height - 5
|
||||||
property int middleHeight: parent.height - fromDatePicker.y - fromDatePicker.height - 17
|
property int middleHeight: parent.height - fromDatePicker.y - fromDatePicker.height - 17
|
||||||
property int collapsedHeight: parent.height - transactionTypeDropdown.y - transactionTypeDropdown.height - 17
|
property int collapsedHeight: parent.height - transactionTypeDropdown.y - transactionTypeDropdown.height - 17
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
// anchors.top: parent.top
|
||||||
color: "#FFFFFF"
|
color: "#FFFFFF"
|
||||||
z: 1
|
z: 1
|
||||||
|
|
||||||
height: middleHeight
|
height: (isMobile)? parent.height : middleHeight
|
||||||
onHeightChanged: {
|
onHeightChanged: {
|
||||||
if(height === middleHeight) z = 1
|
if(height === middleHeight) z = 1
|
||||||
else if(height === collapsedHeight) z = 0
|
else if(height === collapsedHeight) z = 0
|
||||||
@@ -540,6 +549,11 @@ Rectangle {
|
|||||||
anchors.rightMargin: 14
|
anchors.rightMargin: 14
|
||||||
onContentYChanged: flickableScroll.flickableContentYChanged()
|
onContentYChanged: flickableScroll.flickableContentYChanged()
|
||||||
model: root.model
|
model: root.model
|
||||||
|
addressBookModel: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onPageCompleted() {
|
||||||
|
table.addressBookModel = appWindow.currentWallet ? appWindow.currentWallet.addressBookModel : null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
195
pages/Mining.qml
@@ -27,8 +27,199 @@
|
|||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import "../components"
|
||||||
|
import moneroComponents.Wallet 1.0
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 100
|
id: root
|
||||||
height: 62
|
color: "#F0EEEE"
|
||||||
|
property var currentHashRate: 0
|
||||||
|
|
||||||
|
/* main layout */
|
||||||
|
ColumnLayout {
|
||||||
|
id: mainLayout
|
||||||
|
anchors.margins: 40
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
spacing: 20
|
||||||
|
|
||||||
|
// solo
|
||||||
|
ColumnLayout {
|
||||||
|
id: soloBox
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
spacing: 20
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: soloTitleLabel
|
||||||
|
fontSize: 24
|
||||||
|
text: qsTr("Solo mining") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: soloLocalDaemonsLabel
|
||||||
|
fontSize: 18
|
||||||
|
color: "#D02020"
|
||||||
|
text: qsTr("(only available for local daemons)")
|
||||||
|
visible: !isDaemonLocal()
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: soloMainLabel
|
||||||
|
text: qsTr("Mining with your computer helps strengthen the Monero network. The more that people mine, the harder it is for the network to be attacked, and every little bit helps.<br> <br>Mining also gives you a small chance to earn some Monero. Your computer will create hashes looking for block solutions. If you find a block, you will get the associated reward. Good luck!") + translationManager.emptyString
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: soloMinerThreadsRow
|
||||||
|
Label {
|
||||||
|
id: soloMinerThreadsLabel
|
||||||
|
color: "#4A4949"
|
||||||
|
text: qsTr("CPU threads") + translationManager.emptyString
|
||||||
|
fontSize: 16
|
||||||
|
Layout.preferredWidth: 120
|
||||||
|
}
|
||||||
|
LineEdit {
|
||||||
|
id: soloMinerThreadsLine
|
||||||
|
Layout.preferredWidth: 200
|
||||||
|
text: "1"
|
||||||
|
placeholderText: qsTr("(optional)") + translationManager.emptyString
|
||||||
|
validator: IntValidator { bottom: 1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.leftMargin: 125
|
||||||
|
CheckBox {
|
||||||
|
id: backgroundMining
|
||||||
|
enabled: startSoloMinerButton.enabled
|
||||||
|
checked: persistentSettings.allow_background_mining
|
||||||
|
onClicked: {persistentSettings.allow_background_mining = checked}
|
||||||
|
text: qsTr("Background mining (experimental)") + translationManager.emptyString
|
||||||
|
checkedIcon: "../images/checkedVioletIcon.png"
|
||||||
|
uncheckedIcon: "../images/uncheckedIcon.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
// Disable this option until stable
|
||||||
|
visible: false
|
||||||
|
Layout.leftMargin: 125
|
||||||
|
CheckBox {
|
||||||
|
id: ignoreBattery
|
||||||
|
enabled: startSoloMinerButton.enabled
|
||||||
|
checked: !persistentSettings.miningIgnoreBattery
|
||||||
|
onClicked: {persistentSettings.miningIgnoreBattery = !checked}
|
||||||
|
text: qsTr("Enable mining when running on battery") + translationManager.emptyString
|
||||||
|
checkedIcon: "../images/checkedVioletIcon.png"
|
||||||
|
uncheckedIcon: "../images/uncheckedIcon.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Label {
|
||||||
|
id: manageSoloMinerLabel
|
||||||
|
color: "#4A4949"
|
||||||
|
text: qsTr("Manage miner") + translationManager.emptyString
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
visible: true
|
||||||
|
//enabled: !walletManager.isMining()
|
||||||
|
id: startSoloMinerButton
|
||||||
|
width: 110
|
||||||
|
text: qsTr("Start mining") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
onClicked: {
|
||||||
|
var success = walletManager.startMining(appWindow.currentWallet.address, soloMinerThreadsLine.text, persistentSettings.allow_background_mining, persistentSettings.miningIgnoreBattery)
|
||||||
|
if (success) {
|
||||||
|
update()
|
||||||
|
} else {
|
||||||
|
errorPopup.title = qsTr("Error starting mining") + translationManager.emptyString;
|
||||||
|
errorPopup.text = qsTr("Couldn't start mining.<br>")
|
||||||
|
if (!isDaemonLocal())
|
||||||
|
errorPopup.text += qsTr("Mining is only available on local daemons. Run a local daemon to be able to mine.<br>")
|
||||||
|
errorPopup.icon = StandardIcon.Critical
|
||||||
|
errorPopup.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
visible: true
|
||||||
|
//enabled: walletManager.isMining()
|
||||||
|
id: stopSoloMinerButton
|
||||||
|
width: 110
|
||||||
|
text: qsTr("Stop mining") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
onClicked: {
|
||||||
|
walletManager.stopMining()
|
||||||
|
update()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: statusText
|
||||||
|
text: qsTr("Status: not mining")
|
||||||
|
textFormat: Text.RichText
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStatusText() {
|
||||||
|
var text = ""
|
||||||
|
if (walletManager.isMining()) {
|
||||||
|
if (text !== "")
|
||||||
|
text += "<br>";
|
||||||
|
text += qsTr("Mining at %1 H/s").arg(walletManager.miningHashRate())
|
||||||
|
}
|
||||||
|
if (text === "") {
|
||||||
|
text += qsTr("Not mining") + translationManager.emptyString;
|
||||||
|
}
|
||||||
|
statusText.text = qsTr("Status: ") + text
|
||||||
|
}
|
||||||
|
|
||||||
|
function update() {
|
||||||
|
updateStatusText()
|
||||||
|
startSoloMinerButton.enabled = !walletManager.isMining()
|
||||||
|
stopSoloMinerButton.enabled = !startSoloMinerButton.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardDialog {
|
||||||
|
id: errorPopup
|
||||||
|
cancelVisible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: timer
|
||||||
|
interval: 2000; running: false; repeat: true
|
||||||
|
onTriggered: update()
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPageCompleted() {
|
||||||
|
console.log("Mining page loaded");
|
||||||
|
|
||||||
|
update()
|
||||||
|
timer.running = isDaemonLocal()
|
||||||
|
|
||||||
|
}
|
||||||
|
function onPageClosed() {
|
||||||
|
timer.running = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,16 +51,23 @@ Rectangle {
|
|||||||
function updatePaymentId(payment_id) {
|
function updatePaymentId(payment_id) {
|
||||||
if (typeof appWindow.currentWallet === 'undefined' || appWindow.currentWallet == null)
|
if (typeof appWindow.currentWallet === 'undefined' || appWindow.currentWallet == null)
|
||||||
return
|
return
|
||||||
|
|
||||||
// generate a new one if not given as argument
|
// generate a new one if not given as argument
|
||||||
if (typeof payment_id === 'undefined') {
|
if (typeof payment_id === 'undefined') {
|
||||||
payment_id = appWindow.currentWallet.generatePaymentId()
|
payment_id = appWindow.currentWallet.generatePaymentId()
|
||||||
appWindow.persistentSettings.payment_id = payment_id
|
|
||||||
paymentIdLine.text = payment_id
|
paymentIdLine.text = payment_id
|
||||||
}
|
}
|
||||||
addressLine.text = appWindow.currentWallet.address
|
|
||||||
integratedAddressLine.text = appWindow.currentWallet.integratedAddress(payment_id)
|
if (payment_id.length > 0) {
|
||||||
if (integratedAddressLine.text === "")
|
integratedAddressLine.text = appWindow.currentWallet.integratedAddress(payment_id)
|
||||||
integratedAddressLine.text = qsTr("Invalid payment ID")
|
if (integratedAddressLine.text === "")
|
||||||
|
integratedAddressLine.text = qsTr("Invalid payment ID")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
paymentIdLine.text = ""
|
||||||
|
integratedAddressLine.text = ""
|
||||||
|
}
|
||||||
|
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +103,7 @@ Rectangle {
|
|||||||
setTrackingLineText("-")
|
setTrackingLineText("-")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (appWindow.currentWallet.connected == Wallet.ConnectionStatus_Disconnected) {
|
if (appWindow.currentWallet.connected() == Wallet.ConnectionStatus_Disconnected) {
|
||||||
setTrackingLineText(qsTr("WARNING: no connection to daemon"))
|
setTrackingLineText(qsTr("WARNING: no connection to daemon"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -161,7 +168,9 @@ Rectangle {
|
|||||||
/* main layout */
|
/* main layout */
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
anchors.margins: 40
|
anchors.margins: (isMobile)? 17 : 40
|
||||||
|
anchors.topMargin: 40
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -173,9 +182,8 @@ Rectangle {
|
|||||||
property int qrCodeSize: 240
|
property int qrCodeSize: 240
|
||||||
|
|
||||||
|
|
||||||
RowLayout {
|
ColumnLayout {
|
||||||
id: addressRow
|
id: addressRow
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
id: addressLabel
|
id: addressLabel
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
@@ -196,6 +204,7 @@ Rectangle {
|
|||||||
imageSource: "../images/copyToClipboard.png"
|
imageSource: "../images/copyToClipboard.png"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (addressLine.text.length > 0) {
|
if (addressLine.text.length > 0) {
|
||||||
|
console.log(addressLine.text + " copied to clipboard")
|
||||||
clipboard.setText(addressLine.text)
|
clipboard.setText(addressLine.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,42 +212,11 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
GridLayout {
|
||||||
id: integratedAddressRow
|
|
||||||
Label {
|
|
||||||
id: integratedAddressLabel
|
|
||||||
fontSize: 14
|
|
||||||
text: qsTr("Integrated address") + translationManager.emptyString
|
|
||||||
width: mainLayout.labelWidth
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LineEdit {
|
|
||||||
|
|
||||||
id: integratedAddressLine
|
|
||||||
fontSize: mainLayout.lineEditFontSize
|
|
||||||
placeholderText: qsTr("ReadOnly wallet integrated address displayed here") + translationManager.emptyString
|
|
||||||
readOnly: true
|
|
||||||
width: mainLayout.editWidth
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
onTextChanged: cursorPosition = 0
|
|
||||||
|
|
||||||
IconButton {
|
|
||||||
imageSource: "../images/copyToClipboard.png"
|
|
||||||
onClicked: {
|
|
||||||
if (integratedAddressLine.text.length > 0) {
|
|
||||||
clipboard.setText(integratedAddressLine.text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: paymentIdRow
|
id: paymentIdRow
|
||||||
|
columns:2
|
||||||
Label {
|
Label {
|
||||||
|
Layout.columnSpan: 2
|
||||||
id: paymentIdLabel
|
id: paymentIdLabel
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
text: qsTr("Payment ID") + translationManager.emptyString
|
text: qsTr("Payment ID") + translationManager.emptyString
|
||||||
@@ -249,7 +227,7 @@ Rectangle {
|
|||||||
LineEdit {
|
LineEdit {
|
||||||
id: paymentIdLine
|
id: paymentIdLine
|
||||||
fontSize: mainLayout.lineEditFontSize
|
fontSize: mainLayout.lineEditFontSize
|
||||||
placeholderText: qsTr("16 or 64 hexadecimal characters") + translationManager.emptyString;
|
placeholderText: qsTr("16 hexadecimal characters") + translationManager.emptyString;
|
||||||
readOnly: false
|
readOnly: false
|
||||||
onTextChanged: updatePaymentId(paymentIdLine.text)
|
onTextChanged: updatePaymentId(paymentIdLine.text)
|
||||||
|
|
||||||
@@ -269,21 +247,61 @@ Rectangle {
|
|||||||
StandardButton {
|
StandardButton {
|
||||||
id: generatePaymentId
|
id: generatePaymentId
|
||||||
width: 80
|
width: 80
|
||||||
fontSize: 14
|
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
pressedColor: "#FF4304"
|
pressedColor: "#FF4304"
|
||||||
text: qsTr("Generate")
|
text: qsTr("Generate") + translationManager.emptyString;
|
||||||
anchors.right: parent.right
|
onClicked: updatePaymentId()
|
||||||
onClicked: {
|
}
|
||||||
appWindow.persistentSettings.payment_id = appWindow.currentWallet.generatePaymentId();
|
|
||||||
updatePaymentId()
|
StandardButton {
|
||||||
}
|
id: clearPaymentId
|
||||||
|
enabled: !!paymentIdLine.text
|
||||||
|
width: 80
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
text: qsTr("Clear") + translationManager.emptyString;
|
||||||
|
onClicked: updatePaymentId("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
ColumnLayout {
|
||||||
|
id: integratedAddressRow
|
||||||
|
Label {
|
||||||
|
id: integratedAddressLabel
|
||||||
|
fontSize: 14
|
||||||
|
text: qsTr("Integrated address") + translationManager.emptyString
|
||||||
|
width: mainLayout.labelWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LineEdit {
|
||||||
|
|
||||||
|
id: integratedAddressLine
|
||||||
|
fontSize: mainLayout.lineEditFontSize
|
||||||
|
placeholderText: qsTr("Generate payment ID for integrated address") + translationManager.emptyString
|
||||||
|
readOnly: true
|
||||||
|
width: mainLayout.editWidth
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
onTextChanged: cursorPosition = 0
|
||||||
|
|
||||||
|
IconButton {
|
||||||
|
imageSource: "../images/copyToClipboard.png"
|
||||||
|
onClicked: {
|
||||||
|
if (integratedAddressLine.text.length > 0) {
|
||||||
|
clipboard.setText(integratedAddressLine.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
id: amountRow
|
id: amountRow
|
||||||
Label {
|
Label {
|
||||||
id: amountLabel
|
id: amountLabel
|
||||||
@@ -296,7 +314,7 @@ Rectangle {
|
|||||||
LineEdit {
|
LineEdit {
|
||||||
id: amountLine
|
id: amountLine
|
||||||
fontSize: mainLayout.lineEditFontSize
|
fontSize: mainLayout.lineEditFontSize
|
||||||
placeholderText: qsTr("Amount") + translationManager.emptyString
|
placeholderText: qsTr("Amount to receive") + translationManager.emptyString
|
||||||
readOnly: false
|
readOnly: false
|
||||||
width: mainLayout.editWidth
|
width: mainLayout.editWidth
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -358,6 +376,32 @@ Rectangle {
|
|||||||
standardButtons: StandardButton.Ok
|
standardButtons: StandardButton.Ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileDialog {
|
||||||
|
id: qrFileDialog
|
||||||
|
title: "Please choose a name"
|
||||||
|
folder: shortcuts.pictures
|
||||||
|
selectExisting: false
|
||||||
|
nameFilters: [ "Image (*.png)"]
|
||||||
|
onAccepted: {
|
||||||
|
if( ! walletManager.saveQrCode(makeQRCodeString(), walletManager.urlToLocalPath(fileUrl))) {
|
||||||
|
console.log("Failed to save QrCode to file " + walletManager.urlToLocalPath(fileUrl) )
|
||||||
|
trackingHowToUseDialog.title = qsTr("Save QrCode") + translationManager.emptyString;
|
||||||
|
trackingHowToUseDialog.text = qsTr("Failed to save QrCode to ") + walletManager.urlToLocalPath(fileUrl) + translationManager.emptyString;
|
||||||
|
trackingHowToUseDialog.icon = StandardIcon.Error
|
||||||
|
trackingHowToUseDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
id: qrMenu
|
||||||
|
title: "QrCode"
|
||||||
|
MenuItem {
|
||||||
|
text: qsTr("Save As") + translationManager.emptyString;
|
||||||
|
onTriggered: qrFileDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: qrCode
|
id: qrCode
|
||||||
anchors.margins: 50
|
anchors.margins: 50
|
||||||
@@ -367,6 +411,15 @@ Rectangle {
|
|||||||
smooth: false
|
smooth: false
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: "image://qrcode/" + makeQRCodeString()
|
source: "image://qrcode/" + makeQRCodeString()
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
onClicked: {
|
||||||
|
if (mouse.button == Qt.RightButton)
|
||||||
|
qrMenu.popup()
|
||||||
|
}
|
||||||
|
onPressAndHold: qrFileDialog.open()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,12 +432,14 @@ Rectangle {
|
|||||||
function onPageCompleted() {
|
function onPageCompleted() {
|
||||||
console.log("Receive page loaded");
|
console.log("Receive page loaded");
|
||||||
|
|
||||||
if(addressLine.text.length === 0 || addressLine.text !== appWindow.currentWallet.address) {
|
if (appWindow.currentWallet) {
|
||||||
updatePaymentId()
|
if (addressLine.text.length === 0 || addressLine.text !== appWindow.currentWallet.address) {
|
||||||
|
addressLine.text = appWindow.currentWallet.address
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update()
|
update()
|
||||||
timer.running = true
|
timer.running = true
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPageClosed() {
|
function onPageClosed() {
|
||||||
|
|||||||
@@ -39,234 +39,52 @@ import moneroComponents.Clipboard 1.0
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
property var daemonAddress
|
property var daemonAddress
|
||||||
|
property bool viewOnly: false
|
||||||
|
id: page
|
||||||
|
|
||||||
color: "#F0EEEE"
|
color: "#F0EEEE"
|
||||||
|
|
||||||
Clipboard { id: clipboard }
|
Clipboard { id: clipboard }
|
||||||
|
|
||||||
function initSettings() {
|
function initSettings() {
|
||||||
|
//runs on every page load
|
||||||
|
|
||||||
// Mnemonic seed settings
|
|
||||||
memoTextInput.text = qsTr("Click button to show seed") + translationManager.emptyString
|
|
||||||
showSeedButton.visible = true
|
|
||||||
|
|
||||||
// Daemon settings
|
// Daemon settings
|
||||||
|
|
||||||
daemonAddress = persistentSettings.daemon_address.split(":");
|
daemonAddress = persistentSettings.daemon_address.split(":");
|
||||||
console.log("address: " + persistentSettings.daemon_address)
|
console.log("address: " + persistentSettings.daemon_address)
|
||||||
// try connecting to daemon
|
// try connecting to daemon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PasswordDialog {
|
|
||||||
id: settingsPasswordDialog
|
|
||||||
|
|
||||||
onAccepted: {
|
|
||||||
if(appWindow.password === settingsPasswordDialog.password){
|
|
||||||
memoTextInput.text = currentWallet.seed
|
|
||||||
showSeedButton.visible = false
|
|
||||||
} else {
|
|
||||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
|
||||||
informationPopup.text = qsTr("Wrong password");
|
|
||||||
informationPopup.open()
|
|
||||||
informationPopup.onCloseCallback = function() {
|
|
||||||
settingsPasswordDialog.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
settingsPasswordDialog.password = ""
|
|
||||||
}
|
|
||||||
onRejected: {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
anchors.margins: 40
|
anchors.margins: 17
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
spacing: 10
|
spacing: 10
|
||||||
|
|
||||||
|
//! Manage wallet
|
||||||
Label {
|
|
||||||
id: seedLabel
|
|
||||||
color: "#4A4949"
|
|
||||||
fontSize: 16
|
|
||||||
text: qsTr("Mnemonic seed: ") + translationManager.emptyString
|
|
||||||
Layout.preferredWidth: 100
|
|
||||||
Layout.alignment: Qt.AlignLeft
|
|
||||||
}
|
|
||||||
|
|
||||||
TextArea {
|
|
||||||
id: memoTextInput
|
|
||||||
textMargin: 6
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pointSize: 14
|
|
||||||
wrapMode: TextEdit.WordWrap
|
|
||||||
readOnly: true
|
|
||||||
selectByMouse: true
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 100
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
|
|
||||||
text: qsTr("Click button to show seed") + translationManager.emptyString
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id : clipboardButton
|
|
||||||
anchors.right: memoTextInput.right
|
|
||||||
anchors.bottom: memoTextInput.bottom
|
|
||||||
source: "qrc:///images/greyTriangle.png"
|
|
||||||
|
|
||||||
Image {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
source: "qrc:///images/copyToClipboard.png"
|
|
||||||
}
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: clipboard.setText(memoTextInput.text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Label {
|
||||||
Text {
|
id: manageWalletLabel
|
||||||
id: wordsTipText
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pointSize: 12
|
|
||||||
color: "#4A4646"
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
wrapMode: Text.WordWrap
|
color: "#4A4949"
|
||||||
text: qsTr("This is very important to write down and keep secret. It is all you need to restore your wallet.")
|
text: qsTr("Manage wallet") + translationManager.emptyString
|
||||||
+ translationManager.emptyString
|
fontSize: 16
|
||||||
}
|
Layout.topMargin: 10
|
||||||
|
|
||||||
StandardButton {
|
|
||||||
|
|
||||||
id: showSeedButton
|
|
||||||
|
|
||||||
fontSize: 14
|
|
||||||
shadowReleasedColor: "#FF4304"
|
|
||||||
shadowPressedColor: "#B32D00"
|
|
||||||
releasedColor: "#FF6C3C"
|
|
||||||
pressedColor: "#FF4304"
|
|
||||||
text: qsTr("Show seed")
|
|
||||||
Layout.alignment: Qt.AlignRight
|
|
||||||
Layout.preferredWidth: 100
|
|
||||||
onClicked: {
|
|
||||||
settingsPasswordDialog.open();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
height: 1
|
height: 1
|
||||||
color: "#DEDEDE"
|
color: "#DEDEDE"
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
GridLayout {
|
||||||
id: daemonAddrRow
|
columns: (isMobile)? 2 : 4
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 40
|
|
||||||
Layout.topMargin: 40
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: daemonAddrLabel
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
color: "#4A4949"
|
|
||||||
text: qsTr("Daemon address") + translationManager.emptyString
|
|
||||||
fontSize: 16
|
|
||||||
}
|
|
||||||
|
|
||||||
LineEdit {
|
|
||||||
id: daemonAddr
|
|
||||||
Layout.preferredWidth: 200
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: (daemonAddress !== undefined) ? daemonAddress[0] : ""
|
|
||||||
placeholderText: qsTr("Hostname / IP")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LineEdit {
|
|
||||||
id: daemonPort
|
|
||||||
Layout.preferredWidth: 100
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: (daemonAddress !== undefined) ? daemonAddress[1] : "18081"
|
|
||||||
placeholderText: qsTr("Port")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
StandardButton {
|
|
||||||
id: daemonAddrSave
|
|
||||||
|
|
||||||
Layout.fillWidth: false
|
|
||||||
|
|
||||||
Layout.leftMargin: 30
|
|
||||||
Layout.minimumWidth: 100
|
|
||||||
width: 60
|
|
||||||
text: qsTr("Save") + translationManager.emptyString
|
|
||||||
shadowReleasedColor: "#FF4304"
|
|
||||||
shadowPressedColor: "#B32D00"
|
|
||||||
releasedColor: "#FF6C3C"
|
|
||||||
pressedColor: "#FF4304"
|
|
||||||
visible: true
|
|
||||||
onClicked: {
|
|
||||||
console.log("saving daemon adress settings")
|
|
||||||
var newDaemon = daemonAddr.text + ":" + daemonPort.text
|
|
||||||
if(persistentSettings.daemon_address != newDaemon) {
|
|
||||||
persistentSettings.daemon_address = newDaemon
|
|
||||||
//reconnect wallet
|
|
||||||
appWindow.initialize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Label {
|
|
||||||
id: closeWalletLabel
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
color: "#4A4949"
|
|
||||||
text: qsTr("Manage wallet") + translationManager.emptyString
|
|
||||||
fontSize: 16
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RowLayout {
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: closeWalletTip
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pointSize: 12
|
|
||||||
color: "#4A4646"
|
|
||||||
Layout.fillWidth: true
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
text: qsTr("Close current wallet and open wizard")
|
|
||||||
+ translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
StandardButton {
|
StandardButton {
|
||||||
id: closeWalletButton
|
id: closeWalletButton
|
||||||
|
|
||||||
// Layout.leftMargin: 30
|
|
||||||
// Layout.minimumWidth: 100
|
|
||||||
width: 100
|
|
||||||
text: qsTr("Close wallet") + translationManager.emptyString
|
text: qsTr("Close wallet") + translationManager.emptyString
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
@@ -278,21 +96,119 @@ Rectangle {
|
|||||||
appWindow.showWizard();
|
appWindow.showWizard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
enabled: !viewOnly
|
||||||
|
id: createViewOnlyWalletButton
|
||||||
|
text: qsTr("Create view only wallet") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
visible: true
|
||||||
|
onClicked: {
|
||||||
|
wizard.openCreateViewOnlyWalletPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
id: showSeedButton
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
text: qsTr("Show seed & keys") + translationManager.emptyString
|
||||||
|
onClicked: {
|
||||||
|
settingsPasswordDialog.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rescan cache - Disabled until we know it's needed
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
id: rescanWalletbutton
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
text: qsTr("Rescan wallet cache") + translationManager.emptyString
|
||||||
|
onClicked: {
|
||||||
|
// Show confirmation dialog
|
||||||
|
confirmationDialog.title = qsTr("Rescan wallet cache") + translationManager.emptyString;
|
||||||
|
confirmationDialog.text = qsTr("Are you sure you want to rebuild the wallet cache?\n"
|
||||||
|
+ "The following information will be deleted\n"
|
||||||
|
+ "- Recipient addresses\n"
|
||||||
|
+ "- Tx keys\n"
|
||||||
|
+ "- Tx descriptions\n\n"
|
||||||
|
+ "The old wallet cache file will be renamed and can be restored later.\n"
|
||||||
|
);
|
||||||
|
confirmationDialog.icon = StandardIcon.Question
|
||||||
|
confirmationDialog.cancelText = qsTr("Cancel")
|
||||||
|
confirmationDialog.onAcceptedCallback = function() {
|
||||||
|
walletManager.closeWallet();
|
||||||
|
walletManager.clearWalletCache(persistentSettings.wallet_path);
|
||||||
|
walletManager.openWalletAsync(persistentSettings.wallet_path, appWindow.password,
|
||||||
|
persistentSettings.testnet);
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmationDialog.onRejectedCallback = null;
|
||||||
|
|
||||||
|
confirmationDialog.open()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
StandardButton {
|
||||||
|
id: rescanSpentButton
|
||||||
|
text: qsTr("Rescan wallet balance") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
onClicked: {
|
||||||
|
if (!currentWallet.rescanSpent()) {
|
||||||
|
console.error("Error: ", currentWallet.errorString);
|
||||||
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
|
informationPopup.text = qsTr("Error: ") + currentWallet.errorString
|
||||||
|
informationPopup.icon = StandardIcon.Critical
|
||||||
|
informationPopup.onCloseCallback = null
|
||||||
|
informationPopup.open();
|
||||||
|
} else {
|
||||||
|
informationPopup.title = qsTr("Information") + translationManager.emptyString
|
||||||
|
informationPopup.text = qsTr("Sucessfully rescanned spent outputs") + translationManager.emptyString
|
||||||
|
informationPopup.icon = StandardIcon.Information
|
||||||
|
informationPopup.onCloseCallback = null
|
||||||
|
informationPopup.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Manage daemon
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Label {
|
Label {
|
||||||
id: manageDaemonLabel
|
id: manageDaemonLabel
|
||||||
|
Layout.fillWidth: true
|
||||||
color: "#4A4949"
|
color: "#4A4949"
|
||||||
text: qsTr("Manage daemon") + translationManager.emptyString
|
text: qsTr("Manage daemon") + translationManager.emptyString
|
||||||
fontSize: 16
|
fontSize: 16
|
||||||
|
anchors.topMargin: 30
|
||||||
|
Layout.topMargin: 30
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 1
|
||||||
|
color: "#DEDEDE"
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: daemonStatusRow
|
||||||
|
columns: (isMobile) ? 2 : 4
|
||||||
StandardButton {
|
StandardButton {
|
||||||
visible: true
|
visible: true
|
||||||
enabled: !appWindow.daemonRunning
|
enabled: !appWindow.daemonRunning
|
||||||
id: startDaemonButton
|
id: startDaemonButton
|
||||||
width: 110
|
|
||||||
text: qsTr("Start daemon") + translationManager.emptyString
|
text: qsTr("Start daemon") + translationManager.emptyString
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
@@ -307,7 +223,6 @@ Rectangle {
|
|||||||
visible: true
|
visible: true
|
||||||
enabled: appWindow.daemonRunning
|
enabled: appWindow.daemonRunning
|
||||||
id: stopDaemonButton
|
id: stopDaemonButton
|
||||||
width: 110
|
|
||||||
text: qsTr("Stop daemon") + translationManager.emptyString
|
text: qsTr("Stop daemon") + translationManager.emptyString
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
@@ -320,21 +235,49 @@ Rectangle {
|
|||||||
|
|
||||||
StandardButton {
|
StandardButton {
|
||||||
visible: true
|
visible: true
|
||||||
// enabled: appWindow.daemonRunning
|
id: daemonStatusButton
|
||||||
id: daemonConsolePopupButton
|
text: qsTr("Show status") + translationManager.emptyString
|
||||||
width: 110
|
|
||||||
text: qsTr("Show log") + translationManager.emptyString
|
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
pressedColor: "#FF4304"
|
pressedColor: "#FF4304"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
daemonManager.sendCommand("status",currentWallet.testnet);
|
||||||
daemonConsolePopup.open();
|
daemonConsolePopup.open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: blockchainFolderRow
|
||||||
|
Label {
|
||||||
|
id: blockchainFolderLabel
|
||||||
|
color: "#4A4949"
|
||||||
|
text: qsTr("Blockchain location") + translationManager.emptyString
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
LineEdit {
|
||||||
|
id: blockchainFolder
|
||||||
|
Layout.preferredWidth: 200
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: persistentSettings.blockchainDataDir
|
||||||
|
placeholderText: qsTr("(optional)") + translationManager.emptyString
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
mouse.accepted = false
|
||||||
|
if(persistentSettings.blockchainDataDir != "")
|
||||||
|
blockchainFileDialog.folder = "file://" + persistentSettings.blockchainDataDir
|
||||||
|
blockchainFileDialog.open()
|
||||||
|
blockchainFolder.focus = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: daemonFlagsRow
|
id: daemonFlagsRow
|
||||||
Label {
|
Label {
|
||||||
@@ -352,6 +295,118 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: daemonAddrLabel
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: "#4A4949"
|
||||||
|
text: qsTr("Daemon address") + translationManager.emptyString
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: daemonAddrRow
|
||||||
|
Layout.fillWidth: true
|
||||||
|
columnSpacing: 10
|
||||||
|
columns: (isMobile) ? 2 : 3
|
||||||
|
|
||||||
|
LineEdit {
|
||||||
|
id: daemonAddr
|
||||||
|
Layout.preferredWidth: 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: (daemonAddress !== undefined) ? daemonAddress[0] : ""
|
||||||
|
placeholderText: qsTr("Hostname / IP") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LineEdit {
|
||||||
|
id: daemonPort
|
||||||
|
Layout.preferredWidth: 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: (daemonAddress !== undefined) ? daemonAddress[1] : "18081"
|
||||||
|
placeholderText: qsTr("Port") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 10
|
||||||
|
Label {
|
||||||
|
id: daemonLoginLabel
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: "#4A4949"
|
||||||
|
text: qsTr("Login (optional)") + translationManager.emptyString
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
|
||||||
|
LineEdit {
|
||||||
|
id: daemonUsername
|
||||||
|
Layout.preferredWidth: 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: persistentSettings.daemonUsername
|
||||||
|
placeholderText: qsTr("Username") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LineEdit {
|
||||||
|
id: daemonPassword
|
||||||
|
Layout.preferredWidth: 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: persistentSettings.daemonPassword
|
||||||
|
placeholderText: qsTr("Password") + translationManager.emptyString
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
id: daemonAddrSave
|
||||||
|
Layout.fillWidth: false
|
||||||
|
Layout.leftMargin: 30
|
||||||
|
text: qsTr("Connect") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
onClicked: {
|
||||||
|
console.log("saving daemon adress settings")
|
||||||
|
var newDaemon = daemonAddr.text.trim() + ":" + daemonPort.text.trim()
|
||||||
|
if(persistentSettings.daemon_address != newDaemon) {
|
||||||
|
persistentSettings.daemon_address = newDaemon
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update daemon login
|
||||||
|
persistentSettings.daemonUsername = daemonUsername.text;
|
||||||
|
persistentSettings.daemonPassword = daemonPassword.text;
|
||||||
|
currentWallet.setDaemonLogin(persistentSettings.daemonUsername, persistentSettings.daemonPassword);
|
||||||
|
|
||||||
|
//Reinit wallet
|
||||||
|
currentWallet.initAsync(newDaemon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Label {
|
||||||
|
color: "#4A4949"
|
||||||
|
text: qsTr("Layout settings") + translationManager.emptyString
|
||||||
|
fontSize: 16
|
||||||
|
anchors.topMargin: 30
|
||||||
|
Layout.topMargin: 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 1
|
||||||
|
color: "#DEDEDE"
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
CheckBox {
|
CheckBox {
|
||||||
id: customDecorationsCheckBox
|
id: customDecorationsCheckBox
|
||||||
@@ -363,45 +418,303 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
// Log level
|
||||||
id: guiVersion
|
|
||||||
|
RowLayout {
|
||||||
|
Label {
|
||||||
|
color: "#4A4949"
|
||||||
|
text: qsTr("Log level") + translationManager.emptyString
|
||||||
|
fontSize: 16
|
||||||
|
anchors.topMargin: 30
|
||||||
|
Layout.topMargin: 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 1
|
||||||
|
color: "#DEDEDE"
|
||||||
|
}
|
||||||
|
ColumnLayout {
|
||||||
|
ComboBox {
|
||||||
|
id: logLevel
|
||||||
|
model: [0,1,2,3,4,"custom"]
|
||||||
|
currentIndex : appWindow.persistentSettings.logLevel;
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
if (currentIndex == 5) {
|
||||||
|
console.log("log categories changed: ", logCategories.text);
|
||||||
|
walletManager.setLogCategories(logCategories.text);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log("log level changed: ",currentIndex);
|
||||||
|
walletManager.setLogLevel(currentIndex);
|
||||||
|
}
|
||||||
|
appWindow.persistentSettings.logLevel = currentIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LineEdit {
|
||||||
|
id: logCategories
|
||||||
|
Layout.preferredWidth: 200
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: appWindow.persistentSettings.logCategories
|
||||||
|
placeholderText: qsTr("(e.g. *:WARNING,net.p2p:DEBUG)") + translationManager.emptyString
|
||||||
|
enabled: logLevel.currentIndex == 5
|
||||||
|
onEditingFinished: {
|
||||||
|
if(enabled) {
|
||||||
|
console.log("log categories changed: ", text);
|
||||||
|
walletManager.setLogCategories(text);
|
||||||
|
appWindow.persistentSettings.logCategories = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version
|
||||||
|
RowLayout {
|
||||||
|
Label {
|
||||||
|
color: "#4A4949"
|
||||||
|
text: qsTr("Debug info") + translationManager.emptyString
|
||||||
|
fontSize: 16
|
||||||
|
anchors.topMargin: 30
|
||||||
|
Layout.topMargin: 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 1
|
||||||
|
color: "#DEDEDE"
|
||||||
|
}
|
||||||
|
|
||||||
|
TextBlock {
|
||||||
Layout.topMargin: 8
|
Layout.topMargin: 8
|
||||||
color: "#4A4949"
|
Layout.fillWidth: true
|
||||||
text: qsTr("GUI version: ") + Version.GUI_VERSION + translationManager.emptyString
|
text: qsTr("GUI version: ") + Version.GUI_VERSION + translationManager.emptyString
|
||||||
fontSize: 16
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
TextBlock {
|
||||||
id: guiMoneroVersion
|
id: guiMoneroVersion
|
||||||
color: "#4A4949"
|
Layout.fillWidth: true
|
||||||
text: qsTr("Embedded Monero version: ") + Version.GUI_MONERO_VERSION + translationManager.emptyString
|
text: qsTr("Embedded Monero version: ") + Version.GUI_MONERO_VERSION + translationManager.emptyString
|
||||||
fontSize: 16
|
}
|
||||||
|
TextBlock {
|
||||||
|
id: restoreHeightText
|
||||||
|
Layout.fillWidth: true
|
||||||
|
textFormat: Text.RichText
|
||||||
|
property var txt: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C}</style>" + qsTr("Wallet creation height: ") + currentWallet.walletCreationHeight + translationManager.emptyString
|
||||||
|
property var linkTxt: qsTr(" <a href='#'>(Click to change)</a>") + translationManager.emptyString
|
||||||
|
text: (typeof currentWallet == "undefined") ? "" : txt + linkTxt
|
||||||
|
|
||||||
|
onLinkActivated: {
|
||||||
|
restoreHeightRow.visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: restoreHeightRow
|
||||||
|
visible: false
|
||||||
|
LineEdit {
|
||||||
|
id: restoreHeight
|
||||||
|
Layout.preferredWidth: 80
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: currentWallet.walletCreationHeight
|
||||||
|
validator: IntValidator {
|
||||||
|
bottom:0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
id: restoreHeightSave
|
||||||
|
Layout.fillWidth: false
|
||||||
|
Layout.leftMargin: 30
|
||||||
|
text: qsTr("Save") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
currentWallet.walletCreationHeight = restoreHeight.text
|
||||||
|
// Restore height is saved in .keys file. Set password to trigger rewrite.
|
||||||
|
currentWallet.setPassword(appWindow.password)
|
||||||
|
restoreHeightRow.visible = false
|
||||||
|
|
||||||
|
// Show confirmation dialog
|
||||||
|
confirmationDialog.title = qsTr("Rescan wallet cache") + translationManager.emptyString;
|
||||||
|
confirmationDialog.text = qsTr("Are you sure you want to rebuild the wallet cache?\n"
|
||||||
|
+ "The following information will be deleted\n"
|
||||||
|
+ "- Recipient addresses\n"
|
||||||
|
+ "- Tx keys\n"
|
||||||
|
+ "- Tx descriptions\n\n"
|
||||||
|
+ "The old wallet cache file will be renamed and can be restored later.\n"
|
||||||
|
);
|
||||||
|
confirmationDialog.icon = StandardIcon.Question
|
||||||
|
confirmationDialog.cancelText = qsTr("Cancel")
|
||||||
|
confirmationDialog.onAcceptedCallback = function() {
|
||||||
|
walletManager.closeWallet();
|
||||||
|
walletManager.clearWalletCache(persistentSettings.wallet_path);
|
||||||
|
walletManager.openWalletAsync(persistentSettings.wallet_path, appWindow.password,
|
||||||
|
persistentSettings.testnet);
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmationDialog.onRejectedCallback = null;
|
||||||
|
|
||||||
|
confirmationDialog.open()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TextBlock {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: (typeof currentWallet == "undefined") ? "" : qsTr("Wallet log path: ") + currentWallet.walletLogPath + translationManager.emptyString
|
||||||
|
}
|
||||||
|
TextBlock {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: (typeof currentWallet == "undefined") ? "" : qsTr("Daemon log path: ") + currentWallet.daemonLogPath + translationManager.emptyString
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Daemon console
|
// Daemon console
|
||||||
StandardDialog {
|
DaemonConsole {
|
||||||
id: daemonConsolePopup
|
id: daemonConsolePopup
|
||||||
height:500
|
height:500
|
||||||
width:800
|
width:800
|
||||||
cancelVisible: false
|
title: qsTr("Daemon log") + translationManager.emptyString
|
||||||
title: qsTr("Daemon log")
|
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PasswordDialog {
|
||||||
|
id: settingsPasswordDialog
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if(appWindow.password === settingsPasswordDialog.password){
|
||||||
|
if(currentWallet.seedLanguage == "") {
|
||||||
|
console.log("No seed language set. Using English as default");
|
||||||
|
currentWallet.setSeedLanguage("English");
|
||||||
|
}
|
||||||
|
|
||||||
|
seedPopup.title = qsTr("Wallet seed & keys") + translationManager.emptyString;
|
||||||
|
seedPopup.text = "<b>Wallet Mnemonic seed</b> <br>" + currentWallet.seed
|
||||||
|
+ "<br><br> <b>" + qsTr("Secret view key") + ":</b> " + currentWallet.secretViewKey
|
||||||
|
+ "<br><b>" + qsTr("Public view key") + ":</b> " + currentWallet.publicViewKey
|
||||||
|
+ "<br><b>" + qsTr("Secret spend key") + ":</b> " + currentWallet.secretSpendKey
|
||||||
|
+ "<br><b>" + qsTr("Public spend key") + ":</b> " + currentWallet.publicSpendKey
|
||||||
|
seedPopup.open()
|
||||||
|
seedPopup.width = 600
|
||||||
|
seedPopup.height = 300
|
||||||
|
seedPopup.onCloseCallback = function() {
|
||||||
|
seedPopup.text = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
|
informationPopup.text = qsTr("Wrong password");
|
||||||
|
informationPopup.open()
|
||||||
|
informationPopup.onCloseCallback = function() {
|
||||||
|
settingsPasswordDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
settingsPasswordDialog.password = ""
|
||||||
|
}
|
||||||
|
onRejected: {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardDialog {
|
||||||
|
id: seedPopup
|
||||||
|
cancelVisible: false
|
||||||
|
okVisible: true
|
||||||
|
width:600
|
||||||
|
height:400
|
||||||
|
|
||||||
|
property var onCloseCallback
|
||||||
|
onAccepted: {
|
||||||
|
if (onCloseCallback) {
|
||||||
|
onCloseCallback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choose blockchain folder
|
||||||
|
FileDialog {
|
||||||
|
id: blockchainFileDialog
|
||||||
|
title: qsTr("Please choose a folder") + translationManager.emptyString;
|
||||||
|
selectFolder: true
|
||||||
|
folder: "file://" + persistentSettings.blockchainDataDir
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
var dataDir = walletManager.urlToLocalPath(blockchainFileDialog.fileUrl)
|
||||||
|
var validator = daemonManager.validateDataDir(dataDir);
|
||||||
|
if(!validator.valid) {
|
||||||
|
|
||||||
|
confirmationDialog.title = qsTr("Warning") + translationManager.emptyString;
|
||||||
|
confirmationDialog.text = "";
|
||||||
|
if(validator.readOnly) {
|
||||||
|
confirmationDialog.text += qsTr("Error: Filesystem is read only") + "\n\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if(validator.storageAvailable < 20) {
|
||||||
|
confirmationDialog.text += qsTr("Warning: There's only %1 GB available on the device. Blockchain requires ~%2 GB of data.").arg(validator.storageAvailable).arg(15) + "\n\n"
|
||||||
|
} else {
|
||||||
|
confirmationDialog.text += qsTr("Note: There's %1 GB available on the device. Blockchain requires ~%2 GB of data.").arg(validator.storageAvailable).arg(15) + "\n\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!validator.lmdbExists) {
|
||||||
|
confirmationDialog.text += qsTr("Note: lmdb folder not found. A new folder will be created.") + "\n\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
confirmationDialog.icon = StandardIcon.Question
|
||||||
|
confirmationDialog.cancelText = qsTr("Cancel")
|
||||||
|
|
||||||
|
// Continue
|
||||||
|
confirmationDialog.onAcceptedCallback = function() {
|
||||||
|
persistentSettings.blockchainDataDir = dataDir
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel
|
||||||
|
confirmationDialog.onRejectedCallback = function() {
|
||||||
|
};
|
||||||
|
|
||||||
|
confirmationDialog.open()
|
||||||
|
} else {
|
||||||
|
persistentSettings.blockchainDataDir = dataDir
|
||||||
|
}
|
||||||
|
|
||||||
|
delete validator;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
onRejected: {
|
||||||
|
console.log("data dir selection canceled")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// fires on every page load
|
// fires on every page load
|
||||||
function onPageCompleted() {
|
function onPageCompleted() {
|
||||||
console.log("Settings page loaded");
|
console.log("Settings page loaded");
|
||||||
initSettings();
|
initSettings();
|
||||||
|
viewOnly = currentWallet.viewOnly;
|
||||||
|
|
||||||
|
if(typeof daemonManager != "undefined")
|
||||||
|
appWindow.daemonRunning = daemonManager.running(persistentSettings.testnet)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fires only once
|
// fires only once
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
daemonManager.daemonConsoleUpdated.connect(onDaemonConsoleUpdated)
|
if(typeof daemonManager != "undefined")
|
||||||
|
daemonManager.daemonConsoleUpdated.connect(onDaemonConsoleUpdated)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDaemonConsoleUpdated(message){
|
function onDaemonConsoleUpdated(message){
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ Rectangle {
|
|||||||
id: mainLayout
|
id: mainLayout
|
||||||
|
|
||||||
property int labelWidth: 120
|
property int labelWidth: 120
|
||||||
property int editWidth: 400
|
// property int editWidth: 400
|
||||||
property int lineEditFontSize: 12
|
property int lineEditFontSize: 12
|
||||||
|
|
||||||
color: "#F0EEEE"
|
color: "#F0EEEE"
|
||||||
@@ -92,7 +92,7 @@ Rectangle {
|
|||||||
|
|
||||||
// sign / verify
|
// sign / verify
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.margins: 10
|
anchors.margins: 17
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
@@ -100,21 +100,9 @@ Rectangle {
|
|||||||
|
|
||||||
spacing: 20
|
spacing: 20
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: signBox
|
|
||||||
color: "#00000000"
|
|
||||||
border.width: 2
|
|
||||||
border.color: "#CCCCCC"
|
|
||||||
anchors.margins: -15
|
|
||||||
}
|
|
||||||
|
|
||||||
// sign
|
// sign
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: signBox
|
id: signBox
|
||||||
anchors.margins: 40
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
@@ -122,6 +110,7 @@ Rectangle {
|
|||||||
Label {
|
Label {
|
||||||
text: qsTr("Sign a message or file contents with your address:") + translationManager.emptyString
|
text: qsTr("Sign a message or file contents with your address:") + translationManager.emptyString
|
||||||
fontSize: 16
|
fontSize: 16
|
||||||
|
wrapMode: Text.Wrap
|
||||||
}
|
}
|
||||||
Label {}
|
Label {}
|
||||||
}
|
}
|
||||||
@@ -147,7 +136,7 @@ Rectangle {
|
|||||||
fontSize: mainLayout.lineEditFontSize
|
fontSize: mainLayout.lineEditFontSize
|
||||||
placeholderText: qsTr("Message to sign") + translationManager.emptyString;
|
placeholderText: qsTr("Message to sign") + translationManager.emptyString;
|
||||||
readOnly: false
|
readOnly: false
|
||||||
Layout.fillWidth: true
|
// Layout.fillWidth: true
|
||||||
onTextChanged: signSignatureLine.text = ""
|
onTextChanged: signSignatureLine.text = ""
|
||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
@@ -164,7 +153,7 @@ Rectangle {
|
|||||||
id: signMessageButton
|
id: signMessageButton
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
width: 60
|
width: 60
|
||||||
text: qsTr("SIGN") + translationManager.emptyString
|
text: qsTr("Sign") + translationManager.emptyString
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
@@ -192,7 +181,7 @@ Rectangle {
|
|||||||
|
|
||||||
FileDialog {
|
FileDialog {
|
||||||
id: signFileDialog
|
id: signFileDialog
|
||||||
title: "Please choose a file to sign"
|
title: qsTr("Please choose a file to sign") + translationManager.emptyString;
|
||||||
folder: "file://"
|
folder: "file://"
|
||||||
nameFilters: [ "*"]
|
nameFilters: [ "*"]
|
||||||
|
|
||||||
@@ -205,7 +194,7 @@ Rectangle {
|
|||||||
id: loadFileToSignButton
|
id: loadFileToSignButton
|
||||||
anchors.rightMargin: 17
|
anchors.rightMargin: 17
|
||||||
width: 60
|
width: 60
|
||||||
text: qsTr("SELECT") + translationManager.emptyString
|
text: qsTr("Select") + translationManager.emptyString
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
@@ -239,7 +228,7 @@ Rectangle {
|
|||||||
id: signFileButton
|
id: signFileButton
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
width: 60
|
width: 60
|
||||||
text: qsTr("SIGN") + translationManager.emptyString
|
text: qsTr("Sign") + translationManager.emptyString
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
@@ -254,21 +243,16 @@ Rectangle {
|
|||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: signSignatureRow
|
id: signSignatureRow
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
id: signSignatureLabel
|
id: signSignatureLabel
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
text: qsTr("Signature") + translationManager.emptyString
|
text: qsTr("Signature") + translationManager.emptyString
|
||||||
width: mainLayout.labelWidth
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LineEdit {
|
LineEdit {
|
||||||
id: signSignatureLine
|
id: signSignatureLine
|
||||||
anchors.left: signSignatureLabel.right
|
|
||||||
anchors.right: parent.right
|
|
||||||
fontSize: mainLayout.lineEditFontSize
|
fontSize: mainLayout.lineEditFontSize
|
||||||
placeholderText: qsTr("Signature") + translationManager.emptyString;
|
placeholderText: qsTr("Signature") + translationManager.emptyString;
|
||||||
readOnly: true
|
readOnly: true
|
||||||
@@ -286,21 +270,10 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: verifyBox
|
|
||||||
color: "#00000000"
|
|
||||||
border.width: 2
|
|
||||||
border.color: "#CCCCCC"
|
|
||||||
anchors.margins: -15
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: verifyBox
|
id: verifyBox
|
||||||
anchors.margins: 40
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: signBox.bottom
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
@@ -308,6 +281,8 @@ Rectangle {
|
|||||||
Label {
|
Label {
|
||||||
text: qsTr("Verify a message or file signature from an address:") + translationManager.emptyString
|
text: qsTr("Verify a message or file signature from an address:") + translationManager.emptyString
|
||||||
fontSize: 16
|
fontSize: 16
|
||||||
|
// Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
}
|
}
|
||||||
Label {}
|
Label {}
|
||||||
}
|
}
|
||||||
@@ -349,7 +324,7 @@ Rectangle {
|
|||||||
id: verifyMessageButton
|
id: verifyMessageButton
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
width: 60
|
width: 60
|
||||||
text: qsTr("VERIFY") + translationManager.emptyString
|
text: qsTr("Verify") + translationManager.emptyString
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
@@ -377,7 +352,7 @@ Rectangle {
|
|||||||
|
|
||||||
FileDialog {
|
FileDialog {
|
||||||
id: verifyFileDialog
|
id: verifyFileDialog
|
||||||
title: "Please choose a file to verify"
|
title: qsTr("Please choose a file to verify") + translationManager.emptyString;
|
||||||
folder: "file://"
|
folder: "file://"
|
||||||
nameFilters: [ "*"]
|
nameFilters: [ "*"]
|
||||||
|
|
||||||
@@ -390,7 +365,7 @@ Rectangle {
|
|||||||
id: loadFileToVerifyButton
|
id: loadFileToVerifyButton
|
||||||
anchors.rightMargin: 17
|
anchors.rightMargin: 17
|
||||||
width: 60
|
width: 60
|
||||||
text: qsTr("SELECT") + translationManager.emptyString
|
text: qsTr("Select") + translationManager.emptyString
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
@@ -423,7 +398,7 @@ Rectangle {
|
|||||||
id: verifyFileButton
|
id: verifyFileButton
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
width: 60
|
width: 60
|
||||||
text: qsTr("VERIFY") + translationManager.emptyString
|
text: qsTr("Verify") + translationManager.emptyString
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
@@ -444,6 +419,8 @@ Rectangle {
|
|||||||
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
|
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
|
||||||
Signing address <font size='2'> ( Paste in or select from </font> <a href='#'>Address book</a><font size='2'> )</font>")
|
Signing address <font size='2'> ( Paste in or select from </font> <a href='#'>Address book</a><font size='2'> )</font>")
|
||||||
+ translationManager.emptyString
|
+ translationManager.emptyString
|
||||||
|
// Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
|
||||||
onLinkActivated: appWindow.showPageRequest("AddressBook")
|
onLinkActivated: appWindow.showPageRequest("AddressBook")
|
||||||
}
|
}
|
||||||
@@ -460,21 +437,16 @@ Rectangle {
|
|||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: verifySignatureRow
|
id: verifySignatureRow
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
id: verifySignatureLabel
|
id: verifySignatureLabel
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
text: qsTr("Signature") + translationManager.emptyString
|
text: qsTr("Signature") + translationManager.emptyString
|
||||||
width: mainLayout.labelWidth
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LineEdit {
|
LineEdit {
|
||||||
id: verifySignatureLine
|
id: verifySignatureLine
|
||||||
anchors.left: verifySignatureLabel.right
|
|
||||||
anchors.right: parent.right
|
|
||||||
fontSize: mainLayout.lineEditFontSize
|
fontSize: mainLayout.lineEditFontSize
|
||||||
placeholderText: qsTr("Signature") + translationManager.emptyString;
|
placeholderText: qsTr("Signature") + translationManager.emptyString;
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|||||||
@@ -41,10 +41,11 @@ Rectangle {
|
|||||||
signal sweepUnmixableClicked()
|
signal sweepUnmixableClicked()
|
||||||
|
|
||||||
color: "#F0EEEE"
|
color: "#F0EEEE"
|
||||||
property string startLinkText: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style><font size='2'> (</font><a href='#'>Start daemon</a><font size='2'>)</font>"
|
property string startLinkText: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style><font size='2'> (</font><a href='#'>Start daemon</a><font size='2'>)</font>") + translationManager.emptyString
|
||||||
|
property bool showAdvanced: false
|
||||||
|
|
||||||
function scaleValueToMixinCount(scaleValue) {
|
function scaleValueToMixinCount(scaleValue) {
|
||||||
var scaleToMixinCount = [4,5,6,7,8,9,10,11,12,13,14,15,20,25];
|
var scaleToMixinCount = [4,5,6,7,8,9,10,11,12,14,16,18,21,25];
|
||||||
if (scaleValue < scaleToMixinCount.length) {
|
if (scaleValue < scaleToMixinCount.length) {
|
||||||
return scaleToMixinCount[scaleValue];
|
return scaleToMixinCount[scaleValue];
|
||||||
} else {
|
} else {
|
||||||
@@ -69,6 +70,30 @@ Rectangle {
|
|||||||
oaPopup.open()
|
oaPopup.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateMixin() {
|
||||||
|
var fillLevel = privacyLevelItem.fillLevel
|
||||||
|
var mixin = scaleValueToMixinCount(fillLevel)
|
||||||
|
print ("PrivacyLevel changed:" + fillLevel)
|
||||||
|
print ("mixin count: " + mixin)
|
||||||
|
privacyLabel.text = qsTr("Privacy level (ringsize %1)").arg(mixin+1) + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateFromQrCode(address, payment_id, amount, tx_description, recipient_name) {
|
||||||
|
console.log("updateFromQrCode")
|
||||||
|
addressLine.text = address
|
||||||
|
paymentIdLine.text = payment_id
|
||||||
|
amountLine.text = amount
|
||||||
|
descriptionLine.text = recipient_name + " " + tx_description
|
||||||
|
cameraUi.qrcode_decoded.disconnect(updateFromQrCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearFields() {
|
||||||
|
addressLine.text = ""
|
||||||
|
paymentIdLine.text = ""
|
||||||
|
amountLine.text = ""
|
||||||
|
descriptionLine.text = ""
|
||||||
|
}
|
||||||
|
|
||||||
// Information dialog
|
// Information dialog
|
||||||
StandardDialog {
|
StandardDialog {
|
||||||
// dynamically change onclose handler
|
// dynamically change onclose handler
|
||||||
@@ -84,331 +109,317 @@ Rectangle {
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: pageRoot
|
id: pageRoot
|
||||||
anchors.fill: parent
|
anchors.top: parent.top
|
||||||
Label {
|
anchors.left: parent.left
|
||||||
id: amountLabel
|
anchors.right: parent.right
|
||||||
anchors.left: parent.left
|
anchors.topMargin: 20
|
||||||
anchors.top: parent.top
|
height: 400
|
||||||
anchors.leftMargin: 17
|
|
||||||
anchors.rightMargin: 17
|
|
||||||
anchors.topMargin: 17
|
|
||||||
text: qsTr("Amount") + translationManager.emptyString
|
|
||||||
fontSize: 14
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
id: transactionPriority
|
id: amountLabel
|
||||||
anchors.top: parent.top
|
anchors.left: parent.left
|
||||||
anchors.topMargin: 17
|
anchors.top: parent.top
|
||||||
fontSize: 14
|
anchors.leftMargin: 17
|
||||||
x: (parent.width - 17) / 2 + 17
|
anchors.rightMargin: 17
|
||||||
text: qsTr("Transaction priority") + translationManager.emptyString
|
anchors.topMargin: 17
|
||||||
}
|
text: qsTr("Amount") + translationManager.emptyString
|
||||||
|
fontSize: 14
|
||||||
|
}
|
||||||
|
|
||||||
Row {
|
Label {
|
||||||
id: amountRow
|
id: transactionPriority
|
||||||
anchors.top: amountLabel.bottom
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 5
|
anchors.topMargin: 17
|
||||||
anchors.left: parent.left
|
fontSize: 14
|
||||||
anchors.leftMargin: 7
|
x: (parent.width - 17) / 2 + 17
|
||||||
width: (parent.width - 17) / 2 + 10
|
text: qsTr("Transaction priority") + translationManager.emptyString
|
||||||
Item {
|
}
|
||||||
width: 37
|
|
||||||
height: 37
|
|
||||||
|
|
||||||
Image {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
source: "../images/moneroIcon.png"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Amount input
|
|
||||||
LineEdit {
|
|
||||||
id: amountLine
|
|
||||||
placeholderText: qsTr("") + translationManager.emptyString
|
|
||||||
width: parent.width - 37 - 17 - 60
|
|
||||||
validator: DoubleValidator {
|
|
||||||
bottom: 0.0
|
|
||||||
top: 18446744.073709551615
|
|
||||||
decimals: 12
|
|
||||||
notation: DoubleValidator.StandardNotation
|
|
||||||
locale: "C"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StandardButton {
|
|
||||||
id: amountAllButton
|
|
||||||
//anchors.left: amountLine.right
|
|
||||||
//anchors.top: amountLine.top
|
|
||||||
//anchors.bottom: amountLine.bottom
|
|
||||||
width: 60
|
|
||||||
text: qsTr("or ALL") + translationManager.emptyString
|
|
||||||
shadowReleasedColor: "#FF4304"
|
|
||||||
shadowPressedColor: "#B32D00"
|
|
||||||
releasedColor: "#FF6C3C"
|
|
||||||
pressedColor: "#FF4304"
|
|
||||||
enabled : true
|
|
||||||
onClicked: amountLine.text = "(all)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: priorityModel
|
|
||||||
// ListElement: cannot use script for property value, so
|
|
||||||
// code like this wont work:
|
|
||||||
// ListElement { column1: qsTr("LOW") + translationManager.emptyString ; column2: ""; priority: PendingTransaction.Priority_Low }
|
|
||||||
|
|
||||||
ListElement { column1: qsTr("LOW (x1 fee)") ; column2: ""; priority: PendingTransaction.Priority_Low }
|
|
||||||
ListElement { column1: qsTr("MEDIUM (x20 fee)") ; column2: ""; priority: PendingTransaction.Priority_Medium }
|
|
||||||
ListElement { column1: qsTr("HIGH (x166 fee)") ; column2: ""; priority: PendingTransaction.Priority_High }
|
|
||||||
}
|
|
||||||
|
|
||||||
StandardDropdown {
|
|
||||||
id: priorityDropdown
|
|
||||||
anchors.top: transactionPriority.bottom
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 17
|
|
||||||
anchors.topMargin: 5
|
|
||||||
anchors.left: transactionPriority.left
|
|
||||||
shadowReleasedColor: "#FF4304"
|
|
||||||
shadowPressedColor: "#B32D00"
|
|
||||||
releasedColor: "#FF6C3C"
|
|
||||||
pressedColor: "#FF4304"
|
|
||||||
dataModel: priorityModel
|
|
||||||
z: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: amountRow
|
||||||
|
anchors.top: amountLabel.bottom
|
||||||
|
anchors.topMargin: 5
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 7
|
||||||
|
width: (parent.width - 17) / 2 + 10
|
||||||
|
Item {
|
||||||
|
width: 37
|
||||||
|
height: 37
|
||||||
|
|
||||||
Label {
|
Image {
|
||||||
id: privacyLabel
|
anchors.centerIn: parent
|
||||||
anchors.left: parent.left
|
source: "../images/moneroIcon.png"
|
||||||
anchors.right: parent.right
|
}
|
||||||
anchors.top: amountRow.bottom
|
}
|
||||||
anchors.leftMargin: 17
|
// Amount input
|
||||||
anchors.rightMargin: 17
|
LineEdit {
|
||||||
anchors.topMargin: 30
|
id: amountLine
|
||||||
fontSize: 14
|
placeholderText: qsTr("") + translationManager.emptyString
|
||||||
text: qsTr("Privacy level") + translationManager.emptyString
|
width: parent.width - 37 - 17 - 60
|
||||||
}
|
validator: DoubleValidator {
|
||||||
|
bottom: 0.0
|
||||||
|
top: 18446744.073709551615
|
||||||
|
decimals: 12
|
||||||
|
notation: DoubleValidator.StandardNotation
|
||||||
|
locale: "C"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PrivacyLevel {
|
StandardButton {
|
||||||
id: privacyLevelItem
|
id: amountAllButton
|
||||||
anchors.left: parent.left
|
//anchors.left: amountLine.right
|
||||||
anchors.right: parent.right
|
//anchors.top: amountLine.top
|
||||||
anchors.top: privacyLabel.bottom
|
//anchors.bottom: amountLine.bottom
|
||||||
anchors.leftMargin: 17
|
width: 60
|
||||||
anchors.rightMargin: 17
|
text: qsTr("All") + translationManager.emptyString
|
||||||
anchors.topMargin: 5
|
shadowReleasedColor: "#FF4304"
|
||||||
onFillLevelChanged: {
|
shadowPressedColor: "#B32D00"
|
||||||
print ("PrivacyLevel changed:" + fillLevel)
|
releasedColor: "#FF6C3C"
|
||||||
print ("mixin count:" + scaleValueToMixinCount(fillLevel))
|
pressedColor: "#FF4304"
|
||||||
}
|
enabled : true
|
||||||
}
|
onClicked: amountLine.text = "(all)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Label {
|
// Note: workaround for translations in listElements
|
||||||
id: costLabel
|
// ListElement: cannot use script for property value, so
|
||||||
anchors.right: parent.right
|
// code like this wont work:
|
||||||
anchors.top: amountRow.bottom
|
// ListElement { column1: qsTr("LOW") + translationManager.emptyString ; column2: ""; priority: PendingTransaction.Priority_Low }
|
||||||
anchors.leftMargin: 17
|
// For translations to work, the strings need to be listed in
|
||||||
anchors.rightMargin: 17
|
// the file components/StandardDropdown.qml too.
|
||||||
anchors.topMargin: 30
|
|
||||||
fontSize: 14
|
|
||||||
text: qsTr("Transaction cost")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Priorities before v5
|
||||||
|
ListModel {
|
||||||
|
id: priorityModel
|
||||||
|
|
||||||
Label {
|
ListElement { column1: qsTr("Low (x1 fee)") ; column2: ""; priority: PendingTransaction.Priority_Low }
|
||||||
id: addressLabel
|
ListElement { column1: qsTr("Medium (x20 fee)") ; column2: ""; priority: PendingTransaction.Priority_Medium }
|
||||||
anchors.left: parent.left
|
ListElement { column1: qsTr("High (x166 fee)") ; column2: ""; priority: PendingTransaction.Priority_High }
|
||||||
anchors.right: parent.right
|
}
|
||||||
anchors.top: privacyLevelItem.bottom
|
|
||||||
anchors.leftMargin: 17
|
|
||||||
anchors.rightMargin: 17
|
|
||||||
anchors.topMargin: 30
|
|
||||||
fontSize: 14
|
|
||||||
textFormat: Text.RichText
|
|
||||||
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
|
|
||||||
Address <font size='2'> ( Paste in or select from </font> <a href='#'>Address book</a><font size='2'> )</font>")
|
|
||||||
+ translationManager.emptyString
|
|
||||||
|
|
||||||
onLinkActivated: appWindow.showPageRequest("AddressBook")
|
// Priorites after v5
|
||||||
}
|
ListModel {
|
||||||
// recipient address input
|
id: priorityModelV5
|
||||||
RowLayout {
|
|
||||||
id: addressLineRow
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: addressLabel.bottom
|
|
||||||
|
|
||||||
LineEdit {
|
ListElement { column1: qsTr("Slow (x0.25 fee)") ; column2: ""; priority: 1}
|
||||||
id: addressLine
|
ListElement { column1: qsTr("Default (x1 fee)") ; column2: ""; priority: 2 }
|
||||||
anchors.left: parent.left
|
ListElement { column1: qsTr("Fast (x5 fee)") ; column2: ""; priority: 3 }
|
||||||
anchors.right: resolveButton.left
|
ListElement { column1: qsTr("Fastest (x41.5 fee)") ; column2: ""; priority: 4 }
|
||||||
anchors.leftMargin: 17
|
|
||||||
anchors.topMargin: 5
|
|
||||||
placeholderText: "4..."
|
|
||||||
// validator: RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g }
|
|
||||||
}
|
|
||||||
|
|
||||||
StandardButton {
|
}
|
||||||
id: resolveButton
|
|
||||||
anchors.right: parent.right
|
StandardDropdown {
|
||||||
anchors.leftMargin: 17
|
id: priorityDropdown
|
||||||
anchors.topMargin: 17
|
anchors.top: transactionPriority.bottom
|
||||||
anchors.rightMargin: 17
|
anchors.right: parent.right
|
||||||
width: 60
|
anchors.rightMargin: 17
|
||||||
text: qsTr("RESOLVE") + translationManager.emptyString
|
anchors.topMargin: 5
|
||||||
shadowReleasedColor: "#FF4304"
|
anchors.left: transactionPriority.left
|
||||||
shadowPressedColor: "#B32D00"
|
shadowReleasedColor: "#FF4304"
|
||||||
releasedColor: "#FF6C3C"
|
shadowPressedColor: "#B32D00"
|
||||||
pressedColor: "#FF4304"
|
releasedColor: "#FF6C3C"
|
||||||
enabled : isValidOpenAliasAddress(addressLine.text)
|
pressedColor: "#FF4304"
|
||||||
onClicked: {
|
z: 1
|
||||||
var result = walletManager.resolveOpenAlias(addressLine.text)
|
}
|
||||||
if (result) {
|
|
||||||
var parts = result.split("|")
|
Label {
|
||||||
if (parts.length == 2) {
|
id: addressLabel
|
||||||
var address_ok = walletManager.addressValid(parts[1], appWindow.persistentSettings.testnet)
|
anchors.left: parent.left
|
||||||
if (parts[0] === "true") {
|
anchors.right: parent.right
|
||||||
if (address_ok) {
|
anchors.top: amountRow.bottom
|
||||||
addressLine.text = parts[1]
|
anchors.leftMargin: 17
|
||||||
addressLine.cursorPosition = 0
|
anchors.rightMargin: 17
|
||||||
}
|
anchors.topMargin: 30
|
||||||
else
|
fontSize: 14
|
||||||
oa_message(qsTr("No valid address found at this OpenAlias address"))
|
textFormat: Text.RichText
|
||||||
} else if (parts[0] === "false") {
|
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style>\
|
||||||
if (address_ok) {
|
Address <font size='2'> ( Paste in or select from </font> <a href='#'>Address book</a><font size='2'> )</font>")
|
||||||
addressLine.text = parts[1]
|
+ translationManager.emptyString
|
||||||
addressLine.cursorPosition = 0
|
|
||||||
oa_message(qsTr("Address found, but the DNSSEC signatures could not be verified, so this address may be spoofed"))
|
onLinkActivated: appWindow.showPageRequest("AddressBook")
|
||||||
|
}
|
||||||
|
// recipient address input
|
||||||
|
RowLayout {
|
||||||
|
id: addressLineRow
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: addressLabel.bottom
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
id: qrfinderButton
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 17
|
||||||
|
anchors.topMargin: 5
|
||||||
|
text: qsTr("QR Code") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
visible : appWindow.qrScannerEnabled
|
||||||
|
enabled : visible
|
||||||
|
width: visible ? 60 : 0
|
||||||
|
onClicked: {
|
||||||
|
cameraUi.state = "Capture"
|
||||||
|
cameraUi.qrcode_decoded.connect(updateFromQrCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LineEdit {
|
||||||
|
id: addressLine
|
||||||
|
anchors.left: qrfinderButton.right
|
||||||
|
anchors.right: resolveButton.left
|
||||||
|
//anchors.leftMargin: 17
|
||||||
|
anchors.topMargin: 5
|
||||||
|
placeholderText: "4..."
|
||||||
|
// validator: RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g }
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
id: resolveButton
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.leftMargin: 17
|
||||||
|
anchors.topMargin: 17
|
||||||
|
anchors.rightMargin: 17
|
||||||
|
width: 60
|
||||||
|
text: qsTr("Resolve") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
enabled : isValidOpenAliasAddress(addressLine.text)
|
||||||
|
onClicked: {
|
||||||
|
var result = walletManager.resolveOpenAlias(addressLine.text)
|
||||||
|
if (result) {
|
||||||
|
var parts = result.split("|")
|
||||||
|
if (parts.length == 2) {
|
||||||
|
var address_ok = walletManager.addressValid(parts[1], appWindow.persistentSettings.testnet)
|
||||||
|
if (parts[0] === "true") {
|
||||||
|
if (address_ok) {
|
||||||
|
addressLine.text = parts[1]
|
||||||
|
addressLine.cursorPosition = 0
|
||||||
|
}
|
||||||
|
else
|
||||||
|
oa_message(qsTr("No valid address found at this OpenAlias address"))
|
||||||
|
} else if (parts[0] === "false") {
|
||||||
|
if (address_ok) {
|
||||||
|
addressLine.text = parts[1]
|
||||||
|
addressLine.cursorPosition = 0
|
||||||
|
oa_message(qsTr("Address found, but the DNSSEC signatures could not be verified, so this address may be spoofed"))
|
||||||
|
} else {
|
||||||
|
oa_message(qsTr("No valid address found at this OpenAlias address, but the DNSSEC signatures could not be verified, so this may be spoofed"))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
oa_message(qsTr("No valid address found at this OpenAlias address, but the DNSSEC signatures could not be verified, so this may be spoofed"))
|
oa_message(qsTr("Internal error"))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
oa_message(qsTr("Internal error"))
|
oa_message(qsTr("Internal error"))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
oa_message(qsTr("Internal error"))
|
oa_message(qsTr("No address found"))
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
oa_message(qsTr("No address found"))
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
id: paymentIdLabel
|
id: paymentIdLabel
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: addressLineRow.bottom
|
anchors.top: addressLineRow.bottom
|
||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
anchors.rightMargin: 17
|
anchors.rightMargin: 17
|
||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
text: qsTr("Payment ID <font size='2'>( Optional )</font>") + translationManager.emptyString
|
text: qsTr("Payment ID <font size='2'>( Optional )</font>") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
// payment id input
|
// payment id input
|
||||||
LineEdit {
|
LineEdit {
|
||||||
id: paymentIdLine
|
id: paymentIdLine
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: paymentIdLabel.bottom
|
anchors.top: paymentIdLabel.bottom
|
||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
anchors.rightMargin: 17
|
anchors.rightMargin: 17
|
||||||
anchors.topMargin: 5
|
anchors.topMargin: 5
|
||||||
placeholderText: qsTr("16 or 64 hexadecimal characters") + translationManager.emptyString
|
placeholderText: qsTr("16 or 64 hexadecimal characters") + translationManager.emptyString
|
||||||
// validator: DoubleValidator { top: 0.0 }
|
// validator: DoubleValidator { top: 0.0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
id: descriptionLabel
|
id: descriptionLabel
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: paymentIdLine.bottom
|
anchors.top: paymentIdLine.bottom
|
||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
anchors.rightMargin: 17
|
anchors.rightMargin: 17
|
||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
fontSize: 14
|
fontSize: 14
|
||||||
text: qsTr("Description <font size='2'>( Optional - saved to local wallet history )</font>")
|
text: qsTr("Description <font size='2'>( Optional )</font>")
|
||||||
+ translationManager.emptyString
|
+ translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
LineEdit {
|
LineEdit {
|
||||||
id: descriptionLine
|
id: descriptionLine
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: descriptionLabel.bottom
|
anchors.top: descriptionLabel.bottom
|
||||||
anchors.leftMargin: 17
|
anchors.leftMargin: 17
|
||||||
anchors.rightMargin: 17
|
anchors.rightMargin: 17
|
||||||
anchors.topMargin: 5
|
anchors.topMargin: 5
|
||||||
}
|
placeholderText: qsTr("Saved to local wallet history") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
function checkInformation(amount, address, payment_id, testnet) {
|
function checkInformation(amount, address, payment_id, testnet) {
|
||||||
address = address.trim()
|
address = address.trim()
|
||||||
payment_id = payment_id.trim()
|
payment_id = payment_id.trim()
|
||||||
|
|
||||||
var amount_ok = amount.length > 0
|
var amount_ok = amount.length > 0
|
||||||
var address_ok = walletManager.addressValid(address, testnet)
|
var address_ok = walletManager.addressValid(address, testnet)
|
||||||
var payment_id_ok = payment_id.length == 0 || walletManager.paymentIdValid(payment_id)
|
var payment_id_ok = payment_id.length == 0 || walletManager.paymentIdValid(payment_id)
|
||||||
var ipid = walletManager.paymentIdFromAddress(address, testnet)
|
var ipid = walletManager.paymentIdFromAddress(address, testnet)
|
||||||
if (ipid.length > 0 && payment_id.length > 0)
|
if (ipid.length > 0 && payment_id.length > 0)
|
||||||
payment_id_ok = false
|
payment_id_ok = false
|
||||||
|
|
||||||
addressLine.error = !address_ok
|
addressLine.error = !address_ok
|
||||||
amountLine.error = !amount_ok
|
amountLine.error = !amount_ok
|
||||||
paymentIdLine.error = !payment_id_ok
|
paymentIdLine.error = !payment_id_ok
|
||||||
|
|
||||||
return amount_ok && address_ok && payment_id_ok
|
return amount_ok && address_ok && payment_id_ok
|
||||||
}
|
}
|
||||||
|
|
||||||
StandardButton {
|
|
||||||
id: sendButton
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.top: descriptionLine.bottom
|
|
||||||
anchors.leftMargin: 17
|
|
||||||
anchors.topMargin: 17
|
|
||||||
width: 60
|
|
||||||
text: qsTr("SEND") + translationManager.emptyString
|
|
||||||
shadowReleasedColor: "#FF4304"
|
|
||||||
shadowPressedColor: "#B32D00"
|
|
||||||
releasedColor: "#FF6C3C"
|
|
||||||
pressedColor: "#FF4304"
|
|
||||||
enabled : pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
|
|
||||||
onClicked: {
|
|
||||||
console.log("Transfer: paymentClicked")
|
|
||||||
var priority = priorityModel.get(priorityDropdown.currentIndex).priority
|
|
||||||
console.log("priority: " + priority)
|
|
||||||
console.log("amount: " + amountLine.text)
|
|
||||||
addressLine.text = addressLine.text.trim()
|
|
||||||
paymentIdLine.text = paymentIdLine.text.trim()
|
|
||||||
root.paymentClicked(addressLine.text, paymentIdLine.text, amountLine.text, scaleValueToMixinCount(privacyLevelItem.fillLevel),
|
|
||||||
priority, descriptionLine.text)
|
|
||||||
|
|
||||||
}
|
RowLayout {
|
||||||
}
|
anchors.left: parent.left
|
||||||
|
anchors.top: descriptionLine.bottom
|
||||||
|
anchors.leftMargin: 17
|
||||||
|
anchors.topMargin: 17
|
||||||
|
|
||||||
StandardButton {
|
StandardButton {
|
||||||
id: sweepUnmixableButton
|
id: sendButton
|
||||||
anchors.right: parent.right
|
text: qsTr("Send") + translationManager.emptyString
|
||||||
anchors.top: descriptionLine.bottom
|
shadowReleasedColor: "#FF4304"
|
||||||
anchors.rightMargin: 17
|
shadowPressedColor: "#B32D00"
|
||||||
anchors.topMargin: 17
|
releasedColor: "#FF6C3C"
|
||||||
width: 60*2
|
pressedColor: "#FF4304"
|
||||||
text: qsTr("SWEEP UNMIXABLE") + translationManager.emptyString
|
enabled : !appWindow.viewOnly && pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
|
||||||
shadowReleasedColor: "#FF4304"
|
onClicked: {
|
||||||
shadowPressedColor: "#B32D00"
|
console.log("Transfer: paymentClicked")
|
||||||
releasedColor: "#FF6C3C"
|
var priority = priorityModel.get(priorityDropdown.currentIndex).priority
|
||||||
pressedColor: "#FF4304"
|
console.log("priority: " + priority)
|
||||||
enabled : true
|
console.log("amount: " + amountLine.text)
|
||||||
onClicked: {
|
addressLine.text = addressLine.text.trim()
|
||||||
console.log("Transfer: sweepUnmixableClicked")
|
paymentIdLine.text = paymentIdLine.text.trim()
|
||||||
root.sweepUnmixableClicked()
|
root.paymentClicked(addressLine.text, paymentIdLine.text, amountLine.text, scaleValueToMixinCount(privacyLevelItem.fillLevel),
|
||||||
|
priority, descriptionLine.text)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // pageRoot
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id:desaturate
|
id:desaturate
|
||||||
@@ -417,7 +428,231 @@ Rectangle {
|
|||||||
opacity: 0.1
|
opacity: 0.1
|
||||||
visible: (pageRoot.enabled)? 0 : 1;
|
visible: (pageRoot.enabled)? 0 : 1;
|
||||||
}
|
}
|
||||||
} // Rectangle
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.top: pageRoot.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.margins: 17
|
||||||
|
spacing:10
|
||||||
|
enabled: !viewOnly || pageRoot.enabled
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
CheckBox {
|
||||||
|
id: showAdvancedCheckbox
|
||||||
|
checked: persistentSettings.transferShowAdvanced
|
||||||
|
onClicked: {
|
||||||
|
persistentSettings.transferShowAdvanced = !persistentSettings.transferShowAdvanced
|
||||||
|
}
|
||||||
|
text: qsTr("Show advanced options") + translationManager.emptyString
|
||||||
|
checkedIcon: "../images/checkedVioletIcon.png"
|
||||||
|
uncheckedIcon: "../images/uncheckedIcon.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
visible: persistentSettings.transferShowAdvanced
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 1
|
||||||
|
color: "#DEDEDE"
|
||||||
|
Layout.bottomMargin: 30
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
visible: persistentSettings.transferShowAdvanced
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
Label {
|
||||||
|
id: privacyLabel
|
||||||
|
fontSize: 14
|
||||||
|
text: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: costLabel
|
||||||
|
fontSize: 14
|
||||||
|
text: qsTr("Transaction cost") + translationManager.emptyString
|
||||||
|
anchors.right: parent.right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PrivacyLevel {
|
||||||
|
visible: persistentSettings.transferShowAdvanced
|
||||||
|
id: privacyLevelItem
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
onFillLevelChanged: updateMixin()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
visible: persistentSettings.transferShowAdvanced
|
||||||
|
Layout.topMargin: 50
|
||||||
|
|
||||||
|
|
||||||
|
columns: (isMobile) ? 2 : 6
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
id: sweepUnmixableButton
|
||||||
|
text: qsTr("Sweep Unmixable") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
enabled : pageRoot.enabled
|
||||||
|
onClicked: {
|
||||||
|
console.log("Transfer: sweepUnmixableClicked")
|
||||||
|
root.sweepUnmixableClicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
id: saveTxButton
|
||||||
|
text: qsTr("Create tx file") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
visible: appWindow.viewOnly
|
||||||
|
enabled: pageRoot.checkInformation(amountLine.text, addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
|
||||||
|
onClicked: {
|
||||||
|
console.log("Transfer: saveTx Clicked")
|
||||||
|
var priority = priorityModel.get(priorityDropdown.currentIndex).priority
|
||||||
|
console.log("priority: " + priority)
|
||||||
|
console.log("amount: " + amountLine.text)
|
||||||
|
addressLine.text = addressLine.text.trim()
|
||||||
|
paymentIdLine.text = paymentIdLine.text.trim()
|
||||||
|
root.paymentClicked(addressLine.text, paymentIdLine.text, amountLine.text, scaleValueToMixinCount(privacyLevelItem.fillLevel),
|
||||||
|
priority, descriptionLine.text)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
id: signTxButton
|
||||||
|
text: qsTr("Sign tx file") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
visible: !appWindow.viewOnly
|
||||||
|
onClicked: {
|
||||||
|
console.log("Transfer: sign tx clicked")
|
||||||
|
signTxDialog.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StandardButton {
|
||||||
|
id: submitTxButton
|
||||||
|
text: qsTr("Submit tx file") + translationManager.emptyString
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#FF6C3C"
|
||||||
|
pressedColor: "#FF4304"
|
||||||
|
visible: appWindow.viewOnly
|
||||||
|
enabled: pageRoot.enabled
|
||||||
|
onClicked: {
|
||||||
|
console.log("Transfer: submit tx clicked")
|
||||||
|
submitTxDialog.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//SignTxDialog
|
||||||
|
FileDialog {
|
||||||
|
id: signTxDialog
|
||||||
|
title: qsTr("Please choose a file") + translationManager.emptyString
|
||||||
|
folder: "file://" +moneroAccountsDir
|
||||||
|
nameFilters: [ "Unsigned transfers (*)"]
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
var path = walletManager.urlToLocalPath(fileUrl);
|
||||||
|
// Load the unsigned tx from file
|
||||||
|
var transaction = currentWallet.loadTxFile(path);
|
||||||
|
|
||||||
|
if (transaction.status !== PendingTransaction.Status_Ok) {
|
||||||
|
console.error("Can't load unsigned transaction: ", transaction.errorString);
|
||||||
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
|
informationPopup.text = qsTr("Can't load unsigned transaction: ") + transaction.errorString
|
||||||
|
informationPopup.icon = StandardIcon.Critical
|
||||||
|
informationPopup.onCloseCallback = null
|
||||||
|
informationPopup.open();
|
||||||
|
// deleting transaction object, we don't want memleaks
|
||||||
|
transaction.destroy();
|
||||||
|
} else {
|
||||||
|
confirmationDialog.text = qsTr("\nNumber of transactions: ") + transaction.txCount
|
||||||
|
for (var i = 0; i < transaction.txCount; ++i) {
|
||||||
|
confirmationDialog.text += qsTr("\nTransaction #%1").arg(i+1)
|
||||||
|
+qsTr("\nRecipient: ") + transaction.recipientAddress[i]
|
||||||
|
+ (transaction.paymentId[i] == "" ? "" : qsTr("\n\payment ID: ") + transaction.paymentId[i])
|
||||||
|
+ qsTr("\nAmount: ") + walletManager.displayAmount(transaction.amount(i))
|
||||||
|
+ qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee(i))
|
||||||
|
+ qsTr("\nRingsize: ") + transaction.mixin(i+1)
|
||||||
|
|
||||||
|
// TODO: add descriptions to unsigned_tx_set?
|
||||||
|
// + (transactionDescription === "" ? "" : (qsTr("\n\nDescription: ") + transactionDescription))
|
||||||
|
+ translationManager.emptyString
|
||||||
|
if (i > 0) {
|
||||||
|
confirmationDialog.text += "\n\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(transaction.confirmationMessage);
|
||||||
|
|
||||||
|
// Show confirmation dialog
|
||||||
|
confirmationDialog.title = qsTr("Confirmation") + translationManager.emptyString
|
||||||
|
confirmationDialog.icon = StandardIcon.Question
|
||||||
|
confirmationDialog.onAcceptedCallback = function() {
|
||||||
|
transaction.sign(path+"_signed");
|
||||||
|
transaction.destroy();
|
||||||
|
};
|
||||||
|
confirmationDialog.onRejectedCallback = transaction.destroy;
|
||||||
|
|
||||||
|
confirmationDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
onRejected: {
|
||||||
|
// File dialog closed
|
||||||
|
console.log("Canceled")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//SignTxDialog
|
||||||
|
FileDialog {
|
||||||
|
id: submitTxDialog
|
||||||
|
title: qsTr("Please choose a file") + translationManager.emptyString
|
||||||
|
folder: "file://" +moneroAccountsDir
|
||||||
|
nameFilters: [ "signed transfers (*)"]
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if(!currentWallet.submitTxFile(walletManager.urlToLocalPath(fileUrl))){
|
||||||
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
|
informationPopup.text = qsTr("Can't submit transaction: ") + currentWallet.errorString
|
||||||
|
informationPopup.icon = StandardIcon.Critical
|
||||||
|
informationPopup.onCloseCallback = null
|
||||||
|
informationPopup.open();
|
||||||
|
} else {
|
||||||
|
informationPopup.title = qsTr("Information") + translationManager.emptyString
|
||||||
|
informationPopup.text = qsTr("Money sent successfully") + translationManager.emptyString
|
||||||
|
informationPopup.icon = StandardIcon.Information
|
||||||
|
informationPopup.onCloseCallback = null
|
||||||
|
informationPopup.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onRejected: {
|
||||||
|
console.log("Canceled")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
x: root.width/2 - width/2
|
x: root.width/2 - width/2
|
||||||
@@ -446,19 +681,32 @@ Rectangle {
|
|||||||
function onPageCompleted() {
|
function onPageCompleted() {
|
||||||
console.log("transfer page loaded")
|
console.log("transfer page loaded")
|
||||||
updateStatus();
|
updateStatus();
|
||||||
|
updateMixin();
|
||||||
|
updatePriorityDropdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePriorityDropdown() {
|
||||||
|
priorityDropdown.dataModel = priorityModelV5;
|
||||||
|
priorityDropdown.currentIndex = 1
|
||||||
|
priorityDropdown.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Add daemon sync status
|
//TODO: Add daemon sync status
|
||||||
//TODO: enable send page when we're connected and daemon is synced
|
//TODO: enable send page when we're connected and daemon is synced
|
||||||
|
|
||||||
function updateStatus() {
|
function updateStatus() {
|
||||||
console.log("updated transfer page status")
|
|
||||||
if(typeof currentWallet === "undefined") {
|
if(typeof currentWallet === "undefined") {
|
||||||
statusText.text = qsTr("Wallet is not connected to daemon.") + "<br>" + root.startLinkText
|
statusText.text = qsTr("Wallet is not connected to daemon.") + "<br>" + root.startLinkText
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (currentWallet.connected) {
|
if (currentWallet.viewOnly) {
|
||||||
|
// statusText.text = qsTr("Wallet is view only.")
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
pageRoot.enabled = false;
|
||||||
|
|
||||||
|
switch (currentWallet.connected()) {
|
||||||
case Wallet.ConnectionStatus_Disconnected:
|
case Wallet.ConnectionStatus_Disconnected:
|
||||||
statusText.text = qsTr("Wallet is not connected to daemon.") + "<br>" + root.startLinkText
|
statusText.text = qsTr("Wallet is not connected to daemon.") + "<br>" + root.startLinkText
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -89,18 +89,22 @@ Rectangle {
|
|||||||
Text {
|
Text {
|
||||||
text: qsTr("Verify that a third party made a payment by supplying:") + translationManager.emptyString
|
text: qsTr("Verify that a third party made a payment by supplying:") + translationManager.emptyString
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
|
Layout.fillWidth: true;
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: qsTr(" - the recipient address") + translationManager.emptyString
|
text: qsTr(" - the recipient address") + translationManager.emptyString
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
|
Layout.fillWidth: true;
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: qsTr(" - the transaction ID") + translationManager.emptyString
|
text: qsTr(" - the transaction ID") + translationManager.emptyString
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
|
Layout.fillWidth: true;
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: qsTr(" - the secret transaction key supplied by the sender") + translationManager.emptyString
|
text: qsTr(" - the secret transaction key supplied by the sender") + translationManager.emptyString
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
|
Layout.fillWidth: true;
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: qsTr("If a payment had several transactions then each must be checked and the results combined.") + translationManager.emptyString
|
text: qsTr("If a payment had several transactions then each must be checked and the results combined.") + translationManager.emptyString
|
||||||
@@ -209,7 +213,7 @@ Rectangle {
|
|||||||
anchors.top: txKeyRow.bottom
|
anchors.top: txKeyRow.bottom
|
||||||
anchors.topMargin: 17
|
anchors.topMargin: 17
|
||||||
width: 60
|
width: 60
|
||||||
text: qsTr("CHECK") + translationManager.emptyString
|
text: qsTr("Check") + translationManager.emptyString
|
||||||
shadowReleasedColor: "#FF4304"
|
shadowReleasedColor: "#FF4304"
|
||||||
shadowPressedColor: "#B32D00"
|
shadowPressedColor: "#B32D00"
|
||||||
releasedColor: "#FF6C3C"
|
releasedColor: "#FF6C3C"
|
||||||
|
|||||||
23
qml.qrc
@@ -100,13 +100,28 @@
|
|||||||
<file>lang/flags/bangladesh.png</file>
|
<file>lang/flags/bangladesh.png</file>
|
||||||
<file>lang/flags/brazil.png</file>
|
<file>lang/flags/brazil.png</file>
|
||||||
<file>lang/flags/china.png</file>
|
<file>lang/flags/china.png</file>
|
||||||
|
<file>lang/flags/croatia.png</file>
|
||||||
|
<file>lang/flags/esperanto.png</file>
|
||||||
|
<file>lang/flags/finland.png</file>
|
||||||
|
<file>lang/flags/france.png</file>
|
||||||
<file>lang/flags/german.png</file>
|
<file>lang/flags/german.png</file>
|
||||||
<file>lang/flags/india.png</file>
|
<file>lang/flags/india.png</file>
|
||||||
|
<file>lang/flags/indonesia.png</file>
|
||||||
|
<file>lang/flags/italy.png</file>
|
||||||
|
<file>lang/flags/japan.png</file>
|
||||||
|
<file>lang/flags/netherlands.png</file>
|
||||||
<file>lang/flags/palestine.png</file>
|
<file>lang/flags/palestine.png</file>
|
||||||
|
<file>lang/flags/poland.png</file>
|
||||||
<file>lang/flags/rpa.png</file>
|
<file>lang/flags/rpa.png</file>
|
||||||
<file>lang/flags/russia.png</file>
|
<file>lang/flags/russia.png</file>
|
||||||
|
<file>lang/flags/spain.png</file>
|
||||||
|
<file>lang/flags/sweden.png</file>
|
||||||
|
<file>lang/flags/taiwan.png</file>
|
||||||
<file>lang/flags/uk.png</file>
|
<file>lang/flags/uk.png</file>
|
||||||
<file>lang/flags/usa.png</file>
|
<file>lang/flags/usa.png</file>
|
||||||
|
<file>lang/flags/israel.png</file>
|
||||||
|
<file>lang/flags/south_korea.png</file>
|
||||||
|
<file>lang/flags/romania.png</file>
|
||||||
<file>wizard/WizardManageWalletUI.qml</file>
|
<file>wizard/WizardManageWalletUI.qml</file>
|
||||||
<file>wizard/WizardRecoveryWallet.qml</file>
|
<file>wizard/WizardRecoveryWallet.qml</file>
|
||||||
<file>wizard/WizardMemoTextInput.qml</file>
|
<file>wizard/WizardMemoTextInput.qml</file>
|
||||||
@@ -114,7 +129,6 @@
|
|||||||
<file>pages/Receive.qml</file>
|
<file>pages/Receive.qml</file>
|
||||||
<file>pages/TxKey.qml</file>
|
<file>pages/TxKey.qml</file>
|
||||||
<file>components/IconButton.qml</file>
|
<file>components/IconButton.qml</file>
|
||||||
<file>lang/flags/italy.png</file>
|
|
||||||
<file>components/PasswordDialog.qml</file>
|
<file>components/PasswordDialog.qml</file>
|
||||||
<file>components/ProcessingSplash.qml</file>
|
<file>components/ProcessingSplash.qml</file>
|
||||||
<file>components/ProgressBar.qml</file>
|
<file>components/ProgressBar.qml</file>
|
||||||
@@ -122,5 +136,12 @@
|
|||||||
<file>pages/Sign.qml</file>
|
<file>pages/Sign.qml</file>
|
||||||
<file>components/DaemonManagerDialog.qml</file>
|
<file>components/DaemonManagerDialog.qml</file>
|
||||||
<file>version.js</file>
|
<file>version.js</file>
|
||||||
|
<file>wizard/WizardPasswordUI.qml</file>
|
||||||
|
<file>wizard/WizardCreateViewOnlyWallet.qml</file>
|
||||||
|
<file>components/DaemonConsole.qml</file>
|
||||||
|
<file>components/QRCodeScanner.qml</file>
|
||||||
|
<file>components/Notifier.qml</file>
|
||||||
|
<file>components/MobileHeader.qml</file>
|
||||||
|
<file>components/TextBlock.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
104
src/QR-Code-scanner/QrCodeScanner.cpp
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
// Copyright (c) 2014-2017, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "QrCodeScanner.h"
|
||||||
|
#include <WalletManager.h>
|
||||||
|
#include <QVideoProbe>
|
||||||
|
#include <QCamera>
|
||||||
|
|
||||||
|
QrCodeScanner::QrCodeScanner(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, m_processTimerId(-1)
|
||||||
|
, m_processInterval(750)
|
||||||
|
, m_enabled(true)
|
||||||
|
{
|
||||||
|
m_probe = new QVideoProbe(this);
|
||||||
|
m_thread = new QrScanThread(this);
|
||||||
|
m_thread->start();
|
||||||
|
QObject::connect(m_thread, SIGNAL(decoded(int,QString)), this, SLOT(processCode(int,QString)));
|
||||||
|
QObject::connect(m_thread, SIGNAL(notifyError(const QString &, bool)), this, SIGNAL(notifyError(const QString &, bool)));
|
||||||
|
connect(m_probe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame)));
|
||||||
|
}
|
||||||
|
void QrCodeScanner::setSource(QCamera *camera)
|
||||||
|
{
|
||||||
|
m_probe->setSource(camera);
|
||||||
|
}
|
||||||
|
void QrCodeScanner::processCode(int type, const QString &data)
|
||||||
|
{
|
||||||
|
if (! m_enabled) return;
|
||||||
|
qDebug() << "decoded - type: " << type << " data: " << data;
|
||||||
|
QString address, payment_id, tx_description, recipient_name, error;
|
||||||
|
QVector<QString> unknown_parameters;
|
||||||
|
uint64_t amount(0);
|
||||||
|
if( ! WalletManager::instance()->parse_uri(data, address, payment_id, amount, tx_description, recipient_name, unknown_parameters, error) )
|
||||||
|
{
|
||||||
|
qDebug() << "Failed to parse_uri : " << error;
|
||||||
|
emit notifyError(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(unknown_parameters.size() > 0)
|
||||||
|
{
|
||||||
|
qDebug() << "unknown parameters " << unknown_parameters;
|
||||||
|
emit notifyError(error, true);
|
||||||
|
}
|
||||||
|
qDebug() << "Parsed URI : " << address << " " << payment_id << " " << amount << " " << tx_description << " " << recipient_name << " " << error;
|
||||||
|
QString s_amount = WalletManager::instance()->displayAmount(amount);
|
||||||
|
qDebug() << "Amount passed " << s_amount ;
|
||||||
|
emit decoded(address, payment_id, s_amount, tx_description, recipient_name);
|
||||||
|
}
|
||||||
|
void QrCodeScanner::processFrame(QVideoFrame frame)
|
||||||
|
{
|
||||||
|
if(frame.isValid()){
|
||||||
|
m_curFrame = frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool QrCodeScanner::enabled() const
|
||||||
|
{
|
||||||
|
return m_enabled;
|
||||||
|
}
|
||||||
|
void QrCodeScanner::setEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
m_enabled = enabled;
|
||||||
|
if(!enabled && (m_processTimerId != -1) )
|
||||||
|
{
|
||||||
|
this->killTimer(m_processTimerId);
|
||||||
|
m_processTimerId = -1;
|
||||||
|
}
|
||||||
|
else if (enabled && (m_processTimerId == -1) )
|
||||||
|
{
|
||||||
|
m_processTimerId = this->startTimer(m_processInterval);
|
||||||
|
}
|
||||||
|
emit enabledChanged();
|
||||||
|
}
|
||||||
|
void QrCodeScanner::timerEvent(QTimerEvent *event)
|
||||||
|
{
|
||||||
|
if( (event->timerId() == m_processTimerId) ){
|
||||||
|
m_thread->addFrame(m_curFrame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
75
src/QR-Code-scanner/QrCodeScanner.h
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
// Copyright (c) 2014-2017, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef QRCODESCANNER_H_
|
||||||
|
#define QRCODESCANNER_H_
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
|
#include <QVideoFrame>
|
||||||
|
#include "QrScanThread.h"
|
||||||
|
|
||||||
|
class QVideoProbe;
|
||||||
|
class QCamera;
|
||||||
|
|
||||||
|
class QrCodeScanner : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
QrCodeScanner(QObject *parent = Q_NULLPTR);
|
||||||
|
|
||||||
|
void setSource(QCamera*);
|
||||||
|
|
||||||
|
bool enabled() const;
|
||||||
|
void setEnabled(bool enabled);
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void processCode(int type, const QString &data);
|
||||||
|
void processFrame(QVideoFrame);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void enabledChanged();
|
||||||
|
|
||||||
|
void decoded(const QString &address, const QString &payment_id, const QString &amount, const QString &tx_description, const QString &recipient_name);
|
||||||
|
void decode(int type, const QString &data);
|
||||||
|
void notifyError(const QString &error, bool warning = false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void timerEvent(QTimerEvent *);
|
||||||
|
QrScanThread *m_thread;
|
||||||
|
int m_processTimerId;
|
||||||
|
int m_processInterval;
|
||||||
|
int m_enabled;
|
||||||
|
QVideoFrame m_curFrame;
|
||||||
|
QVideoProbe *m_probe;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
132
src/QR-Code-scanner/QrScanThread.cpp
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
// Copyright (c) 2014-2017, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include "QrScanThread.h"
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
|
||||||
|
extern QImage qt_imageFromVideoFrame(const QVideoFrame &f);
|
||||||
|
#else
|
||||||
|
QImage qt_imageFromVideoFrame(const QVideoFrame &f){
|
||||||
|
Q_ASSERT_X(0 != 0, "qt_imageFromVideoFrame", "Should have been managed in .pro");
|
||||||
|
return QImage();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QrScanThread::QrScanThread(QObject *parent)
|
||||||
|
: QThread(parent)
|
||||||
|
,m_running(true)
|
||||||
|
{
|
||||||
|
m_scanner.set_handler(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QrScanThread::image_callback(zbar::Image &image)
|
||||||
|
{
|
||||||
|
qDebug() << "image_callback : Found Code ! " ;
|
||||||
|
for(zbar::Image::SymbolIterator sym = image.symbol_begin();
|
||||||
|
sym != image.symbol_end();
|
||||||
|
++sym)
|
||||||
|
if(!sym->get_count()) {
|
||||||
|
QString data = QString::fromStdString(sym->get_data());
|
||||||
|
emit decoded(sym->get_type(), data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QrScanThread::processZImage(zbar::Image &image)
|
||||||
|
{
|
||||||
|
m_scanner.recycle_image(image);
|
||||||
|
zbar::Image tmp = image.convert(*(long*)"Y800");
|
||||||
|
m_scanner.scan(tmp);
|
||||||
|
image.set_symbols(tmp.get_symbols());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QrScanThread::zimageFromQImage(const QImage &qimg, zbar::Image &dst)
|
||||||
|
{
|
||||||
|
switch( qimg.format() ){
|
||||||
|
case QImage::Format_RGB32 :
|
||||||
|
case QImage::Format_ARGB32 :
|
||||||
|
case QImage::Format_ARGB32_Premultiplied :
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
emit notifyError(QString("Invalid QImage Format !"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unsigned int bpl( qimg.bytesPerLine() ), width( bpl / 4), height( qimg.height());
|
||||||
|
dst.set_size(width, height);
|
||||||
|
dst.set_format("BGR4");
|
||||||
|
unsigned long datalen = qimg.byteCount();
|
||||||
|
dst.set_data(qimg.bits(), datalen);
|
||||||
|
if((width * 4 != bpl) || (width * height * 4 > datalen)){
|
||||||
|
emit notifyError(QString("QImage to Zbar::Image failed !"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void QrScanThread::processQImage(const QImage &qimg)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
m_image = QSharedPointer<zbar::Image>(new zbar::Image());
|
||||||
|
if( ! zimageFromQImage(qimg, *m_image) )
|
||||||
|
return;
|
||||||
|
processZImage(*m_image);
|
||||||
|
}
|
||||||
|
catch(std::exception &e) {
|
||||||
|
qDebug() << "ERROR: " << e.what();
|
||||||
|
emit notifyError(e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QrScanThread::processVideoFrame(const QVideoFrame &frame)
|
||||||
|
{
|
||||||
|
processQImage( qt_imageFromVideoFrame(frame) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QrScanThread::stop()
|
||||||
|
{
|
||||||
|
m_running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QrScanThread::addFrame(const QVideoFrame &frame)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&m_mutex);
|
||||||
|
m_queue.append(frame);
|
||||||
|
m_waitCondition.wakeOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QrScanThread::run()
|
||||||
|
{
|
||||||
|
QVideoFrame frame;
|
||||||
|
while(m_running) {
|
||||||
|
QMutexLocker locker(&m_mutex);
|
||||||
|
while(m_queue.isEmpty())
|
||||||
|
m_waitCondition.wait(&m_mutex);
|
||||||
|
processVideoFrame(m_queue.takeFirst());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
69
src/QR-Code-scanner/QrScanThread.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// Copyright (c) 2014-2017, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef _QRSCANTHREAD_H_
|
||||||
|
#define _QRSCANTHREAD_H_
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QWaitCondition>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QVideoFrame>
|
||||||
|
#include <QCamera>
|
||||||
|
#include <zbar.h>
|
||||||
|
|
||||||
|
class QrScanThread : public QThread, public zbar::Image::Handler
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QrScanThread(QObject *parent = Q_NULLPTR);
|
||||||
|
void addFrame(const QVideoFrame &frame);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void decoded(int type, const QString &data);
|
||||||
|
void notifyError(const QString &error, bool warning = false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void run();
|
||||||
|
virtual void stop();
|
||||||
|
void processVideoFrame(const QVideoFrame &);
|
||||||
|
void processQImage(const QImage &);
|
||||||
|
void processZImage(zbar::Image &image);
|
||||||
|
virtual void image_callback(zbar::Image &image);
|
||||||
|
bool zimageFromQImage(const QImage&, zbar::Image &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
zbar::ImageScanner m_scanner;
|
||||||
|
QSharedPointer<zbar::Image> m_image;
|
||||||
|
bool m_running;
|
||||||
|
QMutex m_mutex;
|
||||||
|
QWaitCondition m_waitCondition;
|
||||||
|
QList<QVideoFrame> m_queue;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
@@ -7,6 +7,15 @@
|
|||||||
#include <QtConcurrent/QtConcurrent>
|
#include <QtConcurrent/QtConcurrent>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <QTime>
|
||||||
|
#include <QStorageInfo>
|
||||||
|
#include <QVariantMap>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
static const int DAEMON_START_TIMEOUT_SECONDS = 30;
|
||||||
|
}
|
||||||
|
|
||||||
DaemonManager * DaemonManager::m_instance = nullptr;
|
DaemonManager * DaemonManager::m_instance = nullptr;
|
||||||
QStringList DaemonManager::m_clArgs;
|
QStringList DaemonManager::m_clArgs;
|
||||||
@@ -23,24 +32,19 @@ DaemonManager *DaemonManager::instance(const QStringList *args)
|
|||||||
return m_instance;
|
return m_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DaemonManager::start(const QString &flags)
|
bool DaemonManager::start(const QString &flags, bool testnet, const QString &dataDir)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
QString process;
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
process = QApplication::applicationDirPath() + "/monerod.exe";
|
|
||||||
#elif defined(Q_OS_UNIX)
|
|
||||||
process = QApplication::applicationDirPath() + "/monerod";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (process.length() == 0) {
|
|
||||||
qDebug() << "no daemon binary defined for current platform";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// prepare command line arguments and pass to monerod
|
// prepare command line arguments and pass to monerod
|
||||||
QStringList arguments;
|
QStringList arguments;
|
||||||
|
|
||||||
|
// Start daemon with --detach flag on non-windows platforms
|
||||||
|
#ifndef Q_OS_WIN
|
||||||
|
arguments << "--detach";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(testnet)
|
||||||
|
arguments << "--testnet";
|
||||||
|
|
||||||
foreach (const QString &str, m_clArgs) {
|
foreach (const QString &str, m_clArgs) {
|
||||||
qDebug() << QString(" [%1] ").arg(str);
|
qDebug() << QString(" [%1] ").arg(str);
|
||||||
if (!str.isEmpty())
|
if (!str.isEmpty())
|
||||||
@@ -54,8 +58,20 @@ bool DaemonManager::start(const QString &flags)
|
|||||||
arguments << str;
|
arguments << str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom data-dir
|
||||||
|
if(!dataDir.isEmpty()) {
|
||||||
|
if(testnet)
|
||||||
|
arguments << "--testnet-data-dir";
|
||||||
|
else
|
||||||
|
arguments << "--data-dir";
|
||||||
|
arguments << dataDir;
|
||||||
|
}
|
||||||
|
|
||||||
qDebug() << "starting monerod " + process;
|
arguments << "--check-updates" << "disabled";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
qDebug() << "starting monerod " + m_monerod;
|
||||||
qDebug() << "With command line arguments " << arguments;
|
qDebug() << "With command line arguments " << arguments;
|
||||||
|
|
||||||
m_daemon = new QProcess();
|
m_daemon = new QProcess();
|
||||||
@@ -66,33 +82,100 @@ bool DaemonManager::start(const QString &flags)
|
|||||||
connect (m_daemon, SIGNAL(readyReadStandardError()), this, SLOT(printError()));
|
connect (m_daemon, SIGNAL(readyReadStandardError()), this, SLOT(printError()));
|
||||||
|
|
||||||
// Start monerod
|
// Start monerod
|
||||||
m_daemon->start(process,arguments);
|
bool started = m_daemon->startDetached(m_monerod, arguments);
|
||||||
bool started = m_daemon->waitForStarted();
|
|
||||||
|
|
||||||
// add state changed listener
|
// add state changed listener
|
||||||
connect(m_daemon,SIGNAL(stateChanged(QProcess::ProcessState)),this,SLOT(stateChanged(QProcess::ProcessState)));
|
connect(m_daemon,SIGNAL(stateChanged(QProcess::ProcessState)),this,SLOT(stateChanged(QProcess::ProcessState)));
|
||||||
|
|
||||||
if (!started) {
|
if (!started) {
|
||||||
qDebug() << "Daemon start error: " + m_daemon->errorString();
|
qDebug() << "Daemon start error: " + m_daemon->errorString();
|
||||||
} else {
|
emit daemonStartFailure();
|
||||||
emit daemonStarted();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return started;
|
// Start start watcher
|
||||||
}
|
QFuture<bool> future = QtConcurrent::run(this, &DaemonManager::startWatcher, testnet);
|
||||||
|
QFutureWatcher<bool> * watcher = new QFutureWatcher<bool>();
|
||||||
|
connect(watcher, &QFutureWatcher<bool>::finished,
|
||||||
|
this, [this, watcher]() {
|
||||||
|
QFuture<bool> future = watcher->future();
|
||||||
|
watcher->deleteLater();
|
||||||
|
if(future.result())
|
||||||
|
emit daemonStarted();
|
||||||
|
else
|
||||||
|
emit daemonStartFailure();
|
||||||
|
});
|
||||||
|
watcher->setFuture(future);
|
||||||
|
|
||||||
bool DaemonManager::stop()
|
|
||||||
{
|
|
||||||
if (initialized) {
|
|
||||||
qDebug() << "stopping daemon";
|
|
||||||
// we can't use QProcess::terminate() on windows console process
|
|
||||||
// write exit command to stdin
|
|
||||||
m_daemon->write("exit\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DaemonManager::stop(bool testnet)
|
||||||
|
{
|
||||||
|
QString message;
|
||||||
|
sendCommand("exit",testnet,message);
|
||||||
|
qDebug() << message;
|
||||||
|
|
||||||
|
// Start stop watcher - Will kill if not shutting down
|
||||||
|
QFuture<bool> future = QtConcurrent::run(this, &DaemonManager::stopWatcher, testnet);
|
||||||
|
QFutureWatcher<bool> * watcher = new QFutureWatcher<bool>();
|
||||||
|
connect(watcher, &QFutureWatcher<bool>::finished,
|
||||||
|
this, [this, watcher]() {
|
||||||
|
QFuture<bool> future = watcher->future();
|
||||||
|
watcher->deleteLater();
|
||||||
|
if(future.result()) {
|
||||||
|
emit daemonStopped();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
watcher->setFuture(future);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DaemonManager::startWatcher(bool testnet) const
|
||||||
|
{
|
||||||
|
// Check if daemon is started every 2 seconds
|
||||||
|
QTime timer;
|
||||||
|
timer.restart();
|
||||||
|
while(true && !m_app_exit && timer.elapsed() / 1000 < DAEMON_START_TIMEOUT_SECONDS ) {
|
||||||
|
QThread::sleep(2);
|
||||||
|
if(!running(testnet)) {
|
||||||
|
qDebug() << "daemon not running. checking again in 2 seconds.";
|
||||||
|
} else {
|
||||||
|
qDebug() << "daemon is started. Waiting 5 seconds to let daemon catch up";
|
||||||
|
QThread::sleep(5);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DaemonManager::stopWatcher(bool testnet) const
|
||||||
|
{
|
||||||
|
// Check if daemon is running every 2 seconds. Kill if still running after 10 seconds
|
||||||
|
int counter = 0;
|
||||||
|
while(true && !m_app_exit) {
|
||||||
|
QThread::sleep(2);
|
||||||
|
counter++;
|
||||||
|
if(running(testnet)) {
|
||||||
|
qDebug() << "Daemon still running. " << counter;
|
||||||
|
if(counter >= 5) {
|
||||||
|
qDebug() << "Killing it! ";
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
QProcess::execute("taskkill /F /IM monerod.exe");
|
||||||
|
#else
|
||||||
|
QProcess::execute("pkill monerod");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DaemonManager::stateChanged(QProcess::ProcessState state)
|
void DaemonManager::stateChanged(QProcess::ProcessState state)
|
||||||
{
|
{
|
||||||
qDebug() << "STATE CHANGED: " << state;
|
qDebug() << "STATE CHANGED: " << state;
|
||||||
@@ -123,29 +206,102 @@ void DaemonManager::printError()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DaemonManager::running() const
|
bool DaemonManager::running(bool testnet) const
|
||||||
{
|
{
|
||||||
if (initialized) {
|
QString status;
|
||||||
qDebug() << m_daemon->state();
|
sendCommand("status",testnet, status);
|
||||||
qDebug() << QProcess::NotRunning;
|
qDebug() << status;
|
||||||
// m_daemon->write("status\n");
|
// `./monerod status` returns BUSY when syncing.
|
||||||
return m_daemon->state() > QProcess::NotRunning;
|
// Treat busy as connected, until fixed upstream.
|
||||||
|
if (status.contains("Height:") || status.contains("BUSY") ) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool DaemonManager::sendCommand(const QString &cmd,bool testnet) const
|
||||||
|
{
|
||||||
|
QString message;
|
||||||
|
return sendCommand(cmd, testnet, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DaemonManager::sendCommand(const QString &cmd,bool testnet, QString &message) const
|
||||||
|
{
|
||||||
|
QProcess p;
|
||||||
|
QStringList external_cmd;
|
||||||
|
external_cmd << cmd;
|
||||||
|
|
||||||
|
// Add testnet flag if needed
|
||||||
|
if (testnet)
|
||||||
|
external_cmd << "--testnet";
|
||||||
|
|
||||||
|
qDebug() << "sending external cmd: " << external_cmd;
|
||||||
|
|
||||||
|
|
||||||
|
p.start(m_monerod, external_cmd);
|
||||||
|
|
||||||
|
bool started = p.waitForFinished(-1);
|
||||||
|
message = p.readAllStandardOutput();
|
||||||
|
emit daemonConsoleUpdated(message);
|
||||||
|
return started;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DaemonManager::exit()
|
||||||
|
{
|
||||||
|
qDebug("DaemonManager: exit()");
|
||||||
|
m_app_exit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap DaemonManager::validateDataDir(const QString &dataDir) const
|
||||||
|
{
|
||||||
|
QVariantMap result;
|
||||||
|
bool valid = true;
|
||||||
|
bool readOnly = false;
|
||||||
|
int storageAvailable = 0;
|
||||||
|
bool lmdbExists = true;
|
||||||
|
|
||||||
|
QStorageInfo storage(dataDir);
|
||||||
|
if (storage.isValid() && storage.isReady()) {
|
||||||
|
if (storage.isReadOnly()) {
|
||||||
|
readOnly = true;
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure there is 20GB storage available
|
||||||
|
storageAvailable = storage.bytesAvailable()/1000/1000/1000;
|
||||||
|
if (storageAvailable < 20) {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!QDir(dataDir+"/lmdb").exists()) {
|
||||||
|
lmdbExists = false;
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.insert("valid", valid);
|
||||||
|
result.insert("lmdbExists", lmdbExists);
|
||||||
|
result.insert("readOnly", readOnly);
|
||||||
|
result.insert("storageAvailable", storageAvailable);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
DaemonManager::DaemonManager(QObject *parent)
|
DaemonManager::DaemonManager(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
// Platform depetent path to monerod
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
m_monerod = QApplication::applicationDirPath() + "/monerod.exe";
|
||||||
|
#elif defined(Q_OS_UNIX)
|
||||||
|
m_monerod = QApplication::applicationDirPath() + "/monerod";
|
||||||
|
#endif
|
||||||
|
|
||||||
void DaemonManager::closing()
|
if (m_monerod.length() == 0) {
|
||||||
{
|
qCritical() << "no daemon binary defined for current platform";
|
||||||
qDebug() << __FUNCTION__;
|
m_has_daemon = false;
|
||||||
stop();
|
|
||||||
// Wait for daemon to stop before exiting (max 10 secs)
|
|
||||||
if (initialized) {
|
|
||||||
m_daemon->waitForFinished(10000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <QVariantMap>
|
||||||
|
|
||||||
class DaemonManager : public QObject
|
class DaemonManager : public QObject
|
||||||
{
|
{
|
||||||
@@ -13,30 +14,41 @@ public:
|
|||||||
|
|
||||||
static DaemonManager * instance(const QStringList *args);
|
static DaemonManager * instance(const QStringList *args);
|
||||||
|
|
||||||
Q_INVOKABLE bool start(const QString &flags);
|
Q_INVOKABLE bool start(const QString &flags, bool testnet, const QString &dataDir = "");
|
||||||
Q_INVOKABLE bool stop();
|
Q_INVOKABLE bool stop(bool testnet);
|
||||||
|
|
||||||
// return true if daemon process is started
|
// return true if daemon process is started
|
||||||
Q_INVOKABLE bool running() const;
|
Q_INVOKABLE bool running(bool testnet) const;
|
||||||
|
// Send daemon command from qml and prints output in console window.
|
||||||
|
Q_INVOKABLE bool sendCommand(const QString &cmd, bool testnet) const;
|
||||||
|
Q_INVOKABLE void exit();
|
||||||
|
Q_INVOKABLE QVariantMap validateDataDir(const QString &dataDir) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool sendCommand(const QString &cmd, bool testnet, QString &message) const;
|
||||||
|
bool startWatcher(bool testnet) const;
|
||||||
|
bool stopWatcher(bool testnet) const;
|
||||||
signals:
|
signals:
|
||||||
void daemonStarted();
|
void daemonStarted() const;
|
||||||
void daemonStopped();
|
void daemonStopped() const;
|
||||||
void daemonConsoleUpdated(QString message);
|
void daemonStartFailure() const;
|
||||||
|
void daemonConsoleUpdated(QString message) const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void printOutput();
|
void printOutput();
|
||||||
void printError();
|
void printError();
|
||||||
void closing();
|
|
||||||
void stateChanged(QProcess::ProcessState state);
|
void stateChanged(QProcess::ProcessState state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
explicit DaemonManager(QObject *parent = 0);
|
explicit DaemonManager(QObject *parent = 0);
|
||||||
static DaemonManager * m_instance;
|
static DaemonManager * m_instance;
|
||||||
static QStringList m_clArgs;
|
static QStringList m_clArgs;
|
||||||
QProcess *m_daemon;
|
QProcess *m_daemon;
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
|
QString m_monerod;
|
||||||
|
bool m_has_daemon = true;
|
||||||
|
bool m_app_exit = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -68,3 +68,8 @@ quint64 AddressBook::count() const
|
|||||||
{
|
{
|
||||||
return m_rows.size();
|
return m_rows.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AddressBook::lookupPaymentID(const QString &payment_id) const
|
||||||
|
{
|
||||||
|
return m_addressBookImpl->lookupPaymentID(payment_id.toStdString());
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public:
|
|||||||
quint64 count() const;
|
quint64 count() const;
|
||||||
Q_INVOKABLE QString errorString() const;
|
Q_INVOKABLE QString errorString() const;
|
||||||
Q_INVOKABLE int errorCode() const;
|
Q_INVOKABLE int errorCode() const;
|
||||||
|
Q_INVOKABLE int lookupPaymentID(const QString &payment_id) const;
|
||||||
|
|
||||||
enum ErrorCode {
|
enum ErrorCode {
|
||||||
Status_Ok,
|
Status_Ok,
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ QString PendingTransaction::errorString() const
|
|||||||
|
|
||||||
bool PendingTransaction::commit()
|
bool PendingTransaction::commit()
|
||||||
{
|
{
|
||||||
return m_pimpl->commit();
|
// Save transaction to file if fileName is set.
|
||||||
|
if(!m_fileName.isEmpty())
|
||||||
|
return m_pimpl->commit(m_fileName.toStdString());
|
||||||
|
return m_pimpl->commit(m_fileName.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 PendingTransaction::amount() const
|
quint64 PendingTransaction::amount() const
|
||||||
@@ -47,6 +50,11 @@ quint64 PendingTransaction::txCount() const
|
|||||||
return m_pimpl->txCount();
|
return m_pimpl->txCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PendingTransaction::setFilename(const QString &fileName)
|
||||||
|
{
|
||||||
|
m_fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
PendingTransaction::PendingTransaction(Monero::PendingTransaction *pt, QObject *parent)
|
PendingTransaction::PendingTransaction(Monero::PendingTransaction *pt, QObject *parent)
|
||||||
: QObject(parent), m_pimpl(pt)
|
: QObject(parent), m_pimpl(pt)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public:
|
|||||||
quint64 fee() const;
|
quint64 fee() const;
|
||||||
QStringList txid() const;
|
QStringList txid() const;
|
||||||
quint64 txCount() const;
|
quint64 txCount() const;
|
||||||
|
Q_INVOKABLE void setFilename(const QString &fileName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit PendingTransaction(Monero::PendingTransaction * pt, QObject *parent = 0);
|
explicit PendingTransaction(Monero::PendingTransaction * pt, QObject *parent = 0);
|
||||||
@@ -51,6 +52,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
friend class Wallet;
|
friend class Wallet;
|
||||||
Monero::PendingTransaction * m_pimpl;
|
Monero::PendingTransaction * m_pimpl;
|
||||||
|
QString m_fileName;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PENDINGTRANSACTION_H
|
#endif // PENDINGTRANSACTION_H
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "QRCodeImageProvider.h"
|
#include "QRCodeImageProvider.h"
|
||||||
|
|
||||||
QImage QRCodeImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
|
QImage QRCodeImageProvider::genQrImage(const QString &id, QSize *size)
|
||||||
{
|
{
|
||||||
using namespace qrcodegen;
|
using namespace qrcodegen;
|
||||||
|
|
||||||
@@ -15,3 +15,8 @@ QImage QRCodeImageProvider::requestImage(const QString &id, QSize *size, const Q
|
|||||||
*size = QSize(qrcode.size, qrcode.size);
|
*size = QSize(qrcode.size, qrcode.size);
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QImage QRCodeImageProvider::requestImage(const QString &id, QSize *size, const QSize &/* requestedSize */)
|
||||||
|
{
|
||||||
|
return genQrImage(id, size);
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,5 +7,6 @@ public:
|
|||||||
QRCodeImageProvider(): QQuickImageProvider(QQuickImageProvider::Image) {}
|
QRCodeImageProvider(): QQuickImageProvider(QQuickImageProvider::Image) {}
|
||||||
|
|
||||||
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
|
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
|
||||||
|
static QImage genQrImage(const QString &id, QSize *size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ QList<TransactionInfo *> TransactionHistory::getAll() const
|
|||||||
|
|
||||||
QDateTime firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block
|
QDateTime firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block
|
||||||
QDateTime lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
|
QDateTime lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
|
||||||
|
quint64 lastTxHeight = 0;
|
||||||
|
m_locked = false;
|
||||||
|
m_minutesToUnlock = 0;
|
||||||
TransactionHistory * parent = const_cast<TransactionHistory*>(this);
|
TransactionHistory * parent = const_cast<TransactionHistory*>(this);
|
||||||
for (const auto i : m_pimpl->getAll()) {
|
for (const auto i : m_pimpl->getAll()) {
|
||||||
TransactionInfo * ti = new TransactionInfo(i, parent);
|
TransactionInfo * ti = new TransactionInfo(i, parent);
|
||||||
@@ -43,6 +45,15 @@ QList<TransactionInfo *> TransactionHistory::getAll() const
|
|||||||
if (ti->timestamp() <= firstDateTime) {
|
if (ti->timestamp() <= firstDateTime) {
|
||||||
firstDateTime = ti->timestamp();
|
firstDateTime = ti->timestamp();
|
||||||
}
|
}
|
||||||
|
quint64 requiredConfirmations = (ti->blockHeight() < ti->unlockTime()) ? ti->unlockTime() - ti->blockHeight() : 10;
|
||||||
|
// store last tx height
|
||||||
|
if (ti->confirmations() < requiredConfirmations && ti->blockHeight() >= lastTxHeight) {
|
||||||
|
lastTxHeight = ti->blockHeight();
|
||||||
|
// TODO: Fetch block time and confirmations needed from wallet2?
|
||||||
|
m_minutesToUnlock = (requiredConfirmations - ti->confirmations()) * 2;
|
||||||
|
m_locked = true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
emit refreshFinished();
|
emit refreshFinished();
|
||||||
|
|
||||||
@@ -81,9 +92,19 @@ QDateTime TransactionHistory::lastDateTime() const
|
|||||||
return m_lastDateTime;
|
return m_lastDateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
quint64 TransactionHistory::minutesToUnlock() const
|
||||||
|
{
|
||||||
|
return m_minutesToUnlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TransactionHistory::TransactionHistory::locked() const
|
||||||
|
{
|
||||||
|
return m_locked;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TransactionHistory::TransactionHistory(Monero::TransactionHistory *pimpl, QObject *parent)
|
TransactionHistory::TransactionHistory(Monero::TransactionHistory *pimpl, QObject *parent)
|
||||||
: QObject(parent), m_pimpl(pimpl)
|
: QObject(parent), m_pimpl(pimpl), m_minutesToUnlock(0), m_locked(false)
|
||||||
{
|
{
|
||||||
m_firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block
|
m_firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block
|
||||||
m_lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
|
m_lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
|
||||||
|
|||||||