Compare commits

...

466 Commits

Author SHA1 Message Date
Riccardo Spagni
4ca35af11a Merge pull request #630
b4f01b9 linux32: use vendored libunbound (Jaquee)
f653535 linux 32 build config test (Jaquee)
2017-03-28 19:57:24 +02:00
Riccardo Spagni
a154eabf87 Merge pull request #633
10c3b8c activate 'git submodule update' (schnerchi)
2017-03-28 19:56:59 +02:00
Riccardo Spagni
2f5a865028 Merge pull request #631
dcc633b Finish zh_tw & zh_cn translations (Lafudoci)
2017-03-28 19:56:30 +02:00
Riccardo Spagni
87d444d128 Merge pull request #560
6e381c3 Update README.md (Matthias Tarasiewicz)
2017-03-28 19:55:51 +02:00
schnerchi
10c3b8c116 activate 'git submodule update'
cloning and trying to build without this does not work at least on mac osx
2017-03-28 18:31:23 +02:00
Lafudoci
dcc633b716 Finish zh_tw & zh_cn translations
Finish translation including PR/596 ( replace save with connect)
2017-03-29 00:03:11 +08:00
Jaquee
b4f01b9f6a linux32: use vendored libunbound 2017-03-28 17:37:06 +02:00
Jaquee
f6535354e4 linux 32 build config test 2017-03-27 21:42:01 +02:00
Riccardo Spagni
60254812c8 Merge pull request #618
d1b1823 Enable pt-br translation (Jaquee)
2017-03-27 21:32:35 +02:00
Jaquee
d1b1823a50 Enable pt-br translation 2017-03-27 21:31:10 +02:00
Riccardo Spagni
fb456fc5fe Merge pull request #617
53e87b4 Update monero-core_pt-br.ts (moneroj)
2017-03-27 21:24:00 +02:00
Riccardo Spagni
508b512c45 Merge pull request #616
716010a README: QtMultimedia dependency optional (MoroccanMalinois)
fb3a618 Make QtMultimedia dependency optional (MoroccanMalinois)
2017-03-27 21:23:21 +02:00
Riccardo Spagni
b1d24f8aa7 Merge pull request #615
4ee23b2 update submodule to v0.10.3.1 (Jaquee)
2017-03-27 21:22:32 +02:00
Riccardo Spagni
6ba2548273 Merge pull request #612
d730766 useForkRules() - Catch no connection error (Jaquee)
2017-03-27 21:22:08 +02:00
Riccardo Spagni
615ef5342e Merge pull request #609
e231a1b add dutch seed (Jaquee)
2017-03-27 21:21:45 +02:00
moneroj
53e87b4a35 Update monero-core_pt-br.ts 2017-03-28 07:54:26 +13:00
MoroccanMalinois
716010a869 README: QtMultimedia dependency optional 2017-03-27 17:49:54 +00:00
MoroccanMalinois
fb3a6182fc Make QtMultimedia dependency optional 2017-03-27 17:39:47 +00:00
Jaquee
4ee23b2218 update submodule to v0.10.3.1 2017-03-27 18:46:14 +02:00
Jaquee
d730766479 useForkRules() - Catch no connection error 2017-03-26 19:02:18 +02:00
Jaquee
e231a1b63f add dutch seed 2017-03-25 18:14:24 +01:00
Matthias Tarasiewicz
0836bd9cfd Merge branch 'master' into patch-1 2017-03-25 17:22:13 +01:00
Matthias Tarasiewicz
6e381c3857 Update README.md
updated the readme to point to the latest version of QT 5.8 on OSX (on current qt.io installer)

Update README.md
2017-03-25 17:18:41 +01:00
Riccardo Spagni
12573652a0 Merge pull request #608
d85dfa4 enable french seeds (Jaquee)
2017-03-25 17:53:45 +02:00
Riccardo Spagni
6262770e6e Merge pull request #607
7c5cf98 enable esperanto (Jaquee)
2017-03-25 17:51:26 +02:00
Riccardo Spagni
7fbd1cf1ca Merge pull request #604
c3ae7f8 Update monero-core_eo.ts (dnaleor)
5969284 Update monero-core_eo.ts (dnaleor)
bd2a336 Update monero-core_eo.ts (dnaleor)
2017-03-25 17:44:33 +02:00
Riccardo Spagni
88b1403020 Merge pull request #603
46d573e Dutch translation already updated for PR/596 (Roy Jacobs)
2017-03-25 17:41:13 +02:00
Riccardo Spagni
d782eacfd6 Merge pull request #601
413d064 japanese translation: added necessary newlines (kenshi84)
2017-03-25 17:40:27 +02:00
Riccardo Spagni
379b02c80b Merge pull request #600
61266ca Rename monero-core_zh_TW.ts to monero-core_zh-tw.ts (Lafudoci)
84c8f79 Rename monero-core_zh_CN.ts to monero-core_zh-cn.ts (Lafudoci)
b2827ca fix filenames (Lafudoci)
8719caa fix locale string (Lafudoci)
db306ca refine the artwork of zh_TW lang flag (Lafudoci)
b4cab57 Add simplified Chinese translation (zh_CN) (Lafudoci)
2017-03-25 17:39:48 +02:00
Riccardo Spagni
b3877868a3 Merge pull request #597
9c4c34d Use new fee multipliers after v5 fork requires #1915 (Jaquee)
f05f0b7 add WalletManager::useForkRules() (Jaquee)
2017-03-25 17:39:07 +02:00
Riccardo Spagni
716106c23e Merge pull request #596
6fbba9f Settlings.qml: Change "Save" button to "Connect" (xmr-eric)
2017-03-25 17:38:44 +02:00
dnaleor
c3ae7f8c80 Update monero-core_eo.ts
some additions (forgot to translate some strings)
2017-03-25 04:16:19 +01:00
Jaquee
d85dfa4fae enable french seeds 2017-03-24 23:48:49 +01:00
Jaquee
7c5cf985b5 enable esperanto 2017-03-24 23:10:44 +01:00
dnaleor
5969284de8 Update monero-core_eo.ts 2017-03-24 23:02:41 +01:00
Lafudoci
61266ca17e Rename monero-core_zh_TW.ts to monero-core_zh-tw.ts 2017-03-25 00:35:43 +08:00
Lafudoci
84c8f790b6 Rename monero-core_zh_CN.ts to monero-core_zh-cn.ts 2017-03-25 00:35:17 +08:00
Lafudoci
b2827ca1dd fix filenames 2017-03-25 00:33:49 +08:00
Lafudoci
8719caad1b fix locale string 2017-03-25 00:32:49 +08:00
dnaleor
bd2a336c5e Update monero-core_eo.ts 2017-03-24 13:56:45 +01:00
Roy Jacobs
46d573e697 Dutch translation already updated for PR/596 2017-03-24 11:52:24 +01:00
Jaquee
9c4c34d502 Use new fee multipliers after v5 fork
requires #1915
2017-03-24 10:12:14 +01:00
kenshi84
413d064127 japanese translation: added necessary newlines 2017-03-24 15:48:30 +09:00
Lafudoci
db306ca823 refine the artwork of zh_TW lang flag 2017-03-24 13:06:21 +08:00
Lafudoci
b4cab574bc Add simplified Chinese translation (zh_CN) 2017-03-24 13:05:48 +08:00
Jaquee
f05f0b73c3 add WalletManager::useForkRules() 2017-03-23 22:50:57 +01:00
xmr-eric
6fbba9f88c Settlings.qml: Change "Save" button to "Connect" 2017-03-23 13:30:36 -04:00
Riccardo Spagni
b1f5d69ce5 Merge pull request #595
439372e README: add qml-module-qtmultimedia dependency (MoroccanMalinois)
2017-03-23 11:50:00 +02:00
Riccardo Spagni
55116a0963 Merge pull request #594
476fdd4 Further translations and removal of 'unfinished' tags for Bahasa Indonesia (Nano Akron)
2017-03-23 11:49:34 +02:00
Riccardo Spagni
d759e0ee44 Merge pull request #593
9fb7c19 Disable incomplete translations (Jaquee)
caf7b7f fix linkage of translation files (Jaquee)
2017-03-23 11:49:17 +02:00
Riccardo Spagni
f6f8e219e7 Merge pull request #591
2ce4559 Update french translation (Guillaume LE VAILLANT)
2017-03-23 11:48:56 +02:00
Riccardo Spagni
d884edf136 Merge pull request #590
e571979 updated japanese translation (kenshi84)
2017-03-23 11:48:19 +02:00
MoroccanMalinois
439372ed5e README: add qml-module-qtmultimedia dependency 2017-03-23 00:21:34 +00:00
Nano Akron
476fdd4ebe Further translations and removal of 'unfinished' tags for Bahasa Indonesia 2017-03-22 23:03:45 +00:00
Jaquee
9fb7c19b9b Disable incomplete translations 2017-03-22 20:02:21 +01:00
Jaquee
caf7b7fc6b fix linkage of translation files 2017-03-22 17:31:25 +01:00
Guillaume LE VAILLANT
2ce455940d Update french translation 2017-03-22 14:35:14 +01:00
kenshi84
e5719791bd updated japanese translation 2017-03-22 18:53:29 +09:00
Riccardo Spagni
57ae6df949 Merge pull request #589
60890b9 Update monero submodule (Jaquee)
2017-03-22 11:35:49 +02:00
Riccardo Spagni
9f3bd9d896 Merge pull request #586
97f9fb6 Monero-core.ts (xmr-eric)
a3c9c98 Main.qml: Capitalize Insufficient funds message (xmr-eric)
2017-03-22 11:35:08 +02:00
Riccardo Spagni
9e3b3d89b6 Merge pull request #585
48a7596 remove processing splash when transfer fails (Jaquee)
2017-03-22 11:34:35 +02:00
Riccardo Spagni
eb24356a95 Merge pull request #584
93e20be pin submodule to v0.10.3 instead of hash (Jaquee)
2017-03-22 11:33:26 +02:00
Riccardo Spagni
5952ff96d7 Merge pull request #583
a0233f1 BasicPanel.qml Remove negative letter space (xmr-eric)
2017-03-22 11:32:30 +02:00
Riccardo Spagni
89fb48138f Merge pull request #582
df78427 Updated translation files and improved dutch (Roy Jacobs)
2017-03-22 11:32:03 +02:00
Jaquee
60890b9185 Update monero submodule 2017-03-21 22:03:30 +01:00
xmr-eric
97f9fb6f01 Monero-core.ts
Update monero-core_ar.ts

Update monero-core_br.ts

Update monero-core_de.ts

Update monero-core_eo.ts

Update monero-core_es.ts

Update monero-core_fi.ts

Update monero-core_hr.ts

Update monero-core_in.ts

Update monero-core_ja.ts

Update monero-core_pl.ts

Update monero-core_ru.ts

Update monero-core_zh.ts

Update monero-core_fr.ts

Update monero-core_id.ts

Update monero-core_it.ts

Update monero-core_nl.ts
2017-03-21 14:18:30 -04:00
xmr-eric
a3c9c98652 Main.qml: Capitalize Insufficient funds message 2017-03-20 21:28:43 -04:00
Jaquee
48a7596953 remove processing splash when transfer fails 2017-03-20 23:13:03 +01:00
Jaquee
93e20be247 pin submodule to v0.10.3 instead of hash 2017-03-20 22:59:21 +01:00
xmr-eric
a0233f103e BasicPanel.qml Remove negative letter space 2017-03-20 15:40:56 -04:00
Roy Jacobs
df78427745 Updated translation files and improved dutch 2017-03-20 16:36:26 +01:00
Riccardo Spagni
a32b30e98b Merge pull request #579
174d6ad Receive.qml Amount placeholder (xmr-eric)
2017-03-20 16:02:29 +02:00
Riccardo Spagni
f0a441301b Merge pull request #577
2e80510 Update monero submodule to new tag (Jaquee)
2017-03-20 16:01:05 +02:00
xmr-eric
174d6ad019 Receive.qml Amount placeholder 2017-03-19 18:55:33 -04:00
Jaquee
2e8051067f Update monero submodule to new tag 2017-03-19 23:02:41 +01:00
Riccardo Spagni
deb75afb7e Merge pull request #574
a9e975f Mail.qml (xmr-eric)
1d74fa6 Titlebar.qml (xmr-eric)
d920b20 SearchInput.qml (xmr-eric)
ec5c73e Checkbox.qml (xmr-eric)
f3dfd18 DatePicker.qml (xmr-eric)
3ecffbc AddressbookTable.qml (xmr-eric)
b75fee7 TipItem.qml (xmr-eric)
94ca32a MiddlePanel.qml (xmr-eric)
2839bcc BasicPanel.qml (xmr-eric)
91e01d5 HistoryTable.qml (xmr-eric)
760f345 DashboardTable.qml (xmr-eric)
1915759 HistoryTable.qml (xmr-eric)
172243c BasicPanel.qml (xmr-eric)
2017-03-19 23:52:06 +02:00
Riccardo Spagni
62089df6e7 Merge pull request #573
d42d2dd Better spacing for Wizard password warning (xmr-eric)
2017-03-19 23:51:34 +02:00
Riccardo Spagni
2542b14534 Merge pull request #571
064c980 Small button improvements (xmr-eric)
2017-03-19 23:51:06 +02:00
Riccardo Spagni
42fb1ed51d Merge pull request #570
5f2e5b0 Better Integrated address placeholder (xmr-eric)
2017-03-19 23:50:43 +02:00
Riccardo Spagni
23a3b1265a Merge pull request #569
10b00f8 Edit: Removed bold (xmr-eric)
7ab5511 Better copy for mining page (xmr-eric)
2017-03-19 23:50:23 +02:00
Riccardo Spagni
1fe0600e1e Merge pull request #567
51074a8 Add a clear payment ID button (Michael Campagnaro)
43a33e7 Don't set a default payment ID on receive page (Michael Campagnaro)
2017-03-19 23:49:50 +02:00
xmr-eric
a9e975f2cd Mail.qml 2017-03-19 13:50:52 -04:00
xmr-eric
1d74fa6f47 Titlebar.qml 2017-03-19 13:49:26 -04:00
xmr-eric
d920b20168 SearchInput.qml 2017-03-19 13:48:52 -04:00
xmr-eric
ec5c73e8aa Checkbox.qml 2017-03-19 13:48:09 -04:00
xmr-eric
f3dfd18641 DatePicker.qml 2017-03-19 13:47:37 -04:00
xmr-eric
3ecffbc767 AddressbookTable.qml 2017-03-19 13:46:39 -04:00
xmr-eric
b75fee7a68 TipItem.qml 2017-03-19 13:45:59 -04:00
xmr-eric
94ca32a164 MiddlePanel.qml 2017-03-19 13:45:21 -04:00
xmr-eric
2839bcc7fb BasicPanel.qml 2017-03-19 13:44:24 -04:00
xmr-eric
91e01d5470 HistoryTable.qml 2017-03-19 13:43:36 -04:00
xmr-eric
760f34579f DashboardTable.qml 2017-03-19 13:41:43 -04:00
xmr-eric
19157590a5 HistoryTable.qml 2017-03-19 13:40:36 -04:00
xmr-eric
172243cdad BasicPanel.qml 2017-03-19 13:39:03 -04:00
xmr-eric
d42d2dd742 Better spacing for Wizard password warning
Title was butted right up against warning. No more.
2017-03-19 13:35:02 -04:00
xmr-eric
10b00f8778 Edit: Removed bold 2017-03-19 12:13:00 -04:00
xmr-eric
064c9805f6 Small button improvements 2017-03-18 22:57:48 -04:00
xmr-eric
5f2e5b041c Better Integrated address placeholder 2017-03-18 21:15:42 -04:00
xmr-eric
7ab5511de3 Better copy for mining page 2017-03-18 19:32:25 -04:00
Michael Campagnaro
51074a8fe6 Add a clear payment ID button 2017-03-18 18:28:29 -04:00
Michael Campagnaro
43a33e717d Don't set a default payment ID on receive page 2017-03-18 18:01:00 -04:00
Riccardo Spagni
69e037ba4d Merge pull request #566
cdb9376 Update monero submodule to v0.10.3 (Jaquee)
2017-03-18 23:03:41 +02:00
Jaquee
cdb9376b85 Update monero submodule to v0.10.3 2017-03-18 21:59:53 +01:00
Riccardo Spagni
24c17a9fe3 Merge pull request #565
628483c Updated translation files after PR's (Roy Jacobs)
2017-03-18 22:33:17 +02:00
Roy Jacobs
628483c310 Updated translation files after PR's 2017-03-18 20:17:07 +01:00
Riccardo Spagni
aeea9ad324 Merge pull request #562
53d7962 Improve text wrap on mining page (Michael Campagnaro)
2017-03-18 11:48:47 +02:00
Riccardo Spagni
8655076b92 Merge pull request #561
58e68be Dutch translation update (Roy Jacobs)
2017-03-18 11:48:04 +02:00
Riccardo Spagni
4310fb096b Merge pull request #559
ce8e5fe Update monero-core_it.ts (Shrikez1)
2017-03-18 11:46:45 +02:00
Riccardo Spagni
62fe3820e2 Merge pull request #558
577726c Updated translation for Bahasa Indonesia (Nano Akron)
2017-03-18 11:44:53 +02:00
Riccardo Spagni
e4aa338869 Merge pull request #557
e4a1143 Add testnet label (Jaquee)
2017-03-18 11:43:50 +02:00
Riccardo Spagni
f22e5fdd7b Merge pull request #556
2b24c91 Add missing, fix and improve translations (Roy Jacobs)
2017-03-18 11:43:18 +02:00
Riccardo Spagni
ed28144ae8 Merge pull request #555
692f927 Update traditional Chinese translation (Lafudoci)
35cd788 add flag for zh_tw (Lafudoci)
2017-03-18 11:42:28 +02:00
Riccardo Spagni
0090303a18 Merge pull request #552
5cf84ff Fixed linux compile instructions (Timo Uhlmann)
2017-03-18 11:41:50 +02:00
Riccardo Spagni
d6dd97f308 Merge pull request #549
82cb509 README: Updating Mac OSX Build notes and adding heading. (Jonathan Cross)
2017-03-18 11:41:05 +02:00
Michael Campagnaro
53d7962eaa Improve text wrap on mining page 2017-03-17 17:55:30 -04:00
Roy Jacobs
58e68be613 Dutch translation update 2017-03-17 21:35:27 +01:00
Shrikez1
ce8e5fe714 Update monero-core_it.ts
added (most) missing italian translations
2017-03-17 07:36:59 +01:00
Nano Akron
577726c184 Updated translation for Bahasa Indonesia
This will no doubt be torn to shreds by a native speaker, but it at least gives us a chance to reach them.
2017-03-17 00:12:17 +00:00
Jaquee
e4a114321f Add testnet label 2017-03-16 17:02:57 +01:00
Roy Jacobs
2b24c91bc5 Add missing, fix and improve translations 2017-03-14 15:14:02 +01:00
Lafudoci
692f927903 Update traditional Chinese translation
Minor zh_tw translation fix

Minor zh_tw translation fix

squash
2017-03-14 14:56:02 +08:00
Lafudoci
35cd788968 add flag for zh_tw
Correct the indication and flag of zh_tw

Add lan flag for zh_tw

Update traditional Chinese translation

Delete monero-core_zh.ts

Update traditional Chinese translation

Delete monero-core_zh.ts

Update traditional Chinese translation

Delete monero-core_zh.ts

Add files via upload

squash

Change zh_tw flag title for less controversy

squash
2017-03-14 14:55:48 +08:00
Jonathan Cross
82cb50994c README: Updating Mac OSX Build notes and adding heading. 2017-03-11 20:48:10 +01:00
Riccardo Spagni
897bc582f0 Merge pull request #551
7960241 Update french translation (Guillaume LE VAILLANT)
2017-03-11 20:32:12 +01:00
Riccardo Spagni
b0d0974561 Merge pull request #550
c45cc3d enabled translations in some places (kenshi84)
6364530 updated Japanese translation (kenshi84)
2017-03-11 20:31:02 +01:00
Riccardo Spagni
fd4619628c Merge pull request #547
3c8a552 fix addressbook button width (Jaquee)
6a666ea fix dynamic width on send btn (Jaquee)
1918c5e fix dynamic button width (Jaquee)
2017-03-11 20:30:23 +01:00
Timo Uhlmann
5cf84ff1f5 Fixed linux compile instructions 2017-03-11 19:35:27 +01:00
Guillaume LE VAILLANT
7960241306 Update french translation 2017-03-11 15:57:37 +01:00
Jaquee
3c8a552522 fix addressbook button width 2017-03-11 15:38:01 +01:00
Jaquee
6a666ead39 fix dynamic width on send btn 2017-03-11 15:36:27 +01:00
Jaquee
1918c5e24a fix dynamic button width 2017-03-11 15:36:25 +01:00
kenshi84
c45cc3de41 enabled translations in some places 2017-03-11 14:09:09 +09:00
kenshi84
6364530b86 updated Japanese translation 2017-03-11 14:07:52 +09:00
Riccardo Spagni
b757cc28b8 Merge pull request #548
4c2f78a Fix translations in dropdown menu (Jaquee)
2017-03-10 14:32:08 +00:00
Riccardo Spagni
b8745299ba Merge pull request #546
ea1d2c3 Last translation files update for PR (Roy Jacobs)
a2f01ea Added missing Receive/Settings/Sign/Transfer translations (Roy Jacobs)
1a1a7a9 Added missing AddressBook translations (Roy Jacobs)
e3daa4b Updated translation files and improved the dutch translation (Roy Jacobs)
c30586c Fixed missing translation (Roy Jacobs)
c9825c5 Updated dutch translation (Roy Jacobs)
ab809b0 Updates translation files (Roy Jacobs)
5589ef7 Fixes missing translations (Roy Jacobs)
2017-03-10 14:31:25 +00:00
Riccardo Spagni
1b021c599b Merge pull request #545
27bc424 Fixed mingw path (Roy Jacobs)
f544ece Improved windows host/target detection and fixed buildbot building (Roy Jacobs)
2017-03-10 14:30:24 +00:00
Jaquee
4c2f78a78b Fix translations in dropdown menu 2017-03-09 16:46:03 +01:00
Roy Jacobs
ea1d2c3731 Last translation files update for PR 2017-03-09 01:36:59 +01:00
Roy Jacobs
a2f01ea541 Added missing Receive/Settings/Sign/Transfer translations 2017-03-09 01:28:24 +01:00
Roy Jacobs
1a1a7a991b Added missing AddressBook translations 2017-03-08 23:35:19 +01:00
Roy Jacobs
e3daa4b16e Updated translation files and improved the dutch translation 2017-03-08 22:31:01 +01:00
Roy Jacobs
c30586ccc8 Fixed missing translation 2017-03-08 21:12:17 +01:00
Roy Jacobs
c9825c5c5b Updated dutch translation 2017-03-08 19:38:57 +01:00
Roy Jacobs
ab809b0df9 Updates translation files 2017-03-08 19:11:30 +01:00
Roy Jacobs
5589ef7fc9 Fixes missing translations 2017-03-08 19:10:35 +01:00
Riccardo Spagni
b611871940 Merge pull request #543
8429cec Update copyright (xmr-eric)
2017-03-08 17:41:33 +00:00
Roy Jacobs
27bc424f04 Fixed mingw path 2017-03-08 14:21:35 +01:00
Roy Jacobs
f544eceaa5 Improved windows host/target detection and fixed buildbot building 2017-03-08 14:05:02 +01:00
xmr-eric
8429cec6c3 Update copyright 2017-03-07 16:01:32 -05:00
Riccardo Spagni
632d347d07 Merge pull request #541
bd95908 update history when new block is found (Jaquee)
2017-03-07 11:03:59 +00:00
Riccardo Spagni
7a79d318a6 Merge pull request #540
630a852 Fixes reliable building in both mingw32 shell as Qt creator. Cleans redundant path naming. (Roy Jacobs)
2a8419c Windows build guide updated (Roy Jacobs)
b43f88c Boost paths fixed for building in Msys2-mingw (Roy Jacobs)
2017-03-07 11:03:50 +00:00
Riccardo Spagni
3273d1f935 Merge pull request #539
c75d3cf fix wizard spacing and dots (Jaquee)
2017-03-07 11:03:13 +00:00
Riccardo Spagni
9f01082937 Merge pull request #538
7987455 reset balance on wallet close (Jaquee)
2017-03-07 11:02:34 +00:00
Riccardo Spagni
05c15930c3 Merge pull request #537
694352c update history page after restore (Jaquee)
2017-03-07 11:02:25 +00:00
Riccardo Spagni
a6f3510ee4 Merge pull request #535
03eaaa4 mining: disable mining status check for remote nodes (Jaquee)
2017-03-07 11:02:13 +00:00
Riccardo Spagni
10d32032e9 Merge pull request #534
64d1e15 add top margin when custom decorations are used (Jaquee)
2017-03-07 11:01:34 +00:00
Riccardo Spagni
9e62e1e097 Merge pull request #533
fb014d8 Update Ubuntu 16.04 x64 dependencies (Timo Uhlmann)
2017-03-07 11:01:23 +00:00
Riccardo Spagni
fed4dd4654 Merge pull request #532
1ff4e90 bring back restore height field (Jaquee)
2017-03-07 11:01:08 +00:00
Riccardo Spagni
0f3f6d215c Merge pull request #530
4fe6b1f recieve page: change payment id description to 16 hex (Jaquee)
2017-03-07 11:00:50 +00:00
Jaquee
bd959085f2 update history when new block is found 2017-03-05 00:05:31 +01:00
Roy Jacobs
630a852669 Fixes reliable building in both mingw32 shell as Qt creator.
Cleans redundant path naming.
2017-03-04 12:17:51 +01:00
Roy Jacobs
2a8419c7cd Windows build guide updated 2017-03-04 06:02:23 +01:00
Roy Jacobs
b43f88cece Boost paths fixed for building in Msys2-mingw 2017-03-04 04:23:20 +01:00
Jaquee
c75d3cf9ec fix wizard spacing and dots 2017-03-04 00:32:53 +01:00
Jaquee
7987455fcf reset balance on wallet close 2017-03-04 00:11:26 +01:00
Jaquee
694352c1df update history page after restore 2017-03-03 23:57:55 +01:00
Jaquee
03eaaa46e0 mining: disable mining status check for remote nodes 2017-03-03 22:01:57 +01:00
Jaquee
64d1e1546a add top margin when custom decorations are used 2017-03-03 21:14:26 +01:00
Timo Uhlmann
fb014d8aff Update Ubuntu 16.04 x64 dependencies 2017-03-03 21:13:43 +01:00
Jaquee
1ff4e9030b bring back restore height field 2017-03-03 19:45:18 +01:00
Jaquee
4fe6b1fd0b recieve page: change payment id description to 16 hex 2017-03-03 18:18:55 +01:00
Riccardo Spagni
27e8090096 Merge pull request #529
e3f81b9 WizardPasswordInput.qml Smaller fontsize (xmr-eric)
2017-03-03 19:16:31 +02:00
xmr-eric
e3f81b9c49 WizardPasswordInput.qml Smaller fontsize 2017-03-03 12:07:40 -05:00
Riccardo Spagni
2e3350c060 Merge pull request #519
223f09d preparations for background mining requires #1827 (Jaquee)
2017-03-03 16:55:23 +02:00
Riccardo Spagni
5db9bd9fdd Merge pull request #515
01e735c move OK button to the right in confirm exit dialog (Jaquee)
bce496b confirm daemon running on exit (Jaquee)
2017-03-03 16:55:09 +02:00
Jaquee
223f09dc94 preparations for background mining
requires #1827
2017-03-03 15:44:01 +01:00
Jaquee
01e735cc0e move OK button to the right in confirm exit dialog 2017-03-03 15:40:46 +01:00
Jaquee
bce496b8d1 confirm daemon running on exit 2017-03-03 15:40:42 +01:00
Riccardo Spagni
988e299290 Merge pull request #498
4e29c14 transfer: increased top margin (Jaquee)
30f87a1 Transfer: hide advanced options (Jaquee)
2017-03-03 16:36:34 +02:00
Riccardo Spagni
cc86720936 Merge pull request #528
5d6e0f5 Trim daemon address (Jaquee)
2017-03-03 16:30:38 +02:00
Riccardo Spagni
0e8b28b958 Merge pull request #527
2ea54a2 adjust unlocked balance waiting text (Jaquee)
2017-03-03 16:30:09 +02:00
Riccardo Spagni
30cfe1041a Merge pull request #526
578cafb increase wizard height (Jaquee)
2017-03-03 16:29:26 +02:00
Riccardo Spagni
18eb7a02cc Merge pull request #525
9c0002a fix undefined buildwithscanner (Jaquee)
2017-03-03 16:28:49 +02:00
Riccardo Spagni
e4bb7bed98 Merge pull request #523
8c17a8c fix build with scanner (MoroccanMalinois)
2017-03-03 16:28:31 +02:00
Riccardo Spagni
cebf4a01a8 Merge pull request #521
3d9ffca LeftPanel.qml (xmr-eric)
c7435c5 MenuButton.qml (xmr-eric)
2017-03-03 16:28:05 +02:00
Riccardo Spagni
afbfbeaa49 Merge pull request #518
cf36420 mining: make threads parameter optional (Jaquee)
2017-03-03 16:27:04 +02:00
Riccardo Spagni
339d78c4ab Merge pull request #517
114ce41 seed password not closing (Jaquee)
2017-03-03 16:26:41 +02:00
Riccardo Spagni
62f016387f Merge pull request #516
8dc95a1 remove animation when swithing to basic layout (Jaquee)
d9a2b1a fix broken basic button (Jaquee)
2017-03-03 16:26:02 +02:00
Riccardo Spagni
9859f33914 Merge pull request #514
e4314dd only enable high dpi scaling on qt >= 5.6 (Jaquee)
e90c186 Fix high DPI scaling (Jaquee)
2017-03-03 16:24:49 +02:00
Jaquee
4e29c1474e transfer: increased top margin 2017-03-03 15:23:23 +01:00
Jaquee
30f87a1019 Transfer: hide advanced options 2017-03-03 15:23:22 +01:00
Riccardo Spagni
9fb884e5a6 Merge pull request #513
d5e1d3e Shorten some strings in french translation (Guillaume LE VAILLANT)
2017-03-03 16:23:05 +02:00
Riccardo Spagni
c9d6267f67 Merge pull request #512
97bda6d Dutch translation fix to proper sentence (Roy Jacobs)
05ef5ea Many fixes and additions to the dutch translation (Roy Jacobs)
2017-03-03 16:22:46 +02:00
Riccardo Spagni
9b633824d5 Merge pull request #511
6e966f8 Indicate that the chinese translation uses traditional characters (Guillaume LE VAILLANT)
2bbb585 Add flags for translations (Guillaume LE VAILLANT)
2017-03-03 16:21:46 +02:00
Riccardo Spagni
573b284017 Merge pull request #508
677432f Better styling for Miner (xmr-eric)
2017-03-03 16:20:25 +02:00
Riccardo Spagni
14ea15e870 Merge pull request #506
67e5042 Better styling for password meter (xmr-eric)
2017-03-03 16:18:57 +02:00
Riccardo Spagni
f11ec2d0bd Merge pull request #504
44bcb3d Update PrivacyLevelSmall.qml (xmr-eric)
e8875e0 PrivacyLevelSmall.qml: mixed case for Wizard (xmr-eric)
d354d4a Sign Verify: keep text mixed case (xmr-eric)
d1202e4 TxKey.qml: Keep text mixed case (xmr-eric)
08d5730 History.qml: Keep text mixed case (xmr-eric)
92a5781 Addressbook.qml: Keep text mixed case (xmr-eric)
9ac8e26 TickDelegate.qml: Keep text mixed case (xmr-eric)
0b017ff Transfer.qml: Keep buttons mixed case (xmr-eric)
2017-03-03 16:18:31 +02:00
Riccardo Spagni
36f245e983 Merge pull request #503
d855cb1 add indonesia flag (Jaquee)
2017-03-03 16:17:47 +02:00
Riccardo Spagni
6e2e8a55c2 Merge pull request #502
a34b7c7 May seem petty, but it's a real political sticking-point in China (Nano Akron)
2017-03-03 16:17:16 +02:00
Riccardo Spagni
50ee218198 Merge pull request #496
be09e3e Wizard: make sure next button is visible when stepping back (Jaquee)
ebcab01 Wizard: mobile redesign (Jaquee)
2017-03-03 16:15:57 +02:00
Riccardo Spagni
5b1588b077 Merge pull request #494
00aa231 Daemon rpc login support requires #1803 (Jaquee)
2017-03-03 16:14:33 +02:00
Jaquee
5d6e0f5851 Trim daemon address 2017-03-03 12:40:50 +01:00
Jaquee
2ea54a2401 adjust unlocked balance waiting text 2017-03-03 12:30:53 +01:00
Jaquee
578cafb059 increase wizard height 2017-03-03 12:07:25 +01:00
Jaquee
9c0002ad9a fix undefined buildwithscanner 2017-03-03 09:36:21 +01:00
MoroccanMalinois
8c17a8c388 fix build with scanner 2017-03-03 02:39:49 +00:00
xmr-eric
3d9ffca016 LeftPanel.qml 2017-03-02 13:14:44 -05:00
xmr-eric
c7435c5dfa MenuButton.qml 2017-03-02 13:13:54 -05:00
Jaquee
cf364206de mining: make threads parameter optional 2017-03-02 14:34:11 +01:00
Jaquee
114ce41fcc seed password not closing 2017-03-02 13:13:13 +01:00
Jaquee
8dc95a17e6 remove animation when swithing to basic layout 2017-03-02 12:40:58 +01:00
Jaquee
d9a2b1aa60 fix broken basic button 2017-03-02 12:40:36 +01:00
Jaquee
e4314ddb4c only enable high dpi scaling on qt >= 5.6 2017-03-02 09:28:43 +01:00
xmr-eric
44bcb3d06c Update PrivacyLevelSmall.qml 2017-03-01 18:45:55 -05:00
Jaquee
e90c18603a Fix high DPI scaling
not android
2017-03-01 20:21:00 +01:00
Guillaume LE VAILLANT
d5e1d3ea60 Shorten some strings in french translation 2017-03-01 14:57:30 +01:00
Roy Jacobs
97bda6d597 Dutch translation fix to proper sentence 2017-03-01 13:09:12 +01:00
Roy Jacobs
05ef5eabf6 Many fixes and additions to the dutch translation 2017-03-01 03:29:11 +01:00
Guillaume LE VAILLANT
6e966f8ae0 Indicate that the chinese translation uses traditional characters 2017-02-28 13:41:00 +01:00
Guillaume LE VAILLANT
2bbb585fc7 Add flags for translations 2017-02-28 12:13:11 +01:00
xmr-eric
677432f634 Better styling for Miner 2017-02-27 20:43:29 -05:00
xmr-eric
67e504288f Better styling for password meter 2017-02-27 19:50:58 -05:00
xmr-eric
e8875e0e1f PrivacyLevelSmall.qml: mixed case for Wizard 2017-02-27 18:58:17 -05:00
xmr-eric
d354d4aa54 Sign Verify: keep text mixed case 2017-02-27 17:12:13 -05:00
Jaquee
d855cb1542 add indonesia flag 2017-02-27 23:11:08 +01:00
xmr-eric
d1202e44eb TxKey.qml: Keep text mixed case 2017-02-27 17:09:23 -05:00
xmr-eric
08d5730fbe History.qml: Keep text mixed case 2017-02-27 17:08:07 -05:00
xmr-eric
92a5781b6a Addressbook.qml: Keep text mixed case 2017-02-27 17:06:05 -05:00
xmr-eric
9ac8e26a48 TickDelegate.qml: Keep text mixed case 2017-02-27 17:03:51 -05:00
xmr-eric
0b017ff954 Transfer.qml: Keep buttons mixed case 2017-02-27 17:02:33 -05:00
Nano Akron
a34b7c7136 May seem petty, but it's a real political sticking-point in China
This also means that the same 'Chinese' (mainland) flag will be used
for both traditional and simplified writing systems.
2017-02-27 21:22:25 +00:00
Jaquee
be09e3e596 Wizard: make sure next button is visible when stepping back 2017-02-27 22:07:17 +01:00
Jaquee
ebcab010bb Wizard: mobile redesign 2017-02-27 22:07:16 +01:00
Riccardo Spagni
e826f7c1ec Merge pull request #497
4c1bf7d Add translation files to project file (Guillaume LE VAILLANT)
8d35711 Remove duplicate translation file (Guillaume LE VAILLANT)
1c79aaf Update french translation (Guillaume LE VAILLANT)
2017-02-27 22:30:51 +02:00
Riccardo Spagni
c524e226de Merge pull request #495
4ff4118 Activate Bahasa Indonesia translation with flag (Nano Akron)
2017-02-27 22:30:16 +02:00
Riccardo Spagni
86a387046f Merge pull request #493
1f1aa98 Notifier: make this look nicer (moneromooo.monero)
2017-02-27 22:30:01 +02:00
Riccardo Spagni
75bb620cb6 Merge pull request #492
8021037 pause refresh while starting daemon + startup timeout (Jaquee)
df60c81 add start/pauseRefresh() (Jaquee)
2ed59f4 Daemon manager improvements (Jaquee)
2017-02-27 22:29:33 +02:00
Riccardo Spagni
0f69ca4bff Merge pull request #491
ce10016 omit --detach flag on windows (Jaquee)
2017-02-27 22:29:11 +02:00
Riccardo Spagni
3f0f942779 Merge pull request #490
53c86ad remove undefined variable error (Jaquee)
023d96b avoid dangling pointers in destructor (Jaquee)
2017-02-27 22:28:47 +02:00
Riccardo Spagni
f738b6ac67 Merge pull request #489
3adeab8 wallet sync: progressbar ui improvements (Jaquee)
2d6ddf0 Improved blockchain sync status ui (Jaquee)
465f6bf fix daemon startup with --check-updates disabled (Jaquee)
2017-02-27 22:25:09 +02:00
Riccardo Spagni
fc6a214197 Merge pull request #488
a0fcf59 do not use -lGL for android (MoroccanMalinois)
2017-02-27 22:24:48 +02:00
Guillaume LE VAILLANT
4c1bf7dcf8 Add translation files to project file
Also fix a few typos in translations files leading to parsing errors.
2017-02-27 16:39:35 +01:00
Guillaume LE VAILLANT
8d35711448 Remove duplicate translation file
We have a monero-core_zh.ts file which doesn't contain any translated
strings, and a monero-core_zh_TW.ts file which contains translated
strings. So let's delete the empty file and rename
monero-core_zh_TW.ts to monero-core_zh.ts.
2017-02-27 15:44:41 +01:00
Guillaume LE VAILLANT
1c79aaff87 Update french translation 2017-02-27 15:18:17 +01:00
Nano Akron
4ff41181dc Activate Bahasa Indonesia translation with flag 2017-02-26 12:11:04 +00:00
Jaquee
00aa23162c Daemon rpc login support
requires #1803
2017-02-25 22:18:52 +01:00
moneromooo.monero
1f1aa9859b Notifier: make this look nicer 2017-02-25 20:41:58 +00:00
Jaquee
80210376f3 pause refresh while starting daemon + startup timeout 2017-02-25 20:25:16 +01:00
Jaquee
df60c8190b add start/pauseRefresh() 2017-02-25 19:49:09 +01:00
Jaquee
2ed59f41ed Daemon manager improvements 2017-02-25 14:57:39 +01:00
Jaquee
ce10016408 omit --detach flag on windows 2017-02-25 10:12:32 +01:00
Jaquee
53c86adbbe remove undefined variable error 2017-02-25 00:20:08 +01:00
Jaquee
023d96bc3e avoid dangling pointers in destructor 2017-02-25 00:19:37 +01:00
Jaquee
3adeab87ed wallet sync: progressbar ui improvements 2017-02-24 21:51:37 +01:00
Jaquee
2d6ddf043e Improved blockchain sync status ui 2017-02-24 18:08:22 +01:00
MoroccanMalinois
a0fcf59348 do not use -lGL for android 2017-02-24 16:29:35 +00:00
Jaquee
465f6bfe27 fix daemon startup with --check-updates disabled 2017-02-24 16:57:44 +01:00
Riccardo Spagni
2ca2376d45 Merge pull request #486
faacd3d start daemon automatically and detached (Jaquee)
2017-02-24 16:04:13 +02:00
Riccardo Spagni
6120013ae2 Merge pull request #485
5bfa9b5 Main.qml: Make ringsize one word (xmr-eric)
3ed4dee Transfer.qml: Make ringsize one word (xmr-eric)
2017-02-24 16:03:44 +02:00
Riccardo Spagni
65d9bde498 Merge pull request #481
9736250 Add updates notifier (moneromooo.monero)
2017-02-24 16:03:17 +02:00
Riccardo Spagni
6a40d38b93 Merge pull request #480
27541f6 fix log init (moneromooo.monero)
2017-02-24 16:02:51 +02:00
Riccardo Spagni
6075592f62 Merge pull request #478
3759e27 spelling (MiWCryptAnalytics)
20517cf fix: add ldl to non-static linux builds (MiWCryptAnalytics)
2e8306b Potential fix for undefined reference 'dlsym' linux (MiWCryptAnalytics)
2017-02-24 16:02:25 +02:00
Riccardo Spagni
fe6a095175 Merge pull request #477
f33a824 potential fix Parse error monero-core_de.ts:500:59: (MiWCryptAnalytics)
2017-02-24 15:57:53 +02:00
Riccardo Spagni
c909ab794a Merge pull request #471
54ee034 updated translation files (Jaquee)
166a285 remove MISS_TR from untranslated strings (Jaquee)
69479ef Enable all translations (Jaquee)
2017-02-24 15:56:12 +02:00
MiWCryptAnalytics
3759e276b2 spelling 2017-02-23 21:23:55 -05:00
MiWCryptAnalytics
20517cfd4d fix: add ldl to non-static linux builds
proposes a fix to add ldl conditionally on non-static build, to fix build failures
2017-02-23 21:23:06 -05:00
Jaquee
faacd3d6a1 start daemon automatically and detached 2017-02-23 19:52:06 +01:00
moneromooo.monero
97362504e8 Add updates notifier 2017-02-22 23:19:29 +00:00
xmr-eric
5bfa9b5734 Main.qml: Make ringsize one word 2017-02-22 14:20:31 -05:00
xmr-eric
3ed4dee00e Transfer.qml: Make ringsize one word 2017-02-22 14:19:50 -05:00
Jaquee
54ee0344b8 updated translation files
rebased and fixed error in german translation
2017-02-22 12:24:34 +01:00
Jaquee
166a285a28 remove MISS_TR from untranslated strings 2017-02-22 12:19:46 +01:00
Jaquee
69479efcf3 Enable all translations 2017-02-22 12:19:45 +01:00
moneromooo.monero
27541f6ec9 fix log init 2017-02-18 20:45:15 +00:00
MiWCryptAnalytics
2e8306b341 Potential fix for undefined reference 'dlsym' linux
Fix for undefined reference including ldl. add -ldl to linux LIBS for Makefile.

/usr/bin/ld: /tmp/ccYIfntN.ltrans11.ltrans.o: undefined reference to symbol 'dlsym@@GLIBC_2.2.5'
/usr/lib/libdl.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make: *** [Makefile:388: release/bin/monero-wallet-gui] Error 1
2017-02-18 14:13:30 -05:00
MiWCryptAnalytics
f33a824708 potential fix Parse error monero-core_de.ts:500:59:
Error during build:

/usr/bin/lrelease -compress -nounfinished -removeidentical ../translations/monero-core_de.ts -qm /x/monero-core/build/release/bin/translations/monero-core_de.qm
lrelease error: Parse error at ../translations/monero-core_de.ts:500:59: Expected '#' or '[a-zA-Z]', but got '%'.

Appears to be a typo in german translation file. Removing character builds this stage OK
2017-02-18 14:04:12 -05:00
Riccardo Spagni
c6688dc876 Merge pull request #473
34415bb Update monero-core_nl.ts (keesieboy)
2017-02-17 21:47:07 +02:00
Riccardo Spagni
de1d7046ee Merge pull request #472
cc06fab Create monero-core_eo.ts (dnaleor)
2017-02-17 21:46:48 +02:00
Riccardo Spagni
0e9ab11213 Merge pull request #468
ccdea1b Update monero-core_de.ts (hundehausen)
2017-02-17 21:45:23 +02:00
Riccardo Spagni
4a216ff786 Merge pull request #466
ad58e00 linux: remove rpath requires #1709 (Jaquee)
57a556a Linux: static libgcc and libstdc++ (Jaquee)
2017-02-17 21:44:19 +02:00
Riccardo Spagni
57fa9830b6 Merge pull request #463
d589ab4 send all debug output to easylogger (Jaquee)
2017-02-17 21:43:53 +02:00
Riccardo Spagni
87f55992f0 Merge pull request #455
c94bd2f linux: remove rpath requires #1709 (Jaquee)
2083357 Linux: static libgcc and libstdc++ (Jaquee)
08ceb5e settings: replace seed  box with popup requires #1709 (Jaquee)
2017-02-17 21:43:12 +02:00
Jaquee
d589ab4058 send all debug output to easylogger 2017-02-16 07:48:07 +01:00
keesieboy
34415bb660 Update monero-core_nl.ts
Spotted a minor flaw, my mistake. Changed line 113 from 'Abbrechen' -> 'Annuleren'.
2017-02-15 17:17:21 +01:00
dnaleor
cc06fab125 Create monero-core_eo.ts
Esperanto translation
2017-02-14 03:52:36 +01:00
Jaquee
c94bd2ff72 linux: remove rpath
requires #1709
2017-02-11 19:41:23 +01:00
Jaquee
20833579e9 Linux: static libgcc and libstdc++ 2017-02-11 19:41:23 +01:00
Jaquee
08ceb5eba0 settings: replace seed box with popup
requires #1709
2017-02-11 19:30:09 +01:00
Jaquee
ad58e0008b linux: remove rpath
requires #1709
2017-02-11 18:09:47 +01:00
Jaquee
57a556a495 Linux: static libgcc and libstdc++ 2017-02-11 17:47:16 +01:00
hundehausen
ccdea1bf57 Update monero-core_de.ts
Added some Strings and did very few corrections, somebody should take a look over it again
2017-02-09 21:39:54 +01:00
Riccardo Spagni
fdc71d2b18 Merge pull request #465
4bcfe63 build libepee if monerod skipped (MoroccanMalinois)
2017-02-08 12:45:21 +02:00
Riccardo Spagni
ea7fab6efe Merge pull request #464
16be0ee wizard: field bg color (Jaquee)
2017-02-08 12:44:24 +02:00
Riccardo Spagni
1869e81883 Merge pull request #460
02ab113 clear payment fields after transfer (Jaquee)
756a821 Wizard: clear restore from keys fields on wizard restart (Jaquee)
2017-02-08 12:43:48 +02:00
Riccardo Spagni
fa4078f38c Merge pull request #459
40540cb Save custom log categories to persistent settings (moneromooo.monero)
2017-02-08 12:43:29 +02:00
Riccardo Spagni
e145793d2f Merge pull request #458
8a0163f don't show daemon popup when connected (Jaquee)
2017-02-08 12:43:04 +02:00
Riccardo Spagni
36cd7a625f Merge pull request #456
fb743a0 main: mixin 4 is ring size 5, not 41... (moneromooo.monero)
2017-02-08 12:42:28 +02:00
Riccardo Spagni
3640bedeee Merge pull request #454
168e354 replace nbsp with ascii equivalent (Jaquee)
2017-02-08 12:40:36 +02:00
Riccardo Spagni
2901a33698 Merge pull request #440
78302be IOS specific settings (Jaquee)
c6dc9a2 IOS build settings (Jaquee)
2017-02-08 12:39:11 +02:00
MoroccanMalinois
4bcfe63c57 build libepee if monerod skipped 2017-02-07 01:52:01 +00:00
Jaquee
02ab113762 clear payment fields after transfer 2017-02-05 20:26:58 +01:00
Jaquee
16be0ee344 wizard: field bg color 2017-02-05 20:24:16 +01:00
Jaquee
78302be193 IOS specific settings 2017-02-05 15:22:43 +01:00
Jaquee
c6dc9a20e7 IOS build settings 2017-02-05 15:22:03 +01:00
Jaquee
756a821f41 Wizard: clear restore from keys fields on wizard restart 2017-02-05 14:04:50 +01:00
Jaquee
8a0163f14a don't show daemon popup when connected 2017-02-05 13:49:25 +01:00
moneromooo.monero
40540cb38a Save custom log categories to persistent settings 2017-02-05 12:38:43 +00:00
moneromooo.monero
fb743a0532 main: mixin 4 is ring size 5, not 41... 2017-02-04 20:20:06 +00:00
Jaquee
168e3544d0 replace nbsp with ascii equivalent 2017-02-04 19:00:20 +01:00
Riccardo Spagni
979acf774a Merge pull request #453
b80d949 remove &nbsp from french translation (Jaquee)
2017-02-04 19:33:35 +02:00
Jaquee
b80d9498ef remove &nbsp from french translation 2017-02-04 18:26:47 +01:00
Riccardo Spagni
6965b0af19 Merge pull request #451
8060307 wizard: fix focus (Jaquee)
2017-02-04 17:47:45 +02:00
Riccardo Spagni
99230e3ff1 Merge pull request #443
7ab3373 use gmake on bsd in build.sh (pigeons)
2017-02-04 17:47:27 +02:00
Riccardo Spagni
739d24efb4 Merge pull request #442
0b41fbc Don't close/reopen when changing daemon requires #1655 (Jaquee)
2586404 sync progress improvements (Jaquee)
eb909e1 async connectionStatus and init (Jaquee)
cb3281d WalletManager: fix possible race (Jaquee)
9dbbd4c WalletManager: check connection before isMining() (Jaquee)
2017-02-04 17:46:57 +02:00
Riccardo Spagni
f2a583fd49 Merge pull request #433
faeead2 Better placeholders (xmr-eric)
9425b77 Payment ID Placeholder: 64 characters only (xmr-eric)
ce87a1c Added AddressBook.qml placeholders (xmr-eric)
2017-02-04 17:44:47 +02:00
Riccardo Spagni
488e4e2b86 Merge pull request #430
4e2e262 Main.qml: Ringsize equals mixin +1 (xmr-eric)
f1327ac Ringsize equals mixin +1 (xmr-eric)
2d12a3c Main.qml: Changed mixin to ring size (xmr-eric)
16f5889 Transfer.qml: Changed mixin to ring size (xmr-eric)
2017-02-04 17:44:20 +02:00
Riccardo Spagni
7e8b6de186 Merge pull request #429
58147a2 Minor spelling corrections (David)
2017-02-04 17:43:42 +02:00
Riccardo Spagni
6c8e770a61 Merge pull request #426
93d2eb5 add qrcode scanner (MoroccanMalinois)
2017-02-04 17:43:03 +02:00
Riccardo Spagni
e16180c2a5 Merge pull request #417
c51a28f fix advanced hotkey + menu separators (Jaquee)
2017-02-04 17:42:28 +02:00
Jaquee
8060307c62 wizard: fix focus 2017-02-04 15:41:10 +01:00
pigeons
7ab3373335 use gmake on bsd in build.sh 2017-02-02 13:11:33 -08:00
Jaquee
0b41fbc858 Don't close/reopen when changing daemon
requires #1655
2017-01-31 11:17:56 +01:00
Jaquee
2586404339 sync progress improvements 2017-01-31 11:17:48 +01:00
Jaquee
eb909e1ae7 async connectionStatus and init 2017-01-31 10:39:03 +01:00
Jaquee
cb3281dee8 WalletManager: fix possible race 2017-01-31 10:39:00 +01:00
Jaquee
9dbbd4c9bc WalletManager: check connection before isMining() 2017-01-31 10:39:00 +01:00
MoroccanMalinois
93d2eb5e1a add qrcode scanner 2017-01-31 04:36:08 +00:00
xmr-eric
faeead242c Better placeholders 2017-01-30 18:45:16 -05:00
xmr-eric
4e2e262f6a Main.qml: Ringsize equals mixin +1 2017-01-30 18:28:56 -05:00
xmr-eric
f1327ace32 Ringsize equals mixin +1 2017-01-30 18:27:55 -05:00
luigi1111
43d5bd3e2d Merge pull request #437
Restore wallet from keys (Jaqueeee)
2017-01-30 17:11:30 -06:00
luigi1111
be564921d8 Merge pull request 441
f4e01e5 Fix git username in build script (Jaqueeee)
2017-01-30 16:57:06 -06:00
luigi1111
ef9bf72b52 Merge pull request 438
7b94a47 detect freebsd, build for armv7, configure general build for unkown platforms (danrmiller)
2017-01-30 16:33:59 -06:00
luigi1111
e0e2b40682 Merge branch 'path' of https://github.com/danrmiller/monero-core into danrmiller-path 2017-01-30 16:33:49 -06:00
Jaquee
f4e01e5756 fix git username in build script 2017-01-30 23:33:04 +01:00
luigi1111
501560940b Merge pull request #435
a521566 Shorter mining description for compact view (xmr-eric)
2017-01-30 16:23:17 -06:00
luigi1111
a80df427e7 Merge branch 'patch-4' of https://github.com/xmr-eric/monero-core into xmr-eric-patch-4 2017-01-30 16:23:05 -06:00
luigi1111
3cbad7350b Merge pull request #431
1acd4a7 Simplified "OR ALL" button to "ALL" (xmr-eric)
2017-01-30 16:21:48 -06:00
luigi1111
58bcc3640c Merge branch 'patch-1' of https://github.com/xmr-eric/monero-core into xmr-eric-patch-1 2017-01-30 16:21:33 -06:00
Jaquee
04ff16ddb2 restore from keys: show error in popup 2017-01-30 23:20:47 +01:00
Jaquee
c5c2a40ef5 Wizard: restore from keys 2017-01-30 23:20:47 +01:00
Jaquee
b3232dc26f WalletManager: restore from keys 2017-01-30 23:20:43 +01:00
luigi1111
26be7fbd46 Merge pull request #432
4fb4bde Payment Description into placeholder (xmr-eric)
2017-01-30 16:19:47 -06:00
luigi1111
0e70e63e0a Merge branch 'patch-2' of https://github.com/xmr-eric/monero-core into xmr-eric-patch-2 2017-01-30 16:19:24 -06:00
luigi1111
1ef1a140b7 Merge pull request #439
a81a071 fix osx build (Jaqueeee)
2017-01-30 16:05:43 -06:00
Jaquee
a81a071d2d fix osx build 2017-01-29 19:31:04 +01:00
pigeons
7b94a47350 detect freebsd, build for armv7, configure general build for unknown platforms 2017-01-27 09:10:08 -08:00
Jaquee
bded77a22b lineEdit: add textUpdated signal 2017-01-26 21:58:48 +01:00
Jaquee
de14886376 fix daemon console error 2017-01-26 21:58:41 +01:00
xmr-eric
9425b77030 Payment ID Placeholder: 64 characters only 2017-01-23 18:35:44 -05:00
xmr-eric
a52156627d Mining.qml: Simplified mining description 2017-01-23 14:48:05 -05:00
xmr-eric
ce87a1c4db Added AddressBook.qml placeholders 2017-01-23 14:25:30 -05:00
xmr-eric
4fb4bde34b Moved Payment Description into placeholder 2017-01-23 13:58:31 -05:00
xmr-eric
1acd4a7ac8 Simplified send-all button 2017-01-23 13:37:23 -05:00
xmr-eric
2d12a3cf3d Main.qml: Changed mixin to ring size 2017-01-23 13:20:15 -05:00
xmr-eric
16f5889a15 Transfer.qml: Changed mixin to ring size 2017-01-23 13:19:31 -05:00
Jaquee
c51a28f206 fix advanced hotkey + menu separators 2017-01-23 14:22:17 +01:00
David
58147a24cf Minor spelling corrections
The biggest one was a missing word.
2017-01-23 14:13:31 +01:00
Riccardo Spagni
cf95742433 Merge pull request #428
8df270c add version.js to .gitignore (MoroccanMalinois)
2017-01-23 08:05:38 -05:00
Riccardo Spagni
d4a40499ac Merge pull request #427
1d7a1f6 save qrcode to file (MoroccanMalinois)
2017-01-23 08:05:22 -05:00
Riccardo Spagni
ecd6c7a0ae Merge pull request #425
ef1d7f9 send custom commands to daemon + status button requires #1618 (Jaquee)
2e925b5 Update submodule + fix epee link (Jaquee)
39f9d5a pin submodule to monero head (Jaquee)
2017-01-23 08:04:19 -05:00
Riccardo Spagni
4cc838f1ff Merge pull request #424
8482481 pin submodule to monero head (Jaquee)
61f4db6 Update submodule + fix epee link (Jaquee)
2017-01-23 08:03:40 -05:00
MoroccanMalinois
8df270cc4b add version.js to .gitignore 2017-01-23 04:57:09 +00:00
MoroccanMalinois
1d7a1f6d53 save qrcode to file 2017-01-23 04:15:49 +00:00
Jaquee
ef1d7f92f7 send custom commands to daemon
+ status button
requires #1618
2017-01-22 23:16:46 +01:00
Jaquee
2e925b530b Update submodule + fix epee link 2017-01-22 23:13:59 +01:00
Jaquee
39f9d5a116 pin submodule to monero head 2017-01-22 23:13:58 +01:00
Jaquee
8482481478 pin submodule to monero head 2017-01-22 21:13:13 +01:00
Jaquee
61f4db61ec Update submodule + fix epee link 2017-01-22 21:00:34 +01:00
Riccardo Spagni
6d73fba14c Merge pull request #412
6a19330 Pull required monero PR's automatically (Jaquee)
2017-01-22 12:18:29 -05:00
Riccardo Spagni
955d13ef0a Merge pull request #420
4eedef0 allow QT location to be set with an environment variable (pigeons)
2017-01-22 12:17:57 -05:00
Riccardo Spagni
2d907c02f0 Merge pull request #416
adaa8cb Wizard: fix recover bug (Jaquee)
2017-01-22 12:16:13 -05:00
Riccardo Spagni
160e5c480a Merge pull request #413
fb8d9bd Settings: allow setting log categories (moneromooo.monero)
ea8bc5b LineEdit: forward editingFinished signal (moneromooo.monero)
d4b3834 Build against monero with new logging system (moneromooo.monero)
2017-01-22 12:15:55 -05:00
Riccardo Spagni
32a81517d6 Merge pull request #411
7f8d4ac exit script with appropriate status if these commands fail (pigeons)
2017-01-22 11:56:06 -05:00
Riccardo Spagni
e7b33347e7 Merge pull request #409
b538baa Added Dutch translation (keesieboy)
2017-01-22 11:55:46 -05:00
Riccardo Spagni
d8ac731dd2 Merge pull request #407
e0be6d4 Clearer results for Verify Payment tool (xmr-eric)
2017-01-22 11:55:19 -05:00
Riccardo Spagni
05e2472d93 Merge pull request #405
0c0de90 LeftPanel.qml: Advanced bullet color to #FFD781 (xmr-eric)
2017-01-22 11:54:57 -05:00
Riccardo Spagni
4f44407187 Merge pull request #404
fdf0652 PrivacyLevelSmall.qml: Medium mixin color- AAFFBB (xmr-eric)
5981e95 PrivacyLevel.qml: Medium mixin color #AAFFBB (xmr-eric)
2017-01-22 11:54:39 -05:00
Riccardo Spagni
2c69d3b726 Merge pull request #403
4a2266b TickDelegate.qml: Changed LOW to NORMAL (xmr-eric)
2017-01-22 11:54:15 -05:00
pigeons
4eedef048d allow QT location to be set with an environment variable
variable for libQt5XmlPatterns path

QTXML_DIR is same relative path on some systems, use that as default

use utils.sh for platform default paths

fix dumb copypasta
2017-01-19 11:14:55 -08:00
Jaquee
adaa8cb806 Wizard: fix recover bug 2017-01-17 22:38:38 +01:00
Jaquee
6a19330e55 Pull required monero PR's automatically 2017-01-17 21:11:31 +01:00
moneromooo.monero
fb8d9bd5dc Settings: allow setting log categories
requires #1589
2017-01-16 23:14:05 +00:00
moneromooo.monero
ea8bc5b56d LineEdit: forward editingFinished signal 2017-01-16 21:56:15 +00:00
moneromooo.monero
d4b3834bce Build against monero with new logging system
Oh, and screw you, cmake.
2017-01-16 20:57:00 +00:00
pigeons
7f8d4ac3d2 exit script with appropriate status if these commands fail 2017-01-16 09:37:12 -08:00
Riccardo Spagni
de63e93024 Merge pull request #410
977f512 check if version.h exists (Jaquee)
7f9cc73 Build libwallet if new version exists (Jaquee)
e08871a Update monero submodule to 16b8b66 (Jaquee)
2017-01-16 10:13:47 -05:00
Jaquee
977f5125e6 check if version.h exists 2017-01-16 14:17:30 +01:00
Jaquee
7f9cc73485 Build libwallet if new version exists 2017-01-16 14:14:12 +01:00
Jaquee
e08871a77e Update monero submodule to 16b8b66 2017-01-16 12:34:34 +01:00
Riccardo Spagni
98c3d6897d Merge pull request #402
20d3c30 Simpler text on Miner page (xmr-eric)
2017-01-15 15:00:57 -05:00
Riccardo Spagni
98ca4f1a70 Merge pull request #398
ae5c21e export/import key images when cold signing (Jaquee)
24ccd27 Add rescan spent button (Jaquee)
15c79df GUI cold signing (Jaquee)
fd98395 view only wallets (Jaquee)
8f56e98 save wallet name in appwindow (Jaquee)
842e4df adjust button size dynamically (Jaquee)
2017-01-15 14:58:47 -05:00
keesieboy
b538baa8d8 Added Dutch translation 2017-01-15 18:32:49 +01:00
Jaquee
ae5c21ef17 export/import key images when cold signing 2017-01-15 12:32:45 +01:00
Jaquee
24ccd27d79 Add rescan spent button 2017-01-15 12:32:39 +01:00
Jaquee
15c79df378 GUI cold signing 2017-01-15 12:32:31 +01:00
Jaquee
fd983955b4 view only wallets
wizard: fix dots on pw page

wizard: fix focus on pw field

viewOnly: added success message
2017-01-15 12:32:25 +01:00
Jaquee
8f56e98397 save wallet name in appwindow 2017-01-15 12:32:14 +01:00
Jaquee
842e4df223 adjust button size dynamically 2017-01-15 12:32:06 +01:00
xmr-eric
e0be6d45c5 Clearer results for Verify Payment tool 2017-01-14 22:52:04 -05:00
xmr-eric
0c0de906c2 LeftPanel.qml: Advanced bullet color to #FFD781 2017-01-14 17:01:47 -05:00
xmr-eric
fdf0652e37 PrivacyLevelSmall.qml: Medium mixin color- AAFFBB 2017-01-14 16:36:50 -05:00
xmr-eric
5981e9537b PrivacyLevel.qml: Medium mixin color #AAFFBB 2017-01-14 16:36:03 -05:00
xmr-eric
4a2266b295 TickDelegate.qml: Changed LOW to NORMAL 2017-01-14 13:31:25 -05:00
xmr-eric
20d3c301e7 Simpler text on Miner page 2017-01-14 13:04:00 -05:00
Riccardo Spagni
7cbd61dae2 Merge pull request #400
a760672 change monero build check (Jaquee)
a8f3021 add monero as git submodule (Jaquee)
2017-01-14 10:44:55 -05:00
Riccardo Spagni
e8a47e322d Merge pull request #396
6034eaf Add parse_uri to libwalletqt (MoroccanMalinois)
2017-01-14 10:42:26 -05:00
Riccardo Spagni
b5ade0d9d1 Merge pull request #368
94e8f3a Add mining screen (moneromooo.monero)
1cd7dd6 StandardDropdown: fix for empty model (moneromooo.monero)
2017-01-14 10:41:13 -05:00
Riccardo Spagni
a1c5e7fed2 Merge pull request #397
ad5115a Add estimated time countdown for locked balance (Jaquee)
205bfcd History: Show num of confirmations + unconfirmed payments (Jaquee)
2017-01-14 10:40:22 -05:00
Jaquee
a76067296e change monero build check 2017-01-14 15:48:20 +01:00
Jaquee
a8f30212d4 add monero as git submodule
update monero submodule to d98db48
2017-01-14 15:35:35 +01:00
Jaquee
ad5115ac3c Add estimated time countdown for locked balance 2017-01-14 00:45:15 +01:00
Jaquee
205bfcdd7b History: Show num of confirmations + unconfirmed payments
history: refresh on new block
2017-01-14 00:45:09 +01:00
MoroccanMalinois
6034eaffc8 Add parse_uri to libwalletqt 2017-01-11 03:18:13 +00:00
Riccardo Spagni
593839a374 Merge pull request #391
8490c69 fix loglevel runtime error (Jaquee)
2017-01-10 08:13:05 -05:00
Jaquee
8490c69692 fix loglevel runtime error 2017-01-09 13:45:00 +01:00
Riccardo Spagni
a8e90069d6 Merge pull request #388
dad9c82 Receive.qml: PaymentID above Integrated address (xmr-eric)
2017-01-08 17:00:19 -08:00
Riccardo Spagni
e286bd1422 Merge pull request #384
6ce83c5 Added Finnish translation (moimoij)
ab92761 Add files via upload (moimoij)
2017-01-08 16:59:10 -08:00
Riccardo Spagni
6437723772 Merge pull request #383
ba8decc wizard: Ensure temporary wallet files are deleted (Jaquee)
2017-01-08 16:58:39 -08:00
Riccardo Spagni
1532c5638f Merge pull request #382
427d9e2 wizard: store settings before opening from file (Jaquee)
2017-01-08 16:57:59 -08:00
Riccardo Spagni
ae537b6764 Merge pull request #380
bb303d0 remove double menu separators (Jaquee)
2017-01-08 16:57:31 -08:00
Riccardo Spagni
1ced5e34b6 Merge pull request #377
bd07a99 history: fix amount/fee overlap on large amounts (Jaquee)
2017-01-08 16:57:09 -08:00
Riccardo Spagni
3badb12ea3 Merge pull request #376
f012e4d history: show pending on top (Jaquee)
2017-01-08 16:56:51 -08:00
Riccardo Spagni
24170f00cc Merge pull request #375
192bfc7 Add "(syncing)" after balance when syncing (moneromooo.monero)
2017-01-08 16:56:17 -08:00
Riccardo Spagni
b3424f73a8 Merge pull request #374
f2aefee settings: log level selector (Jaquee)
2017-01-08 16:55:04 -08:00
Riccardo Spagni
f3e20e746e Merge pull request #373
a526619 Dynamically adjust balance fontsize (Jaquee)
2017-01-08 16:54:45 -08:00
Riccardo Spagni
5c1bd85204 Merge pull request #371
932d5be consistent layout seed textarea (Jaquee)
2017-01-08 16:54:29 -08:00
Riccardo Spagni
3c6c65e25e Merge pull request #370
8445391 add libunwind for android (MoroccanMalinois)
2ce0024 Android build (MoroccanMalinois)
2017-01-08 16:54:13 -08:00
Riccardo Spagni
ee9888d9b6 Merge pull request #366
10ac65f WizardMemoTextInput: Better use of emphasis (xmr-eric)
4406d4b WizardPassword: Better emphasis and a word change (xmr-eric)
2017-01-08 16:51:08 -08:00
Riccardo Spagni
b02751344a Merge pull request #365
c2a57f7 Transfer: print mixin when moving privacy level widget around (moneromooo.monero)
2017-01-08 16:50:51 -08:00
Riccardo Spagni
0cb9747547 Merge pull request #362
fdbd119 Create monero-core_br.ts (moneroj)
2017-01-08 16:50:41 -08:00
Riccardo Spagni
145d753b2c Merge pull request #361
80f7b1f add traditional Chinese translation (Lafudoci)
2017-01-08 16:50:31 -08:00
Riccardo Spagni
8f95e95b21 Merge pull request #359
1c58997 WizardPasswordInput: update password strength on paste too (moneromooo.monero)
d831395 WizardPassword: clamp displayed password strength to widget max (moneromooo.monero)
2017-01-08 16:50:10 -08:00
Riccardo Spagni
e482135ded Merge pull request #357
eff31f0 History: print address book description if available (moneromooo.monero)
2017-01-08 16:49:51 -08:00
Riccardo Spagni
09d252d43b Merge pull request #351
119832a Reduce the number of "balls" in the wizard to be coherent with the hidden steps (3 steps instead of 4). Color green for all. (Clement)
2017-01-08 16:49:15 -08:00
xmr-eric
dad9c82166 Receive.qml: PaymentID above Integrated address 2017-01-07 14:20:40 -05:00
moimoij
6ce83c5ec2 Added Finnish translation
Made some more-or-less silly choices with translations. I'd appreciate it if another Finnish speaker could go through this.
2017-01-04 07:05:53 +02:00
Jaquee
ba8decca3f wizard: Ensure temporary wallet files are deleted 2017-01-03 22:45:41 +01:00
Jaquee
427d9e2645 wizard: store settings before opening from file 2017-01-02 18:45:10 +01:00
MoroccanMalinois
84453912b1 add libunwind for android 2017-01-02 16:34:35 +00:00
moimoij
ab927615d8 Add files via upload 2017-01-02 16:40:16 +02:00
Jaquee
bb303d0063 remove double menu separators 2017-01-01 16:56:39 +01:00
moneromooo.monero
eff31f07d9 History: print address book description if available 2017-01-01 13:47:24 +00:00
MoroccanMalinois
2ce0024a10 Android build 2017-01-01 05:55:49 +01:00
Jaquee
bd07a990fb history: fix amount/fee overlap on large amounts 2016-12-31 15:30:25 +01:00
Jaquee
f012e4d968 history: show pending on top 2016-12-31 14:56:08 +01:00
moneromooo.monero
192bfc70b0 Add "(syncing)" after balance when syncing
Should cut down on people wondering why their balance is wrong
2016-12-31 13:47:40 +00:00
Jaquee
f2aefeebb3 settings: log level selector 2016-12-31 11:56:08 +01:00
Jaquee
a526619f4b Dynamically adjust balance fontsize 2016-12-31 11:22:23 +01:00
moneromooo.monero
94e8f3ac4c Add mining screen
We want to make it easy for people to mine
2016-12-30 23:49:12 +00:00
Jaquee
932d5bee47 consistent layout seed textarea 2016-12-30 19:51:06 +01:00
moneromooo.monero
1cd7dd622f StandardDropdown: fix for empty model 2016-12-30 10:10:54 +00:00
xmr-eric
10ac65ffb1 WizardMemoTextInput: Better use of emphasis 2016-12-27 18:02:31 -05:00
xmr-eric
4406d4bbaa WizardPassword: Better emphasis and a word change 2016-12-27 18:01:22 -05:00
moneromooo.monero
c2a57f704b Transfer: print mixin when moving privacy level widget around 2016-12-27 20:53:17 +00:00
moneroj
fdbd119445 Create monero-core_br.ts
add pt_BR translation
2016-12-27 17:54:51 +09:00
Lafudoci
80f7b1f96e add traditional Chinese translation 2016-12-26 13:01:02 +08:00
moneromooo.monero
1c5899731c WizardPasswordInput: update password strength on paste too 2016-12-25 22:59:19 +00:00
moneromooo.monero
d831395013 WizardPassword: clamp displayed password strength to widget max 2016-12-25 22:59:13 +00:00
Clement
119832a55b Reduce the number of "balls" in the wizard to be coherent with the hidden steps (3 steps instead of 4). Color green for all. 2016-12-23 22:19:11 +01:00
Riccardo Spagni
d8f9e7360f Merge pull request #336
f45099b add qmake rpath for linux build (Jaquee)
2016-12-22 22:43:53 +02:00
Riccardo Spagni
3b1ad0be27 Merge pull request #332
7573f37 linux build instructions (Jaqueeee)
2016-12-22 22:43:01 +02:00
Riccardo Spagni
05434a994f Merge pull request #330
2eebe67 make static build optional on linux/mac (Jaquee)
2016-12-22 22:42:45 +02:00
Jaquee
f45099b398 add qmake rpath for linux build 2016-12-22 18:23:25 +01:00
Jaqueeee
7573f370b3 linux build instructions 2016-12-22 17:41:03 +01:00
Jaquee
2eebe67005 make static build optional on linux/mac 2016-12-22 10:10:03 +01:00
123 changed files with 34305 additions and 7311 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,5 @@
*.user
*.user.*
translations/*.qm
build
build
version.js

4
.gitmodules vendored Normal file
View File

@@ -0,0 +1,4 @@
[submodule "monero"]
path = monero
url = https://github.com/monero-project/monero
ignore = dirty

View File

@@ -90,7 +90,6 @@ Rectangle {
height: 20
font.family: "Arial"
font.pixelSize: 12
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignBottom
@@ -104,7 +103,6 @@ Rectangle {
height: 20
font.family: "Arial"
font.pixelSize: 18
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignBottom
@@ -128,7 +126,6 @@ Rectangle {
height: 20
font.family: "Arial"
font.pixelSize: 12
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignBottom
@@ -142,7 +139,6 @@ Rectangle {
height: 20
font.family: "Arial"
font.pixelSize: 14
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignBottom

View File

@@ -35,9 +35,11 @@ Rectangle {
id: panel
property alias unlockedBalanceText: unlockedBalanceText.text
property alias balanceLabelText: balanceLabel.text
property alias balanceText: balanceText.text
property alias networkStatus : networkStatus
property alias progressBar : progressBar
property alias minutesToUnlockTxt: unlockedBalanceLabel.text
signal dashboardClicked()
signal historyClicked()
@@ -60,6 +62,7 @@ Rectangle {
else if(pos === "TxKey") menuColumn.previousButton = txkeyButton
else if(pos === "Sign") menuColumn.previousButton = signButton
else if(pos === "Settings") menuColumn.previousButton = settingsButton
else if(pos === "Advanced") menuColumn.previousButton = advancedButton
menuColumn.previousButton.checked = true
}
@@ -73,7 +76,7 @@ Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 40
anchors.topMargin: (persistentSettings.customDecorations)? 66 : 36
height: logo.implicitHeight
Image {
@@ -83,6 +86,18 @@ Rectangle {
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
Image {
anchors.left: parent.left
@@ -105,10 +120,11 @@ Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: logoItem.bottom
anchors.topMargin: 30
anchors.topMargin: 26
spacing: 5
Label {
id: balanceLabel
text: qsTr("Balance") + translationManager.emptyString
anchors.left: parent.left
anchors.leftMargin: 50
@@ -131,9 +147,17 @@ Rectangle {
id: balanceText
anchors.verticalCenter: parent.verticalCenter
font.family: "Arial"
font.pixelSize: 26
color: "#000000"
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,6 +168,7 @@ Rectangle {
}
Label {
id: unlockedBalanceLabel
text: qsTr("Unlocked balance") + translationManager.emptyString
anchors.left: parent.left
anchors.leftMargin: 50
@@ -155,9 +180,17 @@ Rectangle {
anchors.left: parent.left
anchors.leftMargin: 50
font.family: "Arial"
font.pixelSize: 18
color: "#000000"
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;
}
}
}
@@ -183,7 +216,7 @@ Rectangle {
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.top: column1.bottom
anchors.topMargin: 50
anchors.topMargin: 25
color: "#1C1C1C"
Column {
@@ -239,6 +272,7 @@ Rectangle {
}
Rectangle {
visible: transferButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
@@ -264,6 +298,7 @@ Rectangle {
}
Rectangle {
visible: addressBookButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
@@ -286,6 +321,7 @@ Rectangle {
}
}
Rectangle {
visible: receiveButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
@@ -309,6 +345,7 @@ Rectangle {
}
}
Rectangle {
visible: historyButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
@@ -316,7 +353,29 @@ Rectangle {
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 {
id: miningButton
anchors.left: parent.left
@@ -324,6 +383,7 @@ Rectangle {
text: qsTr("Mining") + translationManager.emptyString
symbol: qsTr("M") + translationManager.emptyString
dotColor: "#FFD781"
under: advancedButton
onClicked: {
parent.previousButton.checked = false
parent.previousButton = miningButton
@@ -332,34 +392,13 @@ Rectangle {
}
Rectangle {
visible: miningButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
color: miningButton.checked || settingsButton.checked ? "#1C1C1C" : "#505050"
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 ---------------
MenuButton {
id: txkeyButton
@@ -367,7 +406,7 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Check payment") + translationManager.emptyString
symbol: qsTr("K") + translationManager.emptyString
dotColor: "#AAFFBB"
dotColor: "#FFD781"
under: advancedButton
onClicked: {
parent.previousButton.checked = false
@@ -376,6 +415,7 @@ Rectangle {
}
}
Rectangle {
visible: txkeyButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
@@ -390,7 +430,7 @@ Rectangle {
anchors.right: parent.right
text: qsTr("Sign/verify") + translationManager.emptyString
symbol: qsTr("I") + translationManager.emptyString
dotColor: "#AAFFBB"
dotColor: "#FFD781"
under: advancedButton
onClicked: {
parent.previousButton.checked = false
@@ -399,6 +439,7 @@ Rectangle {
}
}
Rectangle {
visible: signButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16

14
MainApp.cpp Normal file
View 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
View 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

View File

@@ -42,7 +42,9 @@ Rectangle {
property Item currentView
property Item previousView
property bool basicMode : false
property string balanceLabelText: qsTr("Balance") + translationManager.emptyString
property string balanceText
property string unlockedBalanceLabelText: qsTr("Unlocked Balance") + translationManager.emptyString
property string unlockedBalanceText
property Transfer transferView: Transfer { }
@@ -51,6 +53,7 @@ Rectangle {
property History historyView: History { }
property Sign signView: Sign { }
property Settings settingsView: Settings { }
property Mining miningView: Mining { }
property AddressBook addressBookView: AddressBook { }
@@ -143,7 +146,7 @@ Rectangle {
PropertyChanges { target: root; currentView: settingsView }
}, State {
name: "Mining"
PropertyChanges { /*TODO*/ }
PropertyChanges { target: root; currentView: miningView }
}
]
@@ -198,17 +201,16 @@ Rectangle {
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: qsTr("Balance:")
text: root.balanceLabelText + ":"
}
Text {
@@ -217,7 +219,6 @@ Rectangle {
height: 20
font.family: "Arial"
font.pixelSize: 18
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignBottom
@@ -237,16 +238,16 @@ Rectangle {
}
Text {
id: availableBalanceLabel
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: root.unlockedBalanceLabelText + ":"
}
Text {
@@ -255,7 +256,6 @@ Rectangle {
height: 20
font.family: "Arial"
font.pixelSize: 14
font.letterSpacing: -1
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignBottom

View File

@@ -1,4 +1,6 @@
Copyright (c) 2014-2016, The Monero Project
# Monero GUI
Copyright (c) 2014-2017, The Monero Project
## Development Resources
@@ -62,7 +64,7 @@ Packaging for your favorite distribution would be a welcome contribution!
### 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 and Linux Mint 18 "Sarah" - Cinnamon x64)
1. Install Monero dependencies.
@@ -83,31 +85,29 @@ Packaging for your favorite distribution would be a welcome contribution!
5. Install the GUI dependencies.
- For Ubuntu 16.04 i386
- For Ubuntu 16.04 x86
`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`
- 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`
- Optional : To build the flag `WITH_SCANNER`
`sudo apt install qtmultimedia5-dev qml-module-qtmultimedia libzbar-dev`
6. Build the GUI.
`qmake`
`./build.sh`
`make`
7. Run the GUI client.
7. Before running the GUI, it's recommended that you have the Monero daemon running in the background.
`./monerod`
8. Run the GUI client.
`./release/bin/monero-core`
`./build/release/bin/monero-wallet-gui`
### On OS X:
@@ -115,28 +115,38 @@ Packaging for your favorite distribution would be a welcome contribution!
2. Install [homebrew](http://brew.sh/)
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`
`brew install qt5` (or download QT 5.8+ from [qt.io](https://www.qt.io/download-open-source/))
If you have an older version of Qt installed via homebrew, you can force it to use 5.x like so:
`brew link --force --overwrite qt5`
4. Install latest Qt using official installer from [qt.io](https://www.qt.io/download-open-source/) (homebrew version might be outdated).
5. Add Qt bin dir to your path:
5. Add Qt bin dir to your path (check first if directory exists; 5.8 is the current version)
`export PATH=$PATH:$HOME/Qt/5.7/clang_64/bin`
`export PATH=$PATH:$HOME/Qt/5.8/clang_64/bin`
where ```Qt``` is the folder you selected to install Qt.
5. Add Qt bin dir to your path. Example:
`export PATH=$PATH:/usr/local/opt/qt5/bin`
make sure this is where Qt 5.x is installed on **your** system eg `$HOME/Qt/5.8/clang_64/bin` if you downloaded from qt.io.
6. 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`
7. Go into the repository.
`cd monero-core`
`cd monero-core`
8. Build libwallet
@@ -164,8 +174,13 @@ More info: http://stackoverflow.com/a/35098040/1683164
### On Windows:
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)**
```
pacman -S mingw-w64-i686-toolchain make mingw-w64-i686-cmake mingw-w64-i686-boost
```
3. Install git into msys2 environment:
@@ -179,35 +194,35 @@ More info: http://stackoverflow.com/a/35098040/1683164
- Tools > MinGW 5.3.0
- continue with installation
5. Open ```mingw``` shell:
5. Open ```MinGW-w64 Win32 Shell``` shell:
```%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
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
```
7. Build libwallet:
8. Build the GUI:
```
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:
- 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```
The resulting executable can be found in ```.\release\bin```

View File

@@ -1,8 +1,44 @@
#!/bin/bash
BUILD_TYPE=$1
source ./utils.sh
platform=$(get_platform)
# default build type
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
@@ -12,27 +48,22 @@ ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
MONERO_DIR=monero
MONEROD_EXEC=monerod
# Build libwallet if monero folder doesnt exist
if [ ! -d $MONERO_DIR ]; then
$SHELL get_libwallet_api.sh $BUILD_TYPE
MAKE='make'
if [[ $platform == *bsd* ]]; then
MAKE='gmake'
fi
# build libwallet
$SHELL get_libwallet_api.sh $BUILD_TYPE
# build zxcvbn
make -C src/zxcvbn-c
$MAKE -C src/zxcvbn-c || exit
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=$(get_platform)
if [ "$platform" == "linux32" ] || [ "$platform" == "linux64" ]; then
if [ "$ANDROID" != true ] && ([ "$platform" == "linux32" ] || [ "$platform" == "linux64" ]); then
distro=$(lsb_release -is)
if [ "$distro" == "Ubuntu" ]; then
CONFIG="$CONFIG libunwind_off"
@@ -54,11 +85,11 @@ popd
echo "var GUI_MONERO_VERSION = \"$VERSIONTAG\"" >> version.js
cd build
qmake ../monero-wallet-gui.pro "$CONFIG"
make
qmake ../monero-wallet-gui.pro "$CONFIG" || exit
$MAKE || exit
# Copy monerod to bin folder
if [ "$platform" != "mingw32" ]; then
if [ "$platform" != "mingw32" ] && [ "$ANDROID" != true ]; then
cp ../$MONERO_DIR/bin/$MONEROD_EXEC $BIN_PATH
fi

View File

@@ -87,7 +87,6 @@ ListView {
anchors.rightMargin: 40
font.family: "Arial"
font.pixelSize: 16
font.letterSpacing: -1
color: "#545454"
text: address
}
@@ -101,7 +100,6 @@ ListView {
width: 139
font.family: "Arial"
font.pixelSize: 12
font.letterSpacing: -1
color: "#535353"
text: qsTr("Payment ID:") + translationManager.emptyString
}
@@ -117,7 +115,6 @@ ListView {
font.family: "Arial"
font.pixelSize: 13
font.letterSpacing: -1
color: "#545454"
text: paymentId
}

View File

@@ -27,6 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.0
import QtQuick.Layouts 1.1
Item {
id: checkBox
@@ -40,6 +41,7 @@ Item {
signal clicked()
height: 25
width: label.x + label.width
Layout.minimumWidth: label.x + label.contentWidth
clip: true
Rectangle {
@@ -74,7 +76,6 @@ Item {
anchors.leftMargin: 25 + 12
font.family: "Arial"
font.pixelSize: checkBox.fontSize
font.letterSpacing: -1
color: "#525252"
}

View File

@@ -0,0 +1,147 @@
// 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
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);
// }
// }
}
}
}

View File

@@ -39,12 +39,14 @@ Window {
id: root
modality: Qt.ApplicationModal
flags: Qt.Window | Qt.FramelessWindowHint
property int countDown: 5;
signal rejected()
signal started();
function open() {
show()
countDown = 5;
timer.start();
}
// TODO: implement without hardcoding sizes
@@ -61,15 +63,29 @@ Window {
//anchors {fill: parent; margins: 16 }
Layout.alignment: Qt.AlignHCenter
Label {
text: qsTr("Daemon doesn't appear to be running")
Timer {
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.columnSpan: 2
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 24
font.family: "Arial"
color: "#555555"
}
}
@@ -81,57 +97,39 @@ Window {
MoneroComponents.StandardButton {
id: okButton
width: 120
visible:false
fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Start daemon")
text: qsTr("Start daemon (%1)").arg(countDown)
KeyNavigation.tab: cancelButton
onClicked: {
timer.stop();
root.close()
appWindow.startDaemon(daemonFlags.text);
appWindow.startDaemon(persistentSettings.daemonFlags);
root.started()
}
}
MoneroComponents.StandardButton {
id: cancelButton
width: 120
fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Cancel")
text: qsTr("Use custom settings")
onClicked: {
timer.stop();
root.close()
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)")
}
}
}
}

View File

@@ -145,7 +145,6 @@ ListView {
Text {
font.family: "Arial"
font.pixelSize: 18
font.letterSpacing: -1
color: "#000000"
text: date
}
@@ -153,7 +152,6 @@ ListView {
Text {
font.family: "Arial"
font.pixelSize: 18
font.letterSpacing: -1
color: "#000000"
text: time
}
@@ -175,7 +173,6 @@ ListView {
Text {
font.family: "Arial"
font.pixelSize: 18
font.letterSpacing: -1
color: "#000000"
text: balance
}
@@ -208,7 +205,6 @@ ListView {
anchors.bottom: parent.bottom
font.family: "Arial"
font.pixelSize: 18
font.letterSpacing: -1
color: out ? "#FF4F41" : "#36B05B"
text: amount
}

View File

@@ -285,7 +285,6 @@ Item {
anchors.centerIn: parent
font.family: "Arial"
font.pixelSize: 12
font.letterSpacing: -1
font.bold: dayArea.pressed
text: styleData.date.getDate()
color: {
@@ -322,7 +321,6 @@ Item {
elide: Text.ElideRight
font.family: "Arial"
font.pixelSize: 9
font.letterSpacing: -1
color: "#535353"
text: {
var locale = Qt.locale()
@@ -339,7 +337,6 @@ Item {
anchors.centerIn: parent
font.family: "Arial"
font.pixelSize: 12
font.letterSpacing: -1
color: "#4A4646"
text: styleData.title
}

View File

@@ -28,6 +28,7 @@
import QtQuick 2.0
import moneroComponents.Clipboard 1.0
import moneroComponents.AddressBookModel 1.0
ListView {
@@ -36,6 +37,7 @@ ListView {
boundsBehavior: ListView.StopAtBounds
property var previousItem
property int rowSpacing: 12
property var addressBookModel: null
function buildTxDetailsString(tx_id, paymentId, tx_key,tx_note, destinations) {
var trStart = '<tr><td width="85" style="padding-top:5px"><b>',
@@ -52,6 +54,15 @@ ListView {
+ 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 {
@@ -188,7 +199,6 @@ ListView {
anchors.bottom: parent.bottom
font.family: "Arial"
font.pixelSize: 12
font.letterSpacing: -1
color: "#535353"
text: paymentId !== "" ? qsTr("Payment ID:") + translationManager.emptyString : ""
}
@@ -202,11 +212,24 @@ ListView {
//elide: Text.ElideRight
font.family: "Arial"
font.pixelSize:13
font.letterSpacing: -1
color: "#545454"
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 {
// block height row
@@ -224,7 +247,6 @@ ListView {
width: 86
font.family: "Arial"
font.pixelSize: 12
font.letterSpacing: -1
color: "#535353"
text: qsTr("BlockHeight:") + translationManager.emptyString
}
@@ -237,9 +259,18 @@ ListView {
//elide: Text.ElideRight
font.family: "Arial"
font.pixelSize: 13
font.letterSpacing: -1
color: "#545454"
text: blockHeight
color: (confirmations < 10)? "#FF6C3C" : "#545454"
text: {
if (!isPending)
if(confirmations < 10)
return blockHeight + " " + qsTr("(%1/10 confirmations)").arg(confirmations)
else
return blockHeight
if (!isOut)
return qsTr("UNCONFIRMED") + translationManager.emptyString
return qsTr("PENDING") + translationManager.emptyString
}
}
}
@@ -277,7 +308,6 @@ ListView {
Text {
font.family: "Arial"
font.pixelSize: 18
font.letterSpacing: -1
color: "#000000"
text: date
}
@@ -285,7 +315,6 @@ ListView {
Text {
font.family: "Arial"
font.pixelSize: 18
font.letterSpacing: -1
color: "#000000"
text: time
}
@@ -310,7 +339,6 @@ ListView {
Text {
font.family: "Arial"
font.pixelSize: 18
font.letterSpacing: -1
color: "#000000"
text: balance
}
@@ -320,7 +348,6 @@ ListView {
// -- "Amount column
Column {
anchors.top: parent.top
width: 148
Text {
anchors.left: parent.left
@@ -342,10 +369,10 @@ ListView {
}
Text {
id: amountText
anchors.bottom: parent.bottom
font.family: "Arial"
font.pixelSize: 18
font.letterSpacing: -1
color: isOut ? "#FF4F41" : "#36B05B"
text: displayAmount
}
@@ -371,7 +398,6 @@ ListView {
anchors.bottom: parent.bottom
font.family: "Arial"
font.pixelSize: 18
font.letterSpacing: -1
color: "#FF4F41"
text: fee
}

View File

@@ -29,14 +29,18 @@
import QtQuick 2.0
Item {
id: item
property alias placeholderText: input.placeholderText
property alias text: input.text
property alias validator: input.validator
property alias readOnly : input.readOnly
property alias cursorPosition: input.cursorPosition
property alias echoMode: input.echoMode
property int fontSize: 18
property bool error: false
signal editingFinished()
signal accepted();
signal textUpdated();
height: 37
@@ -67,5 +71,8 @@ Item {
anchors.leftMargin: 4
anchors.rightMargin: 30
font.pixelSize: parent.fontSize
onEditingFinished: item.editingFinished()
onAccepted: item.accepted();
onTextChanged: item.textUpdated()
}
}

View File

@@ -50,7 +50,7 @@ Rectangle {
color: checked ? "#FFFFFF" : "#1C1C1C"
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 {
yScale: button.present ? 1 : 0

View File

@@ -48,8 +48,11 @@ Row {
}
function getConnectionStatusString(status) {
if (status == Wallet.ConnectionStatus_Connected)
if (status == Wallet.ConnectionStatus_Connected) {
if(!appWindow.daemonSynced)
return qsTr("Synchronizing")
return qsTr("Connected")
}
if (status == Wallet.ConnectionStatus_WrongVersion)
return qsTr("Wrong version")
if (status == Wallet.ConnectionStatus_Disconnected)
@@ -79,7 +82,7 @@ Row {
font.family: "Arial"
font.pixelSize: 12
color: "#545454"
text: qsTr("Network status")
text: qsTr("Network status") + translationManager.emptyString
}
Text {

82
components/Notifier.qml Normal file
View File

@@ -0,0 +1,82 @@
// 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.message = message
item.active = true
hider.running = true
}
}

View File

@@ -52,13 +52,6 @@ Window {
show()
}
function usefulName(path) {
// arbitrary "short enough" limit
if (path.length < 32)
return path
return path.replace(/.*[\/\\]/, '').replace(/\.keys$/, '')
}
// TODO: implement without hardcoding sizes
width: 480
height: walletName ? 240 : 200
@@ -74,7 +67,7 @@ Window {
Layout.alignment: Qt.AlignHCenter
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.columnSpan: 2
Layout.fillWidth: true
@@ -107,12 +100,14 @@ Window {
}
}
Keys.onReturnPressed: {
root.accepted()
root.close()
root.accepted()
}
Keys.onEscapePressed: {
root.rejected()
root.close()
root.rejected()
}
@@ -149,7 +144,7 @@ Window {
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Cancel")
text: qsTr("Cancel") + translationManager.emptyString
KeyNavigation.tab: passwordInput
onClicked: {
root.close()

View File

@@ -64,7 +64,7 @@ Item {
color: {
if(item.fillLevel < 3) return "#FF6C3C"
if(item.fillLevel < 13) return "#FFE00A"
if(item.fillLevel < 13) return "#AAFFBB"
return "#36B25C"
}

View File

@@ -73,7 +73,7 @@ Item {
color: {
if(item.fillLevel < 5) return "#FF6C3C"
if(item.fillLevel < 13) return "#FFE00A"
if(item.fillLevel < 13) return "#AAFFBB"
return "#36B25C"
}
@@ -94,34 +94,28 @@ Item {
Text {
anchors.verticalCenter: parent.verticalCenter
font.family: "Arial"
font.pixelSize: 11
font.letterSpacing: -1
font.bold: true
font.pixelSize: 15
color: "#000000"
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 {
anchors.verticalCenter: parent.verticalCenter
font.family: "Arial"
font.pixelSize: 11
font.letterSpacing: -1
font.bold: true
font.pixelSize: 15
color: "#000000"
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 {
anchors.verticalCenter: parent.verticalCenter
font.family: "Arial"
font.pixelSize: 11
font.letterSpacing: -1
font.bold: true
font.pixelSize: 15
color: "#000000"
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 {

View File

@@ -61,7 +61,7 @@ Window {
id: messageTitle
text: "Please wait..."
font {
pointSize: 22
pixelSize: 22
}
horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
@@ -72,7 +72,7 @@ Window {
Text {
id: heightProgress
font {
pointSize: 18
pixelSize: 18
}
horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter

View File

@@ -37,12 +37,25 @@ Item {
visible: false
//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) {
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
progressText.text = qsTr("Synchronizing blocks %1/%2").arg(currentBlock.toFixed(0)).arg(targetBlock.toFixed(0));
item.visible = (currentWallet.connected !== Wallet.ConnectionStatus_Disconnected) && (currentBlock < targetBlock)
progressText.text = qsTr("Blocks remaining: %1").arg(remaining.toFixed(0));
progressBar.visible = currentBlock < targetBlock
}
}

View 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;
}
}
}

View File

@@ -100,7 +100,6 @@ Item {
font.family: "Arial"
font.pixelSize: 12
font.bold: true
font.letterSpacing: -1
color: "#4A4747"
text: "NAME"
}
@@ -195,7 +194,6 @@ Item {
anchors.rightMargin: 12
font.family: "Arial"
font.bold: true
font.letterSpacing: -1
font.pixelSize: 12
color: delegateArea.pressed || parent.isCurrent ? "#FFFFFF" : "#4A4646"
text: name

View File

@@ -27,6 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.0
import QtQuick.Layouts 1.1
Item {
id: button
@@ -41,6 +42,10 @@ Item {
property alias text: label.text
signal clicked()
// Dynamic label width
Layout.minimumWidth: (label.contentWidth > 80)? label.contentWidth + 20 : 100
Rectangle {
anchors.left: parent.left
@@ -78,13 +83,12 @@ Item {
anchors.left: parent.left
anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
font.family: "Arial"
font.bold: true
font.letterSpacing: -1
font.pixelSize: button.fontSize
color: parent.textColor
visible: parent.icon === ""
// font.capitalization : Font.Capitalize
}
Image {

View File

@@ -45,6 +45,9 @@ Window {
property alias cancelVisible: cancelButton.visible
property alias okVisible: okButton.visible
property alias textArea: dialogContent
property alias okText: okButton.text
property alias cancelText: cancelButton.text
property var icon
// same signals as Dialog has
@@ -98,6 +101,21 @@ Window {
spacing: 60
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 {
id: okButton
width: 120
@@ -114,21 +132,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()
}
}
}
}

View File

@@ -107,7 +107,7 @@ Item {
font.bold: true
font.pixelSize: 12
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 {
@@ -119,7 +119,7 @@ Item {
font.family: "Arial"
font.pixelSize: 12
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
Component.onCompleted: w = implicitWidth
@@ -193,6 +193,15 @@ Item {
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 stringAll: qsTr("All") + translationManager.emptyString
property string stringSent: qsTr("Sent") + translationManager.emptyString
property string stringReceived: qsTr("Received") + translationManager.emptyString
delegate: Rectangle {
anchors.left: parent.left
anchors.right: parent.right
@@ -210,7 +219,7 @@ Item {
font.bold: true
font.pixelSize: 12
color: "#FFFFFF"
text: column1
text: qsTr(column1) + translationManager.emptyString
}
Text {

View File

@@ -177,6 +177,13 @@ Item {
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 same destination</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 {
id: delegate
property bool containsMouse: index === mouseArea.currentIndex
@@ -211,7 +218,7 @@ Item {
onContainsMouseChanged: {
if(containsMouse) {
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
// if(appWindow.toolTip.height > 30)
// pos.y -= appWindow.toolTip.height - 30

View File

@@ -60,6 +60,13 @@ Rectangle {
Repeater {
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 {
id: delegate
property bool desc: false
@@ -81,7 +88,7 @@ Rectangle {
return "#FF4304"
return index === header.activeSortColumn || delegateArea.containsMouse ? "#FF6C3C" : "#4A4949"
}
text: columnName
text: qsTr(columnName) + translationManager.emptyString
}
MouseArea {

View File

@@ -52,9 +52,9 @@ Item {
font.pixelSize: 12
color: "#4A4949"
text: {
if(currentIndex === 0) return qsTr("LOW") + translationManager.emptyString
if(currentIndex === 3) return qsTr("MEDIUM") + translationManager.emptyString
if(currentIndex === 13) return qsTr("HIGH") + 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
return ""
}
}

View File

@@ -65,7 +65,6 @@ Window {
lineHeight: 0.7
font.family: "Arial"
font.pixelSize: 12
font.letterSpacing: -1
color: "#FFFFFF"
}
}

View File

@@ -41,39 +41,37 @@ Rectangle {
y: -height
property string title
property alias maximizeButtonVisible: maximizeButton.visible
z: 1
Text {
anchors.centerIn: parent
font.family: "Arial"
font.pixelSize: 15
font.letterSpacing: -1
color: "#FFFFFF"
text: titleBar.title
visible: customDecorations
}
Behavior on y {
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
}
Rectangle {
id: goToBasicVersionButton
property bool containsMouse: titleBar.mouseX >= x && titleBar.mouseX <= x + width
property bool checked: false
anchors.top: parent.top
anchors.left: parent.left
color: containsMouse || checked ? "#FFE00A" : "#000000"
color: basicMouseArea.containsMouse || checked ? "#FFE00A" : "#000000"
height: 30
width: height
Image {
anchors.centerIn: parent
rotation: parent.checked ? 180 : 0
source: parent.containsMouse || parent.checked ? "../images/goToBasicVersionHovered.png" :
source: parent.customDecorations || parent.checked ? "../images/goToBasicVersionHovered.png" :
"../images/gotoBasicVersion.png"
}
MouseArea {
id: basicMouseArea
hoverEnabled: true
anchors.fill: parent
onClicked: {
parent.checked = !parent.checked

View File

@@ -1,39 +1,121 @@
#!/bin/bash
MONERO_URL=https://github.com/monero-project/monero.git
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)
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $ROOT_DIR/utils.sh
INSTALL_DIR=$ROOT_DIR/wallet
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
git -C $MONERO_DIR fetch --tags
git -C $MONERO_DIR checkout v0.10.3.1
if [ ! -d $MONERO_DIR ]; then
git clone --depth=1 $MONERO_URL $MONERO_DIR --branch $MONERO_BRANCH --single-branch
# get monero core tag
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
cd $MONERO_DIR;
git checkout $MONERO_BRANCH
git pull;
source $MONERO_DIR/version.sh
# compare submodule version with latest build
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
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"
rm -fr $MONERO_DIR/build
#rm -fr $MONERO_DIR/build
rm -fr $MONERO_DIR/lib
rm -fr $MONERO_DIR/include
rm -fr $MONERO_DIR/bin
@@ -46,38 +128,84 @@ pushd $MONERO_DIR/build/release
platform=$(get_platform)
# default make executable
make_exec="make"
## OS X
if [ "$platform" == "darwin" ]; then
# Do something under Mac OS X platform
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
# Do something under GNU/Linux platform
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
# Do something under GNU/Linux platform
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
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
# Do something under Windows NT platform
echo "Configuring build for MINGW64.."
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
# Do something under Windows NT platform
echo "Configuring build for MINGW32.."
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"
else
echo "Unsupported platform: $platform"
popd
exit 1
echo "Unknown platform, configuring general build"
if [ "$STATIC" == true ]; then
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
# 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
pushd $MONERO_DIR/build/release/src/wallet
@@ -88,25 +216,24 @@ popd
# Build monerod
# 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
eval make -j$CPU_CORE_COUNT
eval make install -j$CPU_CORE_COUNT
eval make install -j$CPU_CORE_COUNT
popd
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
# since filename conflict (random.c.obj)
# for Linux, we use libunbound shipped with the system, so we don't need to build it
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
# 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
popd
popd

BIN
lang/flags/croatia.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
lang/flags/esperanto.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
lang/flags/finland.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
lang/flags/france.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
lang/flags/indonesia.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
lang/flags/japan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
lang/flags/netherlands.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
lang/flags/poland.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
lang/flags/spain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
lang/flags/taiwan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<languages>
<!--
@@ -12,13 +12,23 @@ List of available languages for your wallet's seed:
6 : Japanese
-->
<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 (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="Arabic (PS)" locale="ar_PS" wallet_language="English" flag="/lang/flags/palestine.png" qs="none"/>
<language display_name="Hindi" locale="hi_IN" wallet_language="English" flag="/lang/flags/india.png" qs="none"/>
<language display_name="Italian" locale="it_IT" wallet_language="Italian" flag="/lang/flags/italy.png" qs="none"/>
<language display_name="German" locale="de_DE" wallet_language="German" flag="/lang/flags/german.png" qs="none"/>
<language display_name="Mandarin" locale="zh_CN" wallet_language="English" flag="/lang/flags/china.png" qs="none"/>
<language display_name="Portuguese (BR)" locale="pt_BR" wallet_language="Portuguese" flag="/lang/flags/brazil.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="العربية (PS)" locale="ar_PS" wallet_language="English" flag="/lang/flags/palestine.png" qs="none"/> -->
<!-- <language display_name="Deutsch" locale="de_DE" wallet_language="German" flag="/lang/flags/german.png" qs="none"/> -->
<language display_name="Esperanto" locale="eo" wallet_language="English" flag="/lang/flags/esperanto.png" qs="none"/>
<!-- <language display_name="Español" locale="es_ES" wallet_language="Spanish" flag="/lang/flags/spain.png" qs="none"/> -->
<!-- <language display_name="Suomen kieli" locale="fi" wallet_language="English" flag="/lang/flags/finland.png" qs="none"/> -->
<language display_name="Français" locale="fr_FR" wallet_language="French" flag="/lang/flags/france.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="Italian" flag="/lang/flags/italy.png" qs="none"/>
<language display_name="日本語" locale="ja_JP" wallet_language="Japanese" flag="/lang/flags/japan.png" qs="none"/>
<language display_name="Nederlands" locale="nl_NL" wallet_language="Dutch" 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="Portuguese" flag="/lang/flags/brazil.png" qs="none"/>
<!-- <language display_name="русский язык" locale="ru_RU" wallet_language="Russian" flag="/lang/flags/russia.png" qs="none"/> -->
<language display_name="简体中文 (中国)" locale="zh-cn_CN" wallet_language="English" flag="/lang/flags/china.png" qs="none"/>
<language display_name="繁體中文 (台灣)" locale="zh-tw_CN" wallet_language="English" flag="/lang/flags/taiwan.png" qs="none"/>
</languages>

View File

@@ -9,14 +9,36 @@ GUI_EXEC=$2
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
EXCLUDE='libstdc++|libgcc_s.so|libc.so|libpthread'
cp -rv /usr/lib/x86_64-linux-gnu/qt5/qml $TARGET
cp -rv /usr/lib/x86_64-linux-gnu/qt5/plugins $TARGET
mkdir -p $TARGET/libs
ldd $TARGET/$GUI_EXEC | grep "=> /" | awk '{print $3}' | grep -Ev $EXCLUDE | xargs -I '{}' cp -v '{}' $TARGET/libs
ldd $TARGET/plugins/platforms/libqxcb.so| grep "=> /" | awk '{print $3}' | grep -Ev $EXCLUDE | xargs -I '{}' cp -v '{}' $TARGET/libs
cp -v /usr/lib/x86_64-linux-gnu/libQt5XmlPatterns.so.5 $TARGET/libs
INCLUDE='libunbound'
cp -rv $QT_DIR/qml $TARGET || exit
cp -rv $QT_DIR/plugins $TARGET || exit
mkdir -p $TARGET/libs || exit
#ldd $TARGET/$GUI_EXEC | grep "=> /" | awk '{print $3}' | grep $INCLUDE | xargs -I '{}' cp -v '{}' $TARGET/libs || exit
#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
cat > $TARGET/start-gui.sh <<EOL
@@ -26,3 +48,5 @@ export QT_PLUGIN_PATH=\`pwd\`/plugins
export QML2_IMPORT_PATH=\`pwd\`/qml
./$GUI_EXEC
EOL
chmod +x $TARGET/start-gui.sh

View File

@@ -40,19 +40,45 @@
#include "Wallet.h"
#include "QRCodeImageProvider.h"
#include "PendingTransaction.h"
#include "UnsignedTransaction.h"
#include "TranslationManager.h"
#include "TransactionInfo.h"
#include "TransactionHistory.h"
#include "model/TransactionHistoryModel.h"
#include "model/TransactionHistorySortFilterModel.h"
#include "daemon/DaemonManager.h"
#include "AddressBook.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[])
{
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";
@@ -72,6 +98,9 @@ int main(int argc, char *argv[])
qmlRegisterUncreatableType<PendingTransaction>("moneroComponents.PendingTransaction", 1, 0, "PendingTransaction",
"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",
"WalletManager can't be instantiated directly");
@@ -91,10 +120,10 @@ int main(int argc, char *argv[])
qmlRegisterUncreatableType<TransactionInfo>("moneroComponents.TransactionInfo", 1, 0, "TransactionInfo",
"TransactionHistory can't be instantiated directly");
#ifndef Q_OS_IOS
qmlRegisterUncreatableType<DaemonManager>("moneroComponents.DaemonManager", 1, 0, "DaemonManager",
"DaemonManager can't be instantiated directly");
#endif
qmlRegisterUncreatableType<AddressBookModel>("moneroComponents.AddressBookModel", 1, 0, "AddressBookModel",
"AddressBookModel can't be instantiated directly");
@@ -105,6 +134,10 @@ int main(int argc, char *argv[])
qRegisterMetaType<TransactionInfo::Direction>();
qRegisterMetaType<TransactionHistoryModel::TransactionInfoRole>();
#ifdef WITH_SCANNER
qmlRegisterType<QrCodeScanner>("moneroComponents.QRCodeScanner", 1, 0, "QRCodeScanner");
#endif
QQmlApplicationEngine engine;
OSCursor cursor;
@@ -118,9 +151,14 @@ int main(int argc, char *argv[])
engine.addImageProvider(QLatin1String("qrcode"), new QRCodeImageProvider());
const QStringList arguments = QCoreApplication::arguments();
engine.rootContext()->setContextProperty("mainApp", &app);
// Exclude daemon manager from IOS
#ifndef Q_OS_IOS
DaemonManager * daemonManager = DaemonManager::instance(&arguments);
QObject::connect(&app, SIGNAL(aboutToQuit()), daemonManager, SLOT(closing()));
engine.rootContext()->setContextProperty("daemonManager", daemonManager);
#endif
// export to QML monero accounts root directory
// 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
// Windows, ~/Monero Accounts/ on nix / osx
bool isWindows = false;
bool isIOS = false;
bool isMac = false;
#ifdef Q_OS_WIN
isWindows = true;
QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
#elif defined(Q_OS_IOS)
isIOS = true;
QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
#elif defined(Q_OS_UNIX)
QStringList moneroAccountsRootDir = QStandardPaths::standardLocations(QStandardPaths::HomeLocation);
#endif
#ifdef Q_OS_MAC
isMac = true;
#endif
engine.rootContext()->setContextProperty("isWindows", isWindows);
engine.rootContext()->setContextProperty("isIOS", isIOS);
if (!moneroAccountsRootDir.empty()) {
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("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")));
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(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(mouseReleased(QVariant,QVariant,QVariant)), rootObject, SLOT(mouseReleased(QVariant,QVariant,QVariant)));
//WalletManager::instance()->setLogLevel(WalletManager::LogLevel_Max);
return app.exec();
}

386
main.qml
View File

@@ -54,13 +54,20 @@ ApplicationWindow {
property var transaction;
property var transactionDescription;
property alias password : passwordDialog.password
property int splashCounter: 0
property bool isNewWallet: false
property int restoreHeight:0
property bool daemonSynced: false
property int maxWindowHeight: (Screen.height < 900)? 720 : 800;
property bool daemonRunning: false
property alias toolTip: toolTip
property string walletName
property bool viewOnly: false
property bool foundNewBlock: false
property int timeToUnlock: 0
property bool qrScannerEnabled: (typeof builtWithScanner != "undefined") && builtWithScanner
property int blocksToSync: 1
property var isMobile: (appWindow.width > 700) ? false : true
property var cameraUi
// true if wallet ever synchronized
property bool walletInitialized : false
@@ -80,8 +87,9 @@ ApplicationWindow {
return
}
if(seq === "Ctrl+D") middlePanel.state = "Dashboard"
else if(seq === "Ctrl+S") middlePanel.state = "Transfer"
// Dashboard is not implemented
// if(seq === "Ctrl+") middlePanel.state = "Dashboard"
if(seq === "Ctrl+S") middlePanel.state = "Transfer"
else if(seq === "Ctrl+R") middlePanel.state = "Receive"
else if(seq === "Ctrl+K") middlePanel.state = "TxKey"
else if(seq === "Ctrl+H") middlePanel.state = "History"
@@ -89,6 +97,7 @@ ApplicationWindow {
else if(seq === "Ctrl+M") middlePanel.state = "Mining"
else if(seq === "Ctrl+I") middlePanel.state = "Sign"
else if(seq === "Ctrl+E") middlePanel.state = "Settings"
else if(seq === "Ctrl+D") middlePanel.state = "Advanced"
else if(seq === "Ctrl+Tab" || seq === "Alt+Tab") {
/*
if(middlePanel.state === "Dashboard") middlePanel.state = "Transfer"
@@ -140,6 +149,11 @@ ApplicationWindow {
function mousePressed(obj, mouseX, mouseY) {}
function mouseReleased(obj, mouseX, mouseY) {}
function loadPage(page) {
middlePanel.state = page;
leftPanel.selectItem(page);
}
function openWalletFromFile(){
persistentSettings.restore_height = 0
restoreHeight = 0;
@@ -150,15 +164,23 @@ ApplicationWindow {
function initialize() {
console.log("initializing..")
walletInitialized = false;
// Use stored log level
if (persistentSettings.logLevel == 5)
walletManager.setLogCategories(persistentSettings.logCategories)
else
walletManager.setLogLevel(persistentSettings.logLevel)
// setup language
var locale = persistentSettings.locale
if (locale !== "") {
translationManager.setLanguage(locale.split("_")[0]);
}
// Reload transfer page with translations enabled
middlePanel.transferView.onPageCompleted();
// If currentWallet exists, we're just switching daemon - close/reopen wallet
if (typeof currentWallet !== "undefined" && currentWallet !== null) {
console.log("Daemon change - closing " + currentWallet)
@@ -173,7 +195,6 @@ ApplicationWindow {
}
walletManager.setDaemonAddress(persistentSettings.daemon_address)
// wallet already opened with wizard, we just need to initialize it
if (typeof wizard.settings['wallet'] !== 'undefined') {
console.log("using wizard wallet")
@@ -206,6 +227,7 @@ ApplicationWindow {
currentWallet.newBlock.disconnect(onWalletNewBlock)
currentWallet.moneySpent.disconnect(onWalletMoneySent)
currentWallet.moneyReceived.disconnect(onWalletMoneyReceived)
currentWallet.unconfirmedMoneyReceived.disconnect(onWalletUnconfirmedMoneyReceived)
currentWallet.transactionCreated.disconnect(onTransactionCreated)
currentWallet.connectionStatusChanged.disconnect(onWalletConnectionStatusChanged)
middlePanel.paymentClicked.disconnect(handlePayment);
@@ -217,8 +239,11 @@ ApplicationWindow {
}
function connectWallet(wallet) {
showProcessingSplash("Please wait...")
currentWallet = wallet
walletName = usefulName(wallet.path)
updateSyncing(false)
viewOnly = currentWallet.viewOnly;
// connect handlers
currentWallet.refreshed.connect(onWalletRefresh)
@@ -226,6 +251,7 @@ ApplicationWindow {
currentWallet.newBlock.connect(onWalletNewBlock)
currentWallet.moneySpent.connect(onWalletMoneySent)
currentWallet.moneyReceived.connect(onWalletMoneyReceived)
currentWallet.unconfirmedMoneyReceived.connect(onWalletUnconfirmedMoneyReceived)
currentWallet.transactionCreated.connect(onTransactionCreated)
currentWallet.connectionStatusChanged.connect(onWalletConnectionStatusChanged)
middlePanel.paymentClicked.connect(handlePayment);
@@ -235,6 +261,10 @@ ApplicationWindow {
console.log("initializing with daemon address: ", persistentSettings.daemon_address)
console.log("Recovering from seed: ", persistentSettings.is_recovering)
console.log("restore Height", persistentSettings.restore_height)
// Use saved daemon rpc login settings
currentWallet.setDaemonLogin(persistentSettings.daemonUsername, persistentSettings.daemonPassword);
currentWallet.initAsync(persistentSettings.daemon_address, 0, persistentSettings.is_recovering, persistentSettings.restore_height);
}
@@ -243,12 +273,35 @@ ApplicationWindow {
return wallet_path;
}
function onWalletConnectionStatusChanged(){
console.log("Wallet connection status changed")
middlePanel.updateStatus();
function usefulName(path) {
// arbitrary "short enough" limit
if (path.length < 32)
return path
return path.replace(/.*[\/\\]/, '').replace(/\.keys$/, '')
}
function onWalletConnectionStatusChanged(status){
console.log("Wallet connection status changed " + status)
middlePanel.updateStatus();
leftPanel.networkStatus.connected = status
leftPanel.progressBar.visible = (status === Wallet.ConnectionStatus_Connected) && !daemonSynced
// Update fee multiplier dropdown on transfer page
middlePanel.transferView.updatePriorityDropdown();
// If wallet isnt connected and no daemon is running - Ask
if(!walletInitialized && status === Wallet.ConnectionStatus_Disconnected && !daemonManager.running(persistentSettings.testnet)){
daemonManagerDialog.open();
}
// initialize transaction history once wallet is initialized first time;
if (!walletInitialized) {
currentWallet.history.refresh()
walletInitialized = true
}
}
function onWalletOpened(wallet) {
walletName = usefulName(wallet.path)
console.log(">>> wallet opened: " + wallet)
if (wallet.status !== Wallet.Status_Ok) {
if (appWindow.password === '') {
@@ -256,7 +309,7 @@ ApplicationWindow {
console.log("closing wallet async : " + wallet.address)
closeWallet();
// try to open wallet with password;
passwordDialog.open(wallet.path);
passwordDialog.open(walletName);
} else {
// opening with password but password doesn't match
console.error("Error opening wallet with password: ", wallet.errorString);
@@ -268,7 +321,7 @@ ApplicationWindow {
closeWallet();
informationPopup.open()
informationPopup.onCloseCallback = function() {
passwordDialog.open(wallet.path)
passwordDialog.open(walletName)
}
}
return;
@@ -276,7 +329,6 @@ ApplicationWindow {
// wallet opened successfully, subscribing for wallet updates
connectWallet(wallet)
}
@@ -288,32 +340,37 @@ ApplicationWindow {
console.log(">>> wallet updated")
middlePanel.unlockedBalanceText = leftPanel.unlockedBalanceText = walletManager.displayAmount(currentWallet.unlockedBalance);
middlePanel.balanceText = leftPanel.balanceText = walletManager.displayAmount(currentWallet.balance);
// Update history if new block found since last update
if(foundNewBlock) {
foundNewBlock = false;
console.log("New block found - updating history")
currentWallet.history.refresh()
timeToUnlock = currentWallet.history.minutesToUnlock
leftPanel.minutesToUnlockTxt = (timeToUnlock > 0)? (timeToUnlock == 20)? qsTr("Unlocked balance (waiting for block)").arg(timeToUnlock) : qsTr("Unlocked balance (~%1 min)").arg(timeToUnlock) : qsTr("Unlocked balance");
}
}
function onWalletRefresh() {
console.log(">>> wallet refreshed")
if (splash.visible) {
hideProcessingSplash()
}
// Daemon connected
leftPanel.networkStatus.connected = currentWallet.connected
leftPanel.networkStatus.connected = currentWallet.connected()
// Check daemon status
var dCurrentBlock = currentWallet.daemonBlockChainHeight();
var dTargetBlock = currentWallet.daemonBlockChainTargetHeight();
// Daemon fully synced
// TODO: implement onDaemonSynced or similar in wallet API and don't start refresh thread before daemon is synced
daemonSynced = (currentWallet.connected != Wallet.ConnectionStatus_Disconnected && dCurrentBlock >= dTargetBlock)
// targetBlock = currentBlock = 1 before network connection is established.
daemonSynced = dCurrentBlock >= dTargetBlock && dTargetBlock != 1
// Update daemon sync progress
leftPanel.progressBar.updateProgress(dCurrentBlock,dTargetBlock);
leftPanel.progressBar.visible = !daemonSynced && currentWallet.connected() !== Wallet.ConnectionStatus_Disconnected
// Update wallet sync progress
updateSyncing((currentWallet.connected() !== Wallet.ConnectionStatus_Disconnected) && !daemonSynced)
// Update transfer page status
middlePanel.updateStatus();
// If wallet isnt connected and no daemon is running - Ask
if(currentWallet.connected === Wallet.ConnectionStatus_Disconnected && !daemonManager.running() && !walletInitialized){
daemonManagerDialog.open();
}
// Refresh is succesfull if blockchain height > 1
if (currentWallet.blockChainHeight() > 1){
@@ -323,6 +380,9 @@ ApplicationWindow {
console.log("Saving wallet after first refresh");
currentWallet.store()
isNewWallet = false
// Update History
currentWallet.history.refresh();
}
// recovering from seed is finished after first refresh
@@ -331,49 +391,60 @@ ApplicationWindow {
}
}
// initialize transaction history once wallet is initializef first time;
if (!walletInitialized) {
currentWallet.history.refresh()
walletInitialized = true
}
onWalletUpdate();
}
function startDaemon(flags){
// Pause refresh while starting daemon
currentWallet.pauseRefresh();
appWindow.showProcessingSplash(qsTr("Waiting for daemon to start..."))
daemonManager.start(flags);
daemonManager.start(flags, persistentSettings.testnet);
persistentSettings.daemonFlags = flags
}
function stopDaemon(){
appWindow.showProcessingSplash(qsTr("Waiting for daemon to stop..."))
daemonManager.stop();
daemonManager.stop(persistentSettings.testnet);
}
function onDaemonStarted(){
console.log("daemon started");
daemonRunning = true;
hideProcessingSplash();
currentWallet.connected(true);
// resume refresh
currentWallet.startRefresh();
}
function onDaemonStopped(){
console.log("daemon stopped");
hideProcessingSplash();
daemonRunning = false;
currentWallet.connected(true);
}
function onDaemonStartFailure(){
console.log("daemon start failed");
hideProcessingSplash();
// resume refresh
currentWallet.startRefresh();
daemonRunning = false;
informationPopup.title = qsTr("Daemon failed to start") + translationManager.emptyString;
informationPopup.text = qsTr("Please check your wallet and daemon log for errors. You can also try to start %1 manually.").arg((isWindows)? "monerod.exe" : "monerod")
informationPopup.icon = StandardIcon.Critical
informationPopup.onCloseCallback = null
informationPopup.open();
}
function onWalletNewBlock(blockHeight) {
function onWalletNewBlock(blockHeight, targetHeight) {
// Update progress bar
var remaining = targetHeight - blockHeight;
if(blocksToSync < remaining) {
blocksToSync = remaining;
}
// Update progress bar
var currHeight = blockHeight
//fast refresh until restoreHeight is reached
var increment = ((restoreHeight == 0) || currHeight < restoreHeight)? 1000 : 10
if(currHeight > splashCounter + increment){
splashCounter = currHeight
leftPanel.progressBar.updateProgress(currHeight,currentWallet.daemonBlockChainTargetHeight());
}
leftPanel.progressBar.updateProgress(blockHeight,targetHeight, blocksToSync);
foundNewBlock = true;
}
function onWalletMoneyReceived(txId, amount) {
@@ -382,6 +453,12 @@ ApplicationWindow {
currentWallet.history.refresh() // this will refresh model
}
function onWalletUnconfirmedMoneyReceived(txId, amount) {
// refresh history
console.log("unconfirmed money found")
currentWallet.history.refresh()
}
function onWalletMoneySent(txId, amount) {
// refresh transaction history here
currentWallet.refresh()
@@ -403,7 +480,7 @@ ApplicationWindow {
if (transaction.status !== PendingTransaction.Status_Ok) {
console.error("Can't create transaction: ", transaction.errorString);
informationPopup.title = qsTr("Error") + translationManager.emptyString;
if (currentWallet.connected == Wallet.ConnectionStatus_WrongVersion)
if (currentWallet.connected() == Wallet.ConnectionStatus_WrongVersion)
informationPopup.text = qsTr("Can't create transaction: Wrong daemon version: ") + transaction.errorString
else
informationPopup.text = qsTr("Can't create transaction: ") + transaction.errorString
@@ -433,7 +510,7 @@ ApplicationWindow {
+ (paymentId === "" ? "" : (qsTr("\nPayment ID: ") + paymentId))
+ qsTr("\n\nAmount: ") + walletManager.displayAmount(transaction.amount)
+ qsTr("\nFee: ") + walletManager.displayAmount(transaction.fee)
+ qsTr("\n\nMixin: ") + mixinCount
+ qsTr("\n\nRingsize: ") + (mixinCount + 1)
+ qsTr("\n\Number of transactions: ") + transaction.txCount
+ (transactionDescription === "" ? "" : (qsTr("\n\nDescription: ") + transactionDescription))
+ translationManager.emptyString
@@ -444,7 +521,7 @@ ApplicationWindow {
// called on "transfer"
function handlePayment(address, paymentId, amount, mixinCount, priority, description) {
function handlePayment(address, paymentId, amount, mixinCount, priority, description, createFile) {
console.log("Creating transaction: ")
console.log("\taddress: ", address,
", payment_id: ", paymentId,
@@ -463,6 +540,7 @@ ApplicationWindow {
console.log("integer amount: ", amountxmr);
console.log("integer unlocked",currentWallet.unlockedBalance)
if (amountxmr <= 0) {
hideProcessingSplash()
informationPopup.title = qsTr("Error") + translationManager.emptyString;
informationPopup.text = qsTr("Amount is wrong: expected number from %1 to %2")
.arg(walletManager.displayAmount(0))
@@ -474,8 +552,9 @@ ApplicationWindow {
informationPopup.open()
return;
} else if (amountxmr > currentWallet.unlockedBalance) {
hideProcessingSplash()
informationPopup.title = qsTr("Error") + translationManager.emptyString;
informationPopup.text = qsTr("insufficient funds. Unlocked balance: %1")
informationPopup.text = qsTr("Insufficient funds. Unlocked balance: %1")
.arg(walletManager.displayAmount(currentWallet.unlockedBalance))
+ translationManager.emptyString
@@ -492,6 +571,24 @@ ApplicationWindow {
currentWallet.createTransactionAsync(address, paymentId, amountxmr, mixinCount, priority);
}
//Choose where to save transaction
FileDialog {
id: saveTxDialog
title: "Please choose a location"
folder: "file://" +moneroAccountsDir
selectExisting: false;
onAccepted: {
handleTransactionConfirmed()
}
onRejected: {
// do nothing
}
}
function handleSweepUnmixable() {
console.log("Creating transaction: ")
@@ -532,7 +629,7 @@ ApplicationWindow {
}
// called after user confirms transaction
function handleTransactionConfirmed() {
function handleTransactionConfirmed(fileName) {
// grab transaction.txid before commit, since it clears it.
// we actually need to copy it, because QML will incredibly
// call the function multiple times when the variable is used
@@ -543,6 +640,20 @@ ApplicationWindow {
for (var i = 0; i < txid_org.length; ++i)
txid[i] = txid_org[i]
// View only wallet - we save the tx
if(viewOnly && saveTxDialog.fileUrl){
// No file specified - abort
if(!saveTxDialog.fileUrl) {
currentWallet.disposeTransaction(transaction)
return;
}
var path = walletManager.urlToLocalPath(saveTxDialog.fileUrl)
// Store to file
transaction.setFilename(path);
}
if (!transaction.commit()) {
console.log("Error committing transaction: " + transaction.errorString);
informationPopup.title = qsTr("Error") + translationManager.emptyString
@@ -555,12 +666,16 @@ ApplicationWindow {
txid_text += ", "
txid_text += txid[i]
}
informationPopup.text = qsTr("Money sent successfully: %1 transaction(s) ").arg(txid.length) + txid_text + translationManager.emptyString
informationPopup.text = (viewOnly)? qsTr("Transaction saved to file: %1").arg(path) : qsTr("Money sent successfully: %1 transaction(s) ").arg(txid.length) + txid_text + translationManager.emptyString
informationPopup.icon = StandardIcon.Information
if (transactionDescription.length > 0) {
for (var i = 0; i < txid.length; ++i)
currentWallet.setUserNote(txid[i], transactionDescription);
}
// Clear tx fields
middlePanel.transferView.clearFields()
}
informationPopup.onCloseCallback = null
informationPopup.open()
@@ -582,6 +697,7 @@ ApplicationWindow {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
informationPopup.text = "internal error";
informationPopup.icon = StandardIcon.Critical
informationPopup.onCloseCallback = null
informationPopup.open()
return
}
@@ -600,7 +716,7 @@ ApplicationWindow {
else {
var dCurrentBlock = currentWallet.daemonBlockChainHeight();
var confirmations = dCurrentBlock - height
informationPopup.text = qsTr("This address received %1 monero, with %2 confirmations").arg(received).arg(confirmations);
informationPopup.text = qsTr("This address received %1 monero, with %2 confirmation(s).").arg(received).arg(confirmations);
}
}
else {
@@ -615,6 +731,11 @@ ApplicationWindow {
informationPopup.open()
}
function updateSyncing(syncing) {
var text = (syncing ? qsTr("Balance (syncing)") : qsTr("Balance")) + translationManager.emptyString
leftPanel.balanceLabelText = text
middlePanel.balanceLabelText = text
}
// blocks UI if wallet can't be opened or no connection to the daemon
function enableUI(enable) {
@@ -640,14 +761,14 @@ ApplicationWindow {
// close wallet and show wizard
function showWizard(){
walletInitialized = false;
splashCounter = 0;
closeWallet();
currentWallet = undefined;
wizard.restart();
rootItem.state = "wizard"
// reset balance
leftPanel.balanceText = leftPanel.unlockedBalanceText = walletManager.displayAmount(0);
}
objectName: "appWindow"
visible: true
width: rightPanelExpanded ? 1269 : 1269 - 300
@@ -682,8 +803,24 @@ ApplicationWindow {
walletManager.walletClosed.connect(onWalletClosed);
daemonManager.daemonStarted.connect(onDaemonStarted);
daemonManager.daemonStartFailure.connect(onDaemonStartFailure);
daemonManager.daemonStopped.connect(onDaemonStopped);
// Connect app exit to qml window exit handling
mainApp.closing.connect(appWindow.close);
if( appWindow.qrScannerEnabled ){
console.log("qrScannerEnabled : load component QRCodeScanner");
var component = Qt.createComponent("components/QRCodeScanner.qml");
if (component.status == Component.Ready) {
console.log("Camera component ready");
cameraUi = component.createObject(appWindow);
} else {
console.log("component not READY !!!");
appWindow.qrScannerEnabled = false;
}
} else console.log("qrScannerEnabled disabled");
if(!walletsFound()) {
rootItem.state = "wizard"
} else {
@@ -691,6 +828,7 @@ ApplicationWindow {
initialize(persistentSettings);
}
checkUpdates();
}
onRightPanelExpandedChanged: {
@@ -709,6 +847,7 @@ ApplicationWindow {
property bool auto_donations_enabled : false
property int auto_donations_amount : 50
property bool allow_background_mining : false
property bool miningIgnoreBattery : true
property bool testnet: false
property string daemon_address: "localhost:18081"
property string payment_id
@@ -716,6 +855,11 @@ ApplicationWindow {
property bool is_recovering : false
property bool customDecorations : true
property string daemonFlags
property int logLevel: 0
property string logCategories: ""
property string daemonUsername: ""
property string daemonPassword: ""
property bool transferShowAdvanced: false
}
// Information dialog
@@ -736,10 +880,31 @@ ApplicationWindow {
id: transactionConfirmationPopup
onAccepted: {
close();
handleTransactionConfirmed()
// Save transaction to file if view only wallet
if(viewOnly) {
saveTxDialog.open();
return;
} else
handleTransactionConfirmed()
}
}
StandardDialog {
id: confirmationDialog
property var onAcceptedCallback
property var onRejectedCallback
onAccepted: {
if (onAcceptedCallback)
onAcceptedCallback()
}
onRejected: {
if (onRejectedCallback)
onRejectedCallback();
}
}
//Open Wallet from file
FileDialog {
id: fileDialog
@@ -773,6 +938,9 @@ ApplicationWindow {
DaemonManagerDialog {
id: daemonManagerDialog
onRejected: {
loadPage("Settings");
}
}
@@ -785,8 +953,6 @@ ApplicationWindow {
messageText: qsTr("Please wait...")
}
Item {
id: rootItem
anchors.fill: parent
@@ -802,7 +968,7 @@ ApplicationWindow {
PropertyChanges { target: titleBar; basicButtonVisible: false }
PropertyChanges { target: wizard; visible: true }
PropertyChanges { target: appWindow; width: 930; }
PropertyChanges { target: appWindow; height: 595; }
PropertyChanges { target: appWindow; height: 650; }
PropertyChanges { target: resizeArea; visible: false }
PropertyChanges { target: titleBar; maximizeButtonVisible: false }
PropertyChanges { target: frameArea; blocked: true }
@@ -838,7 +1004,7 @@ ApplicationWindow {
onTxkeyClicked: middlePanel.state = "TxKey"
onHistoryClicked: middlePanel.state = "History"
onAddressBookClicked: middlePanel.state = "AddressBook"
onMiningClicked: middlePanel.state = "Minning"
onMiningClicked: middlePanel.state = "Mining"
onSignClicked: middlePanel.state = "Sign"
onSettingsClicked: middlePanel.state = "Settings"
}
@@ -906,19 +1072,15 @@ ApplicationWindow {
properties: "visible"
value: false
}
NumberAnimation {
PropertyAction {
target: appWindow
properties: "height"
to: 30
easing.type: Easing.InCubic
duration: 200
value: 30
}
NumberAnimation {
PropertyAction {
target: appWindow
properties: "width"
to: 470
easing.type: Easing.InCubic
duration: 200
value: 470
}
PropertyAction {
targets: [leftPanel, rightPanel]
@@ -931,12 +1093,10 @@ ApplicationWindow {
value: true
}
NumberAnimation {
PropertyAction {
target: appWindow
properties: "height"
to: middlePanel.height
easing.type: Easing.InCubic
duration: 200
value: middlePanel.height
}
onStopped: {
@@ -948,12 +1108,10 @@ ApplicationWindow {
SequentialAnimation {
id: goToProAnimation
NumberAnimation {
PropertyAction {
target: appWindow
properties: "height"
to: 30
easing.type: Easing.InCubic
duration: 200
value: 30
}
PropertyAction {
target: middlePanel
@@ -965,19 +1123,15 @@ ApplicationWindow {
properties: "visible"
value: true
}
NumberAnimation {
PropertyAction {
target: appWindow
properties: "width"
to: rightPanelExpanded ? 1269 : 1269 - 300
easing.type: Easing.InCubic
duration: 200
value: rightPanelExpanded ? 1269 : 1269 - 300
}
NumberAnimation {
PropertyAction {
target: appWindow
properties: "height"
to: maxWindowHeight
easing.type: Easing.InCubic
duration: 200
value: maxWindowHeight
}
PropertyAction {
target: frameArea
@@ -1004,7 +1158,7 @@ ApplicationWindow {
}
}
property int maxWidth: leftPanel.width + 655 + rightPanel.width
property int minWidth: 326
property int minHeight: 720
MouseArea {
id: resizeArea
@@ -1038,9 +1192,9 @@ ApplicationWindow {
var dx = previousPosition.x - pos.x
var dy = previousPosition.y - pos.y
if(appWindow.width - dx > parent.maxWidth)
if(appWindow.width - dx > parent.minWidth)
appWindow.width -= dx
else appWindow.width = parent.maxWidth
else appWindow.width = parent.minWidth
if(appWindow.height - dy > parent.minHeight)
appWindow.height -= dy
@@ -1111,16 +1265,72 @@ ApplicationWindow {
lineHeight: 0.7
font.family: "Arial"
font.pixelSize: 12
font.letterSpacing: -1
color: "#FFFFFF"
}
}
Notifier {
id: notifier
}
}
onClosing: {
// Close wallet non async on exit
walletManager.closeWallet();
// Stop daemon
daemonManager.stop();
// If daemon is running - prompt user before exiting
if(typeof daemonManager != undefined && daemonManager.running(persistentSettings.testnet)) {
close.accepted = false;
// Show confirmation dialog
confirmationDialog.title = qsTr("Daemon is running") + translationManager.emptyString;
confirmationDialog.text = qsTr("Daemon will still be running in background when GUI is closed.");
confirmationDialog.icon = StandardIcon.Question
confirmationDialog.cancelText = qsTr("Stop daemon")
confirmationDialog.onAcceptedCallback = function() {
closeAccepted();
}
confirmationDialog.onRejectedCallback = function() {
daemonManager.stop(persistentSettings.testnet);
closeAccepted();
};
confirmationDialog.open()
} else {
closeAccepted();
}
}
function closeAccepted(){
// Close wallet non async on exit
daemonManager.exit();
walletManager.closeWallet();
Qt.quit();
}
function checkUpdates() {
var update = walletManager.checkUpdates("monero-gui", "gui")
if (update === "")
return
print("Update found: " + update)
var parts = update.split("|")
if (parts.length == 4) {
var version = parts[0]
var hash = parts[1]
var user_url = parts[2]
var auto_url = parts[3]
var msg = qsTr("New version of monero-wallet-gui is available: %1<br>%2").arg(version).arg(user_url) + translationManager.emptyString
notifier.show(msg)
}
else {
print("Failed to parse update spec")
}
}
Timer {
id: updatesTimer
interval: 3600*1000; running: true; repeat: true
onTriggered: checkUpdates()
}
}

1
monero Submodule

Submodule monero added at c9063c0b8f

View File

@@ -9,10 +9,11 @@ CONFIG += c++11
# cleaning "auto-generated" bitmonero directory on "make distclean"
QMAKE_DISTCLEAN += -r $$WALLET_ROOT
INCLUDEPATH += $$WALLET_ROOT/include \
INCLUDEPATH += $$WALLET_ROOT/include \
$$PWD/src/libwalletqt \
$$PWD/src/QR-Code-generator \
$$PWD/src
$$PWD/src \
$$WALLET_ROOT/src
HEADERS += \
filter.h \
@@ -32,11 +33,11 @@ HEADERS += \
src/QR-Code-generator/BitBuffer.hpp \
src/QR-Code-generator/QrCode.hpp \
src/QR-Code-generator/QrSegment.hpp \
src/daemon/DaemonManager.h \
src/model/AddressBookModel.h \
src/libwalletqt/AddressBook.h \
src/zxcvbn-c/zxcvbn.h
src/zxcvbn-c/zxcvbn.h \
src/libwalletqt/UnsignedTransaction.h \
MainApp.h
SOURCES += main.cpp \
filter.cpp \
@@ -55,10 +56,16 @@ SOURCES += main.cpp \
src/QR-Code-generator/BitBuffer.cpp \
src/QR-Code-generator/QrCode.cpp \
src/QR-Code-generator/QrSegment.cpp \
src/daemon/DaemonManager.cpp \
src/model/AddressBookModel.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 {
SOURCES = *.qml \
@@ -68,35 +75,112 @@ SOURCES = *.qml \
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 \
-lwallet_merged \
-lepee \
-lunbound
}
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
LIBS+= \
-L$$PWD/OpenSSL-for-iPhone/lib \
-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
win32 {
# Win64 Host settings
contains(QMAKE_HOST.arch, x86_64) {
message("Host is 64bit")
MSYS_PATH=c:/msys64/mingw32
# QMAKE_HOST.arch is unreliable, will allways report 32bit if mingw32 shell is run.
# Obtaining arch through uname should be reliable. This also fixes building the project in Qt creator without changes.
MSYS_HOST_ARCH = $$system(uname -a | grep -o "x86_64")
# boost root path
BOOST_PATH=c:/msys64/mingw64/boost
# WIN64 Host settings
contains(MSYS_HOST_ARCH, x86_64) {
message("Host is 64bit")
MSYS_ROOT_PATH=c:/msys64
# WIN32 Host settings
} else {
message("Host is 32bit")
MSYS_PATH=c:/msys32/mingw32
# boost root path
BOOST_PATH=c:/msys32/mingw32/boost
MSYS_ROOT_PATH=c:/msys32
}
# 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_MINGW_PATH/lib
LIBS+=-L$$BOOST_PATH/lib
LIBS+=-L$$BOOST_MINGW_PATH/lib
LIBS+= \
-Wl,-Bstatic \
@@ -129,7 +213,18 @@ win32 {
}
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+= \
-lboost_serialization \
-lboost_thread \
@@ -140,9 +235,13 @@ linux {
-lboost_chrono \
-lboost_program_options \
-lssl \
-lcrypto \
-Wl,-Bdynamic \
-ldl
-lcrypto
if(!android) {
LIBS+= \
-Wl,-Bdynamic \
-lGL
}
# currently monero has an issue with "static" build and linunwind-dev,
# so we link libunwind-dev only for non-Ubuntu distros
CONFIG(libunwind_off) {
@@ -154,6 +253,11 @@ linux {
}
macx {
# mixing static and shared libs are not supported on mac
# CONFIG(static) {
# message("using static libraries")
# LIBS+= -Wl,-Bstatic
# }
LIBS+= \
-L/usr/local/lib \
-L/usr/local/opt/openssl/lib \
@@ -176,16 +280,22 @@ macx {
# translation stuff
TRANSLATIONS = \ # English is default language, no explicit translation file
$$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_fi.ts \ # Finnish
$$PWD/translations/monero-core_fr.ts \ # French
$$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_ja.ts \ # Japanese
$$PWD/translations/monero-core_nl.ts \ # Dutch
$$PWD/translations/monero-core_pl.ts \ # Polish
$$PWD/translations/monero-core_ru.ts \ # Russian
$$PWD/translations/monero-core_zh.ts \ # Chineese
$$PWD/translations/monero-core_zh-cn.ts \ # Chinese (Simplified-China)
$$PWD/translations/monero-core_zh-tw.ts \ # Chinese (Traditional-Taiwan)
CONFIG(release, debug|release) {
DESTDIR = release/bin
@@ -195,7 +305,7 @@ CONFIG(release, debug|release) {
} else {
DESTDIR = debug/bin
LANGUPD_OPTIONS =
LANGREL_OPTIONS = -markuntranslated "MISS_TR "
# LANGREL_OPTIONS = -markuntranslated "MISS_TR "
}
TARGET_FULL_PATH = $$OUT_PWD/$$DESTDIR
@@ -207,32 +317,36 @@ macx {
}
!ios {
isEmpty(QMAKE_LUPDATE) {
win32:LANGUPD = $$[QT_INSTALL_BINS]\lupdate.exe
else:LANGUPD = $$[QT_INSTALL_BINS]/lupdate
}
isEmpty(QMAKE_LUPDATE) {
win32:LANGUPD = $$[QT_INSTALL_BINS]\lupdate.exe
else:LANGUPD = $$[QT_INSTALL_BINS]/lupdate
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
}
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,
@@ -261,10 +375,13 @@ win32 {
}
}
linux {
linux:!android {
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 += \
@@ -272,7 +389,8 @@ OTHER_FILES += \
$$TRANSLATIONS
DISTFILES += \
notes.txt
notes.txt \
monero/src/wallet/CMakeLists.txt
# windows application icon

View File

@@ -1,6 +1,8 @@
#include "oshelper.h"
#include <QTemporaryFile>
#include <QDir>
#include <QDebug>
#include <QString>
OSHelper::OSHelper(QObject *parent) : QObject(parent)
{
@@ -18,6 +20,16 @@ QString OSHelper::temporaryFilename() const
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
{
return QDir::tempPath();

View File

@@ -13,6 +13,7 @@ public:
Q_INVOKABLE QString temporaryFilename() const;
Q_INVOKABLE QString temporaryPath() const;
Q_INVOKABLE bool removeTemporaryWallet(const QString &walletName) const;
signals:

View File

@@ -27,6 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.0
import QtQuick.Layouts 1.1
import "../components"
import moneroComponents.AddressBook 1.0
import moneroComponents.AddressBookModel 1.0
@@ -57,20 +58,40 @@ Rectangle {
anchors.top: newEntryText.bottom
anchors.leftMargin: 17
anchors.topMargin: 17
text: qsTr("Address")
text: qsTr("Address") + translationManager.emptyString
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 {
id: addressLine
anchors.left: parent.left
anchors.left: qrfinderButton.right
anchors.right: parent.right
anchors.top: addressLabel.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
error: true;
placeholderText: qsTr("4...") + translationManager.emptyString
}
Label {
@@ -93,6 +114,7 @@ Rectangle {
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
placeholderText: qsTr("Paste 64 hexadecimal characters") + translationManager.emptyString
}
Label {
@@ -101,7 +123,7 @@ Rectangle {
anchors.top: paymentIdLine.bottom
anchors.leftMargin: 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
tipText: qsTr("<b>Tip test test</b><br/><br/>test line 2") + translationManager.emptyString
}
@@ -114,44 +136,49 @@ Rectangle {
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
placeholderText: qsTr("Give this entry a name or description") + translationManager.emptyString
}
StandardButton {
RowLayout {
id: addButton
anchors.left: parent.left
anchors.top: descriptionLine.bottom
anchors.leftMargin: 17
anchors.topMargin: 17
width: 60
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("ADD")
enabled: checkInformation(addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
StandardButton {
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Add") + translationManager.emptyString
enabled: checkInformation(addressLine.text, paymentIdLine.text, appWindow.persistentSettings.testnet)
onClicked: {
if (!currentWallet.addressBook.addRow(addressLine.text.trim(), paymentIdLine.text.trim(), descriptionLine.text)) {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
// TODO: check currentWallet.addressBook.errorString() instead.
if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Address)
informationPopup.text = qsTr("Invalid address")
else if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Payment_Id)
informationPopup.text = qsTr("Invalid Payment ID")
else
informationPopup.text = qsTr("Can't create entry")
onClicked: {
if (!currentWallet.addressBook.addRow(addressLine.text.trim(), paymentIdLine.text.trim(), descriptionLine.text)) {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
// TODO: check currentWallet.addressBook.errorString() instead.
if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Address)
informationPopup.text = qsTr("Invalid address") + translationManager.emptyString
else if(currentWallet.addressBook.errorCode() === AddressBook.Invalid_Payment_Id)
informationPopup.text = currentWallet.addressBook.errorString()
else
informationPopup.text = qsTr("Can't create entry") + translationManager.emptyString
informationPopup.onCloseCallback = null
informationPopup.open();
} else {
addressLine.text = "";
paymentIdLine.text = "";
descriptionLine.text = "";
informationPopup.onCloseCallback = null
informationPopup.open();
} else {
addressLine.text = "";
paymentIdLine.text = "";
descriptionLine.text = "";
}
}
}
}
Item {
id: expandItem
property bool expanded: false
@@ -275,5 +302,13 @@ Rectangle {
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)
}
}

View File

@@ -244,7 +244,7 @@ Rectangle {
anchors.top: searchLine.bottom //descriptionLine.bottom
anchors.leftMargin: 17
anchors.topMargin: 17
text: qsTr("To")
text: qsTr("To") + translationManager.emptyString
fontSize: 14
tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString
}
@@ -270,7 +270,7 @@ Rectangle {
anchors.left: toDatePicker.right
anchors.leftMargin: 17
width: 60
text: qsTr("FILTER")
text: qsTr("Filter") + translationManager.emptyString
shadowReleasedColor: "#4D0051"
shadowPressedColor: "#2D002F"
releasedColor: "#6B0072"
@@ -307,7 +307,7 @@ Rectangle {
CheckBox {
id: advancedFilteringCheckBox
text: qsTr("Advanced filtering")
text: qsTr("Advanced filtering") + translationManager.emptyString
anchors.left: filterButton.right
anchors.bottom: filterButton.bottom
anchors.leftMargin: 17
@@ -333,9 +333,9 @@ Rectangle {
ListModel {
id: transactionsModel
ListElement { column1: "ALL"; column2: ""; value: TransactionInfo.Direction_Both }
ListElement { column1: "SENT"; column2: ""; value: TransactionInfo.Direction_Out }
ListElement { column1: "RECEIVED"; column2: ""; value: TransactionInfo.Direction_In }
ListElement { column1: "All"; column2: ""; value: TransactionInfo.Direction_Both }
ListElement { column1: "Sent"; column2: ""; value: TransactionInfo.Direction_Out }
ListElement { column1: "Received"; column2: ""; value: TransactionInfo.Direction_In }
}
@@ -393,7 +393,7 @@ Rectangle {
anchors.leftMargin: 17
anchors.topMargin: 17
width: 156
text: qsTr("To")
text: qsTr("To") + translationManager.emptyString
fontSize: 14
tipText: qsTr("<b>Tip tekst test</b>") + translationManager.emptyString
}
@@ -540,6 +540,11 @@ Rectangle {
anchors.rightMargin: 14
onContentYChanged: flickableScroll.flickableContentYChanged()
model: root.model
addressBookModel: null
}
}
function onPageCompleted() {
table.addressBookModel = appWindow.currentWallet ? appWindow.currentWallet.addressBookModel : null
}
}

View File

@@ -27,8 +27,214 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
import "../components"
import moneroComponents.Wallet 1.0
Rectangle {
width: 100
height: 62
id: root
color: "#F0EEEE"
property var currentHashRate: 0
function isDaemonLocal() {
var daemonAddress = appWindow.persistentSettings.daemon_address
if (daemonAddress === "")
return false
var daemonHost = daemonAddress.split(":")[0]
if (daemonHost === "127.0.0.1" || daemonHost === "localhost")
return true
return false
}
/* main layout */
ColumnLayout {
id: mainLayout
anchors.margins: 40
anchors.bottomMargin: 10
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 {
// Disable this option until stable
visible: false
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
anchors.topMargin: 17
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
}
}

View File

@@ -51,16 +51,23 @@ Rectangle {
function updatePaymentId(payment_id) {
if (typeof appWindow.currentWallet === 'undefined' || appWindow.currentWallet == null)
return
// generate a new one if not given as argument
if (typeof payment_id === 'undefined') {
payment_id = appWindow.currentWallet.generatePaymentId()
appWindow.persistentSettings.payment_id = payment_id
paymentIdLine.text = payment_id
}
addressLine.text = appWindow.currentWallet.address
integratedAddressLine.text = appWindow.currentWallet.integratedAddress(payment_id)
if (integratedAddressLine.text === "")
integratedAddressLine.text = qsTr("Invalid payment ID")
if (payment_id.length > 0) {
integratedAddressLine.text = appWindow.currentWallet.integratedAddress(payment_id)
if (integratedAddressLine.text === "")
integratedAddressLine.text = qsTr("Invalid payment ID")
}
else {
paymentIdLine.text = ""
integratedAddressLine.text = ""
}
update()
}
@@ -96,7 +103,7 @@ Rectangle {
setTrackingLineText("-")
return
}
if (appWindow.currentWallet.connected == Wallet.ConnectionStatus_Disconnected) {
if (appWindow.currentWallet.connected() == Wallet.ConnectionStatus_Disconnected) {
setTrackingLineText(qsTr("WARNING: no connection to daemon"))
return
}
@@ -161,7 +168,8 @@ Rectangle {
/* main layout */
ColumnLayout {
id: mainLayout
anchors.margins: 40
anchors.margins: 17
anchors.topMargin: 40
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
@@ -203,39 +211,6 @@ Rectangle {
}
}
RowLayout {
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
Label {
@@ -249,7 +224,7 @@ Rectangle {
LineEdit {
id: paymentIdLine
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("16 or 64 hexadecimal characters") + translationManager.emptyString;
placeholderText: qsTr("16 hexadecimal characters") + translationManager.emptyString;
readOnly: false
onTextChanged: updatePaymentId(paymentIdLine.text)
@@ -269,17 +244,57 @@ Rectangle {
StandardButton {
id: generatePaymentId
width: 80
fontSize: 14
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
text: qsTr("Generate")
anchors.right: parent.right
onClicked: {
appWindow.persistentSettings.payment_id = appWindow.currentWallet.generatePaymentId();
updatePaymentId()
text: qsTr("Generate") + translationManager.emptyString;
onClicked: 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 {
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)
}
}
}
}
}
@@ -296,7 +311,7 @@ Rectangle {
LineEdit {
id: amountLine
fontSize: mainLayout.lineEditFontSize
placeholderText: qsTr("Amount") + translationManager.emptyString
placeholderText: qsTr("Amount to receive") + translationManager.emptyString
readOnly: false
width: mainLayout.editWidth
Layout.fillWidth: true
@@ -358,6 +373,32 @@ Rectangle {
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 {
id: qrCode
anchors.margins: 50
@@ -367,6 +408,15 @@ Rectangle {
smooth: false
fillMode: Image.PreserveAspectFit
source: "image://qrcode/" + makeQRCodeString()
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
if (mouse.button == Qt.RightButton)
qrMenu.popup()
}
onPressAndHold: qrFileDialog.open()
}
}
}
@@ -379,12 +429,14 @@ Rectangle {
function onPageCompleted() {
console.log("Receive page loaded");
if(addressLine.text.length === 0 || addressLine.text !== appWindow.currentWallet.address) {
updatePaymentId()
if (appWindow.currentWallet) {
if (addressLine.text.length === 0 || addressLine.text !== appWindow.currentWallet.address) {
addressLine.text = appWindow.currentWallet.address
}
}
update()
timer.running = true
}
function onPageClosed() {

View File

@@ -39,51 +39,22 @@ import moneroComponents.Clipboard 1.0
Rectangle {
property var daemonAddress
property bool viewOnly: false
color: "#F0EEEE"
Clipboard { id: clipboard }
function initSettings() {
// Mnemonic seed settings
memoTextInput.text = qsTr("Click button to show seed") + translationManager.emptyString
showSeedButton.visible = true
//runs on every page load
// Daemon settings
daemonAddress = persistentSettings.daemon_address.split(":");
console.log("address: " + persistentSettings.daemon_address)
// 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 {
id: mainLayout
anchors.margins: 40
@@ -92,83 +63,18 @@ Rectangle {
anchors.right: parent.right
spacing: 10
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)
}
}
}
//! Manage wallet
RowLayout {
Layout.fillWidth: true
Text {
id: wordsTipText
font.family: "Arial"
font.pointSize: 12
color: "#4A4646"
Label {
id: manageWalletLabel
Layout.fillWidth: true
wrapMode: Text.WordWrap
text: qsTr("This is very important to write down and keep secret. It is all you need to restore your wallet.")
+ translationManager.emptyString
}
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();
}
color: "#4A4949"
text: qsTr("Manage wallet") + translationManager.emptyString
fontSize: 16
Layout.topMargin: 10
}
}
Rectangle {
Layout.fillWidth: true
height: 1
@@ -176,97 +82,8 @@ Rectangle {
}
RowLayout {
id: daemonAddrRow
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 {
id: closeWalletButton
// Layout.leftMargin: 30
// Layout.minimumWidth: 100
width: 100
text: qsTr("Close wallet") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -278,21 +95,60 @@ Rectangle {
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") + translationManager.emptyString
onClicked: {
settingsPasswordDialog.open();
}
}
}
//! Manage daemon
RowLayout {
Label {
id: manageDaemonLabel
Layout.fillWidth: true
color: "#4A4949"
text: qsTr("Manage daemon") + translationManager.emptyString
fontSize: 16
anchors.topMargin: 30
Layout.topMargin: 30
}
}
Rectangle {
Layout.fillWidth: true
height: 1
color: "#DEDEDE"
}
RowLayout {
id: daemonStatusRow
Layout.fillWidth: true
StandardButton {
visible: true
enabled: !appWindow.daemonRunning
id: startDaemonButton
width: 110
text: qsTr("Start daemon") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -307,7 +163,6 @@ Rectangle {
visible: true
enabled: appWindow.daemonRunning
id: stopDaemonButton
width: 110
text: qsTr("Stop daemon") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
@@ -320,19 +175,20 @@ Rectangle {
StandardButton {
visible: true
// enabled: appWindow.daemonRunning
id: daemonConsolePopupButton
width: 110
text: qsTr("Show log") + translationManager.emptyString
id: daemonStatusButton
text: qsTr("Show status") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
onClicked: {
daemonManager.sendCommand("status",currentWallet.testnet);
daemonConsolePopup.open();
}
}
}
RowLayout {
@@ -352,6 +208,109 @@ Rectangle {
}
}
RowLayout {
id: daemonAddrRow
Layout.fillWidth: true
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") + translationManager.emptyString
}
LineEdit {
id: daemonPort
Layout.preferredWidth: 100
Layout.fillWidth: true
text: (daemonAddress !== undefined) ? daemonAddress[1] : "18081"
placeholderText: qsTr("Port") + translationManager.emptyString
}
}
RowLayout {
Label {
id: daemonLoginLabel
Layout.fillWidth: true
color: "#4A4949"
text: qsTr("Login (optional)") + translationManager.emptyString
fontSize: 16
}
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"
visible: true
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 {
CheckBox {
id: customDecorationsCheckBox
@@ -363,6 +322,65 @@ Rectangle {
}
}
// Log level
RowLayout {
Label {
id: logLevelLabel
color: "#4A4949"
text: qsTr("Log level") + translationManager.emptyString
fontSize: 16
}
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("Version") + translationManager.emptyString
fontSize: 16
anchors.topMargin: 30
Layout.topMargin: 30
}
}
Rectangle {
Layout.fillWidth: true
height: 1
color: "#DEDEDE"
}
Label {
id: guiVersion
Layout.topMargin: 8
@@ -377,26 +395,54 @@ Rectangle {
text: qsTr("Embedded Monero version: ") + Version.GUI_MONERO_VERSION + translationManager.emptyString
fontSize: 16
}
}
// Daemon console
StandardDialog {
DaemonConsole {
id: daemonConsolePopup
height:500
width:800
cancelVisible: false
title: qsTr("Daemon log")
title: qsTr("Daemon log") + translationManager.emptyString
onAccepted: {
close();
}
}
PasswordDialog {
id: settingsPasswordDialog
onAccepted: {
if(appWindow.password === settingsPasswordDialog.password){
informationPopup.title = qsTr("Wallet mnemonic seed") + translationManager.emptyString;
informationPopup.text = currentWallet.seed
informationPopup.open()
informationPopup.onCloseCallback = function() {
informationPopup.text = ""
}
} else {
informationPopup.title = qsTr("Error") + translationManager.emptyString;
informationPopup.text = qsTr("Wrong password");
informationPopup.open()
informationPopup.onCloseCallback = function() {
settingsPasswordDialog.open()
}
}
settingsPasswordDialog.password = ""
}
onRejected: {
}
}
// fires on every page load
function onPageCompleted() {
console.log("Settings page loaded");
initSettings();
viewOnly = currentWallet.viewOnly;
appWindow.daemonRunning = daemonManager.running(persistentSettings.testnet)
}
// fires only once

View File

@@ -164,7 +164,7 @@ Rectangle {
id: signMessageButton
anchors.right: parent.right
width: 60
text: qsTr("SIGN") + translationManager.emptyString
text: qsTr("Sign") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@@ -192,7 +192,7 @@ Rectangle {
FileDialog {
id: signFileDialog
title: "Please choose a file to sign"
title: qsTr("Please choose a file to sign") + translationManager.emptyString;
folder: "file://"
nameFilters: [ "*"]
@@ -205,7 +205,7 @@ Rectangle {
id: loadFileToSignButton
anchors.rightMargin: 17
width: 60
text: qsTr("SELECT") + translationManager.emptyString
text: qsTr("Select") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@@ -239,7 +239,7 @@ Rectangle {
id: signFileButton
anchors.right: parent.right
width: 60
text: qsTr("SIGN") + translationManager.emptyString
text: qsTr("Sign") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@@ -349,7 +349,7 @@ Rectangle {
id: verifyMessageButton
anchors.right: parent.right
width: 60
text: qsTr("VERIFY") + translationManager.emptyString
text: qsTr("Verify") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@@ -377,7 +377,7 @@ Rectangle {
FileDialog {
id: verifyFileDialog
title: "Please choose a file to verify"
title: qsTr("Please choose a file to verify") + translationManager.emptyString;
folder: "file://"
nameFilters: [ "*"]
@@ -390,7 +390,7 @@ Rectangle {
id: loadFileToVerifyButton
anchors.rightMargin: 17
width: 60
text: qsTr("SELECT") + translationManager.emptyString
text: qsTr("Select") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
@@ -423,7 +423,7 @@ Rectangle {
id: verifyFileButton
anchors.right: parent.right
width: 60
text: qsTr("VERIFY") + translationManager.emptyString
text: qsTr("Verify") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"

View File

@@ -41,7 +41,8 @@ Rectangle {
signal sweepUnmixableClicked()
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) {
var scaleToMixinCount = [4,5,6,7,8,9,10,11,12,13,14,15,20,25];
@@ -69,6 +70,30 @@ Rectangle {
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
StandardDialog {
// dynamically change onclose handler
@@ -84,331 +109,313 @@ Rectangle {
Item {
id: pageRoot
anchors.fill: parent
Label {
id: amountLabel
anchors.left: parent.left
anchors.top: parent.top
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 17
text: qsTr("Amount") + translationManager.emptyString
fontSize: 14
}
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
height: 400
Label {
id: transactionPriority
anchors.top: parent.top
anchors.topMargin: 17
fontSize: 14
x: (parent.width - 17) / 2 + 17
text: qsTr("Transaction priority") + translationManager.emptyString
}
Label {
id: amountLabel
anchors.left: parent.left
anchors.top: parent.top
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 17
text: qsTr("Amount") + translationManager.emptyString
fontSize: 14
}
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 {
id: transactionPriority
anchors.top: parent.top
anchors.topMargin: 17
fontSize: 14
x: (parent.width - 17) / 2 + 17
text: qsTr("Transaction priority") + translationManager.emptyString
}
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)"
}
}
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
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 }
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"
}
}
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
}
StandardButton {
id: amountAllButton
//anchors.left: amountLine.right
//anchors.top: amountLine.top
//anchors.bottom: amountLine.bottom
width: 60
text: qsTr("All") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
enabled : true
onClicked: amountLine.text = "(all)"
}
}
Label {
id: privacyLabel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: amountRow.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 30
fontSize: 14
text: qsTr("Privacy level") + translationManager.emptyString
}
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 }
PrivacyLevel {
id: privacyLevelItem
anchors.left: parent.left
anchors.right: parent.right
anchors.top: privacyLabel.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
onFillLevelChanged: {
print ("PrivacyLevel changed:" + fillLevel)
print ("mixin count:" + scaleValueToMixinCount(fillLevel))
}
}
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 }
}
// Priorites after v5
ListModel {
id: priorityModelV5
Label {
id: costLabel
anchors.right: parent.right
anchors.top: amountRow.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 30
fontSize: 14
text: qsTr("Transaction cost")
}
ListElement { column1: qsTr("Low (x1 fee)") ; column2: ""; priority: 1}
ListElement { column1: qsTr("Default (x4 fee)") ; column2: ""; priority: 2 }
ListElement { column1: qsTr("Medium (x20 fee)") ; column2: ""; priority: 3 }
ListElement { column1: qsTr("High (x166 fee)") ; column2: ""; priority: 4 }
}
Label {
id: addressLabel
anchors.left: parent.left
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
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"
z: 1
}
onLinkActivated: appWindow.showPageRequest("AddressBook")
}
// recipient address input
RowLayout {
id: addressLineRow
anchors.left: parent.left
anchors.right: parent.right
anchors.top: addressLabel.bottom
Label {
id: addressLabel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: amountRow.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
LineEdit {
id: addressLine
anchors.left: parent.left
anchors.right: resolveButton.left
anchors.leftMargin: 17
anchors.topMargin: 5
placeholderText: "4..."
// validator: RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g }
}
onLinkActivated: appWindow.showPageRequest("AddressBook")
}
// recipient address input
RowLayout {
id: addressLineRow
anchors.left: parent.left
anchors.right: parent.right
anchors.top: addressLabel.bottom
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"))
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 {
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 {
oa_message(qsTr("Internal error"))
}
} else {
oa_message(qsTr("Internal error"))
oa_message(qsTr("No address found"))
}
} else {
oa_message(qsTr("No address found"))
}
}
}
}
}
}
}
Label {
id: paymentIdLabel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: addressLineRow.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 17
fontSize: 14
text: qsTr("Payment ID <font size='2'>( Optional )</font>") + translationManager.emptyString
}
Label {
id: paymentIdLabel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: addressLineRow.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 17
fontSize: 14
text: qsTr("Payment ID <font size='2'>( Optional )</font>") + translationManager.emptyString
}
// payment id input
LineEdit {
id: paymentIdLine
anchors.left: parent.left
anchors.right: parent.right
anchors.top: paymentIdLabel.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
placeholderText: qsTr("16 or 64 hexadecimal characters") + translationManager.emptyString
// validator: DoubleValidator { top: 0.0 }
}
// payment id input
LineEdit {
id: paymentIdLine
anchors.left: parent.left
anchors.right: parent.right
anchors.top: paymentIdLabel.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
placeholderText: qsTr("16 or 64 hexadecimal characters") + translationManager.emptyString
// validator: DoubleValidator { top: 0.0 }
}
Label {
id: descriptionLabel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: paymentIdLine.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 17
fontSize: 14
text: qsTr("Description <font size='2'>( Optional - saved to local wallet history )</font>")
+ translationManager.emptyString
}
Label {
id: descriptionLabel
anchors.left: parent.left
anchors.right: parent.right
anchors.top: paymentIdLine.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 17
fontSize: 14
text: qsTr("Description <font size='2'>( Optional )</font>")
+ translationManager.emptyString
}
LineEdit {
id: descriptionLine
anchors.left: parent.left
anchors.right: parent.right
anchors.top: descriptionLabel.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
}
LineEdit {
id: descriptionLine
anchors.left: parent.left
anchors.right: parent.right
anchors.top: descriptionLabel.bottom
anchors.leftMargin: 17
anchors.rightMargin: 17
anchors.topMargin: 5
placeholderText: qsTr("Saved to local wallet history") + translationManager.emptyString
}
function checkInformation(amount, address, payment_id, testnet) {
address = address.trim()
payment_id = payment_id.trim()
function checkInformation(amount, address, payment_id, testnet) {
address = address.trim()
payment_id = payment_id.trim()
var amount_ok = amount.length > 0
var address_ok = walletManager.addressValid(address, testnet)
var payment_id_ok = payment_id.length == 0 || walletManager.paymentIdValid(payment_id)
var ipid = walletManager.paymentIdFromAddress(address, testnet)
if (ipid.length > 0 && payment_id.length > 0)
payment_id_ok = false
var amount_ok = amount.length > 0
var address_ok = walletManager.addressValid(address, testnet)
var payment_id_ok = payment_id.length == 0 || walletManager.paymentIdValid(payment_id)
var ipid = walletManager.paymentIdFromAddress(address, testnet)
if (ipid.length > 0 && payment_id.length > 0)
payment_id_ok = false
addressLine.error = !address_ok
amountLine.error = !amount_ok
paymentIdLine.error = !payment_id_ok
addressLine.error = !address_ok
amountLine.error = !amount_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 {
id: sweepUnmixableButton
anchors.right: parent.right
anchors.top: descriptionLine.bottom
anchors.rightMargin: 17
anchors.topMargin: 17
width: 60*2
text: qsTr("SWEEP UNMIXABLE") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
enabled : true
onClicked: {
console.log("Transfer: sweepUnmixableClicked")
root.sweepUnmixableClicked()
StandardButton {
id: sendButton
text: qsTr("Send") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
enabled : !appWindow.viewOnly && 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)
}
}
}
}
}
} // pageRoot
Rectangle {
id:desaturate
@@ -417,7 +424,263 @@ Rectangle {
opacity: 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 {
// Label {
// id: manageWalletLabel
// Layout.fillWidth: true
// color: "#4A4949"
// text: qsTr("Advanced options") + translationManager.emptyString
// fontSize: 16
// Layout.topMargin: 20
// }
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()
}
RowLayout {
visible: persistentSettings.transferShowAdvanced
Layout.topMargin: 50
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();
}
}
StandardButton {
id: rescanSpentButton
text: qsTr("Rescan spent") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"
pressedColor: "#FF4304"
enabled: pageRoot.enabled
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();
}
}
}
}
}
//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 {
x: root.width/2 - width/2
@@ -446,19 +709,38 @@ Rectangle {
function onPageCompleted() {
console.log("transfer page loaded")
updateStatus();
updateMixin();
updatePriorityDropdown()
}
function updatePriorityDropdown() {
// Use new fee multipliers after v5 fork
if (typeof currentWallet != "undefined" && currentWallet.useForkRules(5)) {
priorityDropdown.dataModel = priorityModelV5;
priorityDropdown.currentIndex = 1
} else {
priorityDropdown.dataModel = priorityModel;
priorityDropdown.currentIndex = 0
}
}
//TODO: Add daemon sync status
//TODO: enable send page when we're connected and daemon is synced
function updateStatus() {
console.log("updated transfer page status")
if(typeof currentWallet === "undefined") {
statusText.text = qsTr("Wallet is not connected to daemon.") + "<br>" + root.startLinkText
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:
statusText.text = qsTr("Wallet is not connected to daemon.") + "<br>" + root.startLinkText
break

View File

@@ -209,7 +209,7 @@ Rectangle {
anchors.top: txKeyRow.bottom
anchors.topMargin: 17
width: 60
text: qsTr("CHECK") + translationManager.emptyString
text: qsTr("Check") + translationManager.emptyString
shadowReleasedColor: "#FF4304"
shadowPressedColor: "#B32D00"
releasedColor: "#FF6C3C"

16
qml.qrc
View File

@@ -100,13 +100,24 @@
<file>lang/flags/bangladesh.png</file>
<file>lang/flags/brazil.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/india.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/poland.png</file>
<file>lang/flags/rpa.png</file>
<file>lang/flags/russia.png</file>
<file>lang/flags/spain.png</file>
<file>lang/flags/taiwan.png</file>
<file>lang/flags/uk.png</file>
<file>lang/flags/usa.png</file>
<file>lang/flags/indonesia.png</file>
<file>wizard/WizardManageWalletUI.qml</file>
<file>wizard/WizardRecoveryWallet.qml</file>
<file>wizard/WizardMemoTextInput.qml</file>
@@ -122,5 +133,10 @@
<file>pages/Sign.qml</file>
<file>components/DaemonManagerDialog.qml</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>
</qresource>
</RCC>

View 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);
}
}

View 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

View 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());
}
}

View 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

View File

@@ -7,6 +7,11 @@
#include <QtConcurrent/QtConcurrent>
#include <QApplication>
#include <QProcess>
#include <QTime>
namespace {
static const int DAEMON_START_TIMEOUT_SECONDS = 30;
}
DaemonManager * DaemonManager::m_instance = nullptr;
QStringList DaemonManager::m_clArgs;
@@ -23,24 +28,19 @@ DaemonManager *DaemonManager::instance(const QStringList *args)
return m_instance;
}
bool DaemonManager::start(const QString &flags)
bool DaemonManager::start(const QString &flags, bool testnet)
{
//
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
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) {
qDebug() << QString(" [%1] ").arg(str);
if (!str.isEmpty())
@@ -54,8 +54,9 @@ bool DaemonManager::start(const QString &flags)
arguments << str;
}
arguments << "--check-updates" << "disabled";
qDebug() << "starting monerod " + process;
qDebug() << "starting monerod " + m_monerod;
qDebug() << "With command line arguments " << arguments;
m_daemon = new QProcess();
@@ -66,33 +67,100 @@ bool DaemonManager::start(const QString &flags)
connect (m_daemon, SIGNAL(readyReadStandardError()), this, SLOT(printError()));
// Start monerod
m_daemon->start(process,arguments);
bool started = m_daemon->waitForStarted();
bool started = m_daemon->startDetached(m_monerod, arguments);
// add state changed listener
connect(m_daemon,SIGNAL(stateChanged(QProcess::ProcessState)),this,SLOT(stateChanged(QProcess::ProcessState)));
if (!started) {
qDebug() << "Daemon start error: " + m_daemon->errorString();
} else {
emit daemonStarted();
emit daemonStartFailure();
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;
}
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)
{
qDebug() << "STATE CHANGED: " << state;
@@ -123,29 +191,62 @@ void DaemonManager::printError()
}
}
bool DaemonManager::running() const
{
if (initialized) {
qDebug() << m_daemon->state();
qDebug() << QProcess::NotRunning;
// m_daemon->write("status\n");
return m_daemon->state() > QProcess::NotRunning;
bool DaemonManager::running(bool testnet) const
{
QString status;
sendCommand("status",testnet, status);
qDebug() << status;
// `./monerod status` returns BUSY when syncing.
// Treat busy as connected, until fixed upstream.
if (status.contains("Height:") || status.contains("BUSY") ) {
return true;
}
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;
QString external_cmd = m_monerod + " " + cmd;
qDebug() << "sending external cmd: " << external_cmd;
// Add testnet flag if needed
if (testnet)
external_cmd += " --testnet";
external_cmd += "\n";
p.start(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;
}
DaemonManager::DaemonManager(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()
{
qDebug() << __FUNCTION__;
stop();
// Wait for daemon to stop before exiting (max 10 secs)
if (initialized) {
m_daemon->waitForFinished(10000);
if (m_monerod.length() == 0) {
qCritical() << "no daemon binary defined for current platform";
m_has_daemon = false;
}
}

View File

@@ -13,30 +13,40 @@ public:
static DaemonManager * instance(const QStringList *args);
Q_INVOKABLE bool start(const QString &flags);
Q_INVOKABLE bool stop();
Q_INVOKABLE bool start(const QString &flags, bool testnet);
Q_INVOKABLE bool stop(bool testnet);
// 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();
private:
bool sendCommand(const QString &cmd, bool testnet, QString &message) const;
bool startWatcher(bool testnet) const;
bool stopWatcher(bool testnet) const;
signals:
void daemonStarted();
void daemonStopped();
void daemonConsoleUpdated(QString message);
void daemonStarted() const;
void daemonStopped() const;
void daemonStartFailure() const;
void daemonConsoleUpdated(QString message) const;
public slots:
void printOutput();
void printError();
void closing();
void stateChanged(QProcess::ProcessState state);
private:
explicit DaemonManager(QObject *parent = 0);
static DaemonManager * m_instance;
static QStringList m_clArgs;
QProcess *m_daemon;
bool initialized = false;
QString m_monerod;
bool m_has_daemon = true;
bool m_app_exit = false;
};

View File

@@ -68,3 +68,8 @@ quint64 AddressBook::count() const
{
return m_rows.size();
}
int AddressBook::lookupPaymentID(const QString &payment_id) const
{
return m_addressBookImpl->lookupPaymentID(payment_id.toStdString());
}

View File

@@ -22,6 +22,7 @@ public:
quint64 count() const;
Q_INVOKABLE QString errorString() const;
Q_INVOKABLE int errorCode() const;
Q_INVOKABLE int lookupPaymentID(const QString &payment_id) const;
enum ErrorCode {
Status_Ok,

View File

@@ -13,7 +13,10 @@ QString PendingTransaction::errorString() const
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
@@ -47,6 +50,11 @@ quint64 PendingTransaction::txCount() const
return m_pimpl->txCount();
}
void PendingTransaction::setFilename(const QString &fileName)
{
m_fileName = fileName;
}
PendingTransaction::PendingTransaction(Monero::PendingTransaction *pt, QObject *parent)
: QObject(parent), m_pimpl(pt)
{

View File

@@ -44,6 +44,7 @@ public:
quint64 fee() const;
QStringList txid() const;
quint64 txCount() const;
Q_INVOKABLE void setFilename(const QString &fileName);
private:
explicit PendingTransaction(Monero::PendingTransaction * pt, QObject *parent = 0);
@@ -51,6 +52,7 @@ private:
private:
friend class Wallet;
Monero::PendingTransaction * m_pimpl;
QString m_fileName;
};
#endif // PENDINGTRANSACTION_H

View File

@@ -2,7 +2,7 @@
#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;
@@ -15,3 +15,8 @@ QImage QRCodeImageProvider::requestImage(const QString &id, QSize *size, const Q
*size = QSize(qrcode.size, qrcode.size);
return img;
}
QImage QRCodeImageProvider::requestImage(const QString &id, QSize *size, const QSize &/* requestedSize */)
{
return genQrImage(id, size);
}

View File

@@ -7,5 +7,6 @@ public:
QRCodeImageProvider(): QQuickImageProvider(QQuickImageProvider::Image) {}
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
static QImage genQrImage(const QString &id, QSize *size);
};

View File

@@ -31,7 +31,9 @@ QList<TransactionInfo *> TransactionHistory::getAll() const
QDateTime firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block
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);
for (const auto i : m_pimpl->getAll()) {
TransactionInfo * ti = new TransactionInfo(i, parent);
@@ -43,6 +45,14 @@ QList<TransactionInfo *> TransactionHistory::getAll() const
if (ti->timestamp() <= firstDateTime) {
firstDateTime = ti->timestamp();
}
// store last tx height
if (ti->confirmations() < 10 && ti->blockHeight() >= lastTxHeight ){
lastTxHeight = ti->blockHeight();
// TODO: Fetch block time and confirmations needed from wallet2?
m_minutesToUnlock = (10 - ti->confirmations()) * 2;
m_locked = true;
}
}
emit refreshFinished();
@@ -81,9 +91,19 @@ QDateTime TransactionHistory::lastDateTime() const
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)
: 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_lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)

View File

@@ -17,6 +17,8 @@ class TransactionHistory : public QObject
Q_PROPERTY(int count READ count)
Q_PROPERTY(QDateTime firstDateTime READ firstDateTime NOTIFY firstDateTimeChanged)
Q_PROPERTY(QDateTime lastDateTime READ lastDateTime NOTIFY lastDateTimeChanged)
Q_PROPERTY(int minutesToUnlock READ minutesToUnlock)
Q_PROPERTY(bool locked READ locked)
public:
Q_INVOKABLE TransactionInfo *transaction(int index);
@@ -26,6 +28,8 @@ public:
quint64 count() const;
QDateTime firstDateTime() const;
QDateTime lastDateTime() const;
quint64 minutesToUnlock() const;
bool locked() const;
signals:
void refreshStarted() const;
@@ -45,6 +49,9 @@ private:
mutable QList<TransactionInfo*> m_tinfo;
mutable QDateTime m_firstDateTime;
mutable QDateTime m_lastDateTime;
mutable int m_minutesToUnlock;
// history contains locked transfers
mutable bool m_locked;
};

View File

@@ -46,6 +46,11 @@ quint64 TransactionInfo::blockHeight() const
return m_pimpl->blockHeight();
}
quint64 TransactionInfo::confirmations() const
{
return m_pimpl->confirmations();
}
QString TransactionInfo::hash() const
{
return QString::fromStdString(m_pimpl->hash());

View File

@@ -18,6 +18,7 @@ class TransactionInfo : public QObject
Q_PROPERTY(QString displayAmount READ displayAmount)
Q_PROPERTY(QString fee READ fee)
Q_PROPERTY(quint64 blockHeight READ blockHeight)
Q_PROPERTY(quint64 confirmations READ confirmations)
Q_PROPERTY(QString hash READ hash)
Q_PROPERTY(QDateTime timestamp READ timestamp)
Q_PROPERTY(QString date READ date)
@@ -42,6 +43,7 @@ public:
QString displayAmount() const;
QString fee() const;
quint64 blockHeight() const;
quint64 confirmations() const;
//! transaction_id
QString hash() const;
QDateTime timestamp() const;

View File

@@ -0,0 +1,92 @@
#include "UnsignedTransaction.h"
#include <QVector>
#include <QDebug>
UnsignedTransaction::Status UnsignedTransaction::status() const
{
return static_cast<Status>(m_pimpl->status());
}
QString UnsignedTransaction::errorString() const
{
return QString::fromStdString(m_pimpl->errorString());
}
quint64 UnsignedTransaction::amount(int index) const
{
std::vector<uint64_t> arr = m_pimpl->amount();
if(index > arr.size() - 1)
return 0;
return arr[index];
}
quint64 UnsignedTransaction::fee(int index) const
{
std::vector<uint64_t> arr = m_pimpl->fee();
if(index > arr.size() - 1)
return 0;
return arr[index];
}
quint64 UnsignedTransaction::mixin(int index) const
{
std::vector<uint64_t> arr = m_pimpl->mixin();
if(index > arr.size() - 1)
return 0;
return arr[index];
}
quint64 UnsignedTransaction::txCount() const
{
return m_pimpl->txCount();
}
quint64 UnsignedTransaction::minMixinCount() const
{
return m_pimpl->minMixinCount();
}
QString UnsignedTransaction::confirmationMessage() const
{
return QString::fromStdString(m_pimpl->confirmationMessage());
}
QStringList UnsignedTransaction::paymentId() const
{
QList<QString> list;
for (const auto &t: m_pimpl->paymentId())
list.append(QString::fromStdString(t));
return list;
}
QStringList UnsignedTransaction::recipientAddress() const
{
QList<QString> list;
for (const auto &t: m_pimpl->recipientAddress())
list.append(QString::fromStdString(t));
return list;
}
bool UnsignedTransaction::sign(const QString &fileName) const
{
if(!m_pimpl->sign(fileName.toStdString()))
return false;
// export key images
return m_walletImpl->exportKeyImages(fileName.toStdString() + "_keyImages");
}
void UnsignedTransaction::setFilename(const QString &fileName)
{
m_fileName = fileName;
}
UnsignedTransaction::UnsignedTransaction(Monero::UnsignedTransaction *pt, Monero::Wallet *walletImpl, QObject *parent)
: QObject(parent), m_pimpl(pt), m_walletImpl(walletImpl)
{
}
UnsignedTransaction::~UnsignedTransaction()
{
delete m_pimpl;
}

View File

@@ -0,0 +1,59 @@
#ifndef UNSIGNEDTRANSACTION_H
#define UNSIGNEDTRANSACTION_H
#include <QObject>
#include <wallet/wallet2_api.h>
class UnsignedTransaction : public QObject
{
Q_OBJECT
Q_PROPERTY(Status status READ status)
Q_PROPERTY(QString errorString READ errorString)
// Q_PROPERTY(QList<qulonglong> amount READ amount)
// Q_PROPERTY(QList<qulonglong> fee READ fee)
Q_PROPERTY(quint64 txCount READ txCount)
Q_PROPERTY(QString confirmationMessage READ confirmationMessage)
Q_PROPERTY(QStringList recipientAddress READ recipientAddress)
Q_PROPERTY(QStringList paymentId READ paymentId)
Q_PROPERTY(quint64 minMixinCount READ minMixinCount)
public:
enum Status {
Status_Ok = Monero::UnsignedTransaction::Status_Ok,
Status_Error = Monero::UnsignedTransaction::Status_Error,
Status_Critical = Monero::UnsignedTransaction::Status_Critical
};
Q_ENUM(Status)
enum Priority {
Priority_Low = Monero::UnsignedTransaction::Priority_Low,
Priority_Medium = Monero::UnsignedTransaction::Priority_Medium,
Priority_High = Monero::UnsignedTransaction::Priority_High
};
Q_ENUM(Priority)
Status status() const;
QString errorString() const;
Q_INVOKABLE quint64 amount(int index) const;
Q_INVOKABLE quint64 fee(int index) const;
Q_INVOKABLE quint64 mixin(int index) const;
QStringList recipientAddress() const;
QStringList paymentId() const;
quint64 txCount() const;
QString confirmationMessage() const;
quint64 minMixinCount() const;
Q_INVOKABLE bool sign(const QString &fileName) const;
Q_INVOKABLE void setFilename(const QString &fileName);
private:
explicit UnsignedTransaction(Monero::UnsignedTransaction * pt, Monero::Wallet *walletImpl, QObject *parent = 0);
~UnsignedTransaction();
private:
friend class Wallet;
Monero::UnsignedTransaction * m_pimpl;
QString m_fileName;
Monero::Wallet * m_walletImpl;
};
#endif // UNSIGNEDTRANSACTION_H

View File

@@ -1,5 +1,6 @@
#include "Wallet.h"
#include "PendingTransaction.h"
#include "UnsignedTransaction.h"
#include "TransactionHistory.h"
#include "AddressBook.h"
#include "model/TransactionHistoryModel.h"
@@ -15,10 +16,12 @@
#include <QtConcurrent/QtConcurrent>
#include <QList>
#include <QVector>
#include <QMutex>
#include <QMutexLocker>
namespace {
static const int DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS = 10;
static const int DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS = 60;
static const int DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS = 5;
static const int DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS = 30;
static const int WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS = 5;
}
@@ -44,10 +47,16 @@ public:
emit m_wallet->moneyReceived(QString::fromStdString(txId), amount);
}
virtual void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount)
{
qDebug() << __FUNCTION__;
emit m_wallet->unconfirmedMoneyReceived(QString::fromStdString(txId), amount);
}
virtual void newBlock(uint64_t height)
{
// qDebug() << __FUNCTION__;
emit m_wallet->newBlock(height);
emit m_wallet->newBlock(height, m_wallet->daemonBlockChainTargetHeight());
}
virtual void updated()
@@ -91,17 +100,41 @@ Wallet::Status Wallet::status() const
return static_cast<Status>(m_walletImpl->status());
}
Wallet::ConnectionStatus Wallet::connected() const
bool Wallet::testnet() const
{
return m_walletImpl->testnet();
}
void Wallet::updateConnectionStatusAsync()
{
QFuture<Monero::Wallet::ConnectionStatus> future = QtConcurrent::run(m_walletImpl, &Monero::Wallet::connected);
QFutureWatcher<Monero::Wallet::ConnectionStatus> *connectionWatcher = new QFutureWatcher<Monero::Wallet::ConnectionStatus>();
connect(connectionWatcher, &QFutureWatcher<Monero::Wallet::ConnectionStatus>::finished, [=]() {
QFuture<Monero::Wallet::ConnectionStatus> future = connectionWatcher->future();
connectionWatcher->deleteLater();
ConnectionStatus newStatus = static_cast<ConnectionStatus>(future.result());
if (newStatus != m_connectionStatus || !m_initialized) {
m_initialized = true;
m_connectionStatus = newStatus;
qDebug() << "NEW STATUS " << newStatus;
emit connectionStatusChanged(newStatus);
}
// Release lock
m_connectionStatusRunning = false;
});
connectionWatcher->setFuture(future);
}
Wallet::ConnectionStatus Wallet::connected(bool forceCheck)
{
// cache connection status
if (!m_initialized || m_connectionStatusTime.elapsed() / 1000 > m_connectionStatusTtl) {
m_initialized = true;
ConnectionStatus newStatus = static_cast<ConnectionStatus>(m_walletImpl->connected());
if (newStatus != m_connectionStatus) {
m_connectionStatus = newStatus;
emit connectionStatusChanged();
}
if (forceCheck || !m_initialized || (m_connectionStatusTime.elapsed() / 1000 > m_connectionStatusTtl && !m_connectionStatusRunning) || m_connectionStatusTime.elapsed() > 30000) {
qDebug() << "Checking connection status";
m_connectionStatusRunning = true;
m_connectionStatusTime.restart();
updateConnectionStatusAsync();
}
return m_connectionStatus;
@@ -139,17 +172,57 @@ bool Wallet::store(const QString &path)
bool Wallet::init(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering, quint64 restoreHeight)
{
return m_walletImpl->init(daemonAddress.toStdString(), upperTransactionLimit);
}
void Wallet::initAsync(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering, quint64 restoreHeight)
{
qDebug() << "init non async";
if (isRecovering){
qDebug() << "RESTORING";
m_walletImpl->setRecoveringFromSeed(true);
m_walletImpl->setRefreshFromBlockHeight(restoreHeight);
}
m_walletImpl->initAsync(daemonAddress.toStdString(), upperTransactionLimit);
m_walletImpl->init(daemonAddress.toStdString(), upperTransactionLimit, m_daemonUsername.toStdString(), m_daemonPassword.toStdString());
return true;
}
void Wallet::setDaemonLogin(const QString &daemonUsername, const QString &daemonPassword)
{
// store daemon login
m_daemonUsername = daemonUsername;
m_daemonPassword = daemonPassword;
}
void Wallet::initAsync(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering, quint64 restoreHeight)
{
qDebug() << "initAsync: " + daemonAddress;
// Change status to disconnected if connected
if(m_connectionStatus != Wallet::ConnectionStatus_Disconnected) {
m_connectionStatus = Wallet::ConnectionStatus_Disconnected;
emit connectionStatusChanged(m_connectionStatus);
}
QFuture<bool> future = QtConcurrent::run(this, &Wallet::init,
daemonAddress, upperTransactionLimit, isRecovering, restoreHeight);
QFutureWatcher<bool> * watcher = new QFutureWatcher<bool>();
connect(watcher, &QFutureWatcher<bool>::finished,
this, [this, watcher, daemonAddress, upperTransactionLimit, isRecovering, restoreHeight]() {
QFuture<bool> future = watcher->future();
watcher->deleteLater();
if(future.result()){
qDebug() << "init async finished - starting refresh";
connected(true);
m_walletImpl->startRefresh();
}
});
watcher->setFuture(future);
}
//! create a view only wallet
bool Wallet::createViewOnly(const QString &path, const QString &password) const
{
// Create path
QDir d = QFileInfo(path).absoluteDir();
d.mkpath(d.absolutePath());
return m_walletImpl->createWatchOnly(path.toStdString(),password.toStdString(),m_walletImpl->getSeedLanguage());
}
bool Wallet::connectToDaemon()
@@ -162,6 +235,11 @@ void Wallet::setTrustedDaemon(bool arg)
m_walletImpl->setTrustedDaemon(arg);
}
bool Wallet::viewOnly() const
{
return m_walletImpl->watchOnly();
}
quint64 Wallet::balance() const
{
return m_walletImpl->balance();
@@ -191,10 +269,10 @@ quint64 Wallet::daemonBlockChainHeight() const
quint64 Wallet::daemonBlockChainTargetHeight() const
{
if (m_daemonBlockChainTargetHeight == 0
if (m_daemonBlockChainTargetHeight <= 1
|| m_daemonBlockChainTargetHeightTime.elapsed() / 1000 > m_daemonBlockChainTargetHeightTtl) {
m_daemonBlockChainTargetHeight = m_walletImpl->daemonBlockChainTargetHeight();
// Target height is set to 0 if daemon is synced.
// Use current height from daemon when target height < current height
if (m_daemonBlockChainTargetHeight < m_daemonBlockChainHeight){
@@ -217,6 +295,7 @@ bool Wallet::refresh()
void Wallet::refreshAsync()
{
qDebug() << "refresh async";
m_walletImpl->refreshAsync();
}
@@ -230,6 +309,16 @@ int Wallet::autoRefreshInterval() const
return m_walletImpl->autoRefreshInterval();
}
void Wallet::startRefresh() const
{
m_walletImpl->startRefresh();
}
void Wallet::pauseRefresh() const
{
m_walletImpl->pauseRefresh();
}
PendingTransaction *Wallet::createTransaction(const QString &dst_addr, const QString &payment_id,
quint64 amount, quint32 mixin_count,
PendingTransaction::Priority priority)
@@ -248,13 +337,14 @@ void Wallet::createTransactionAsync(const QString &dst_addr, const QString &paym
QFuture<PendingTransaction*> future = QtConcurrent::run(this, &Wallet::createTransaction,
dst_addr, payment_id,amount, mixin_count, priority);
QFutureWatcher<PendingTransaction*> * watcher = new QFutureWatcher<PendingTransaction*>();
watcher->setFuture(future);
connect(watcher, &QFutureWatcher<PendingTransaction*>::finished,
this, [this, watcher,dst_addr,payment_id,mixin_count]() {
QFuture<PendingTransaction*> future = watcher->future();
watcher->deleteLater();
emit transactionCreated(future.result(),dst_addr,payment_id,mixin_count);
});
watcher->setFuture(future);
}
PendingTransaction *Wallet::createTransactionAll(const QString &dst_addr, const QString &payment_id,
@@ -274,13 +364,14 @@ void Wallet::createTransactionAllAsync(const QString &dst_addr, const QString &p
QFuture<PendingTransaction*> future = QtConcurrent::run(this, &Wallet::createTransactionAll,
dst_addr, payment_id, mixin_count, priority);
QFutureWatcher<PendingTransaction*> * watcher = new QFutureWatcher<PendingTransaction*>();
watcher->setFuture(future);
connect(watcher, &QFutureWatcher<PendingTransaction*>::finished,
this, [this, watcher,dst_addr,payment_id,mixin_count]() {
QFuture<PendingTransaction*> future = watcher->future();
watcher->deleteLater();
emit transactionCreated(future.result(),dst_addr,payment_id,mixin_count);
});
watcher->setFuture(future);
}
PendingTransaction *Wallet::createSweepUnmixableTransaction()
@@ -294,13 +385,31 @@ void Wallet::createSweepUnmixableTransactionAsync()
{
QFuture<PendingTransaction*> future = QtConcurrent::run(this, &Wallet::createSweepUnmixableTransaction);
QFutureWatcher<PendingTransaction*> * watcher = new QFutureWatcher<PendingTransaction*>();
watcher->setFuture(future);
connect(watcher, &QFutureWatcher<PendingTransaction*>::finished,
this, [this, watcher]() {
QFuture<PendingTransaction*> future = watcher->future();
watcher->deleteLater();
emit transactionCreated(future.result(),"","",0);
});
watcher->setFuture(future);
}
UnsignedTransaction * Wallet::loadTxFile(const QString &fileName)
{
qDebug() << "Trying to sign " << fileName;
Monero::UnsignedTransaction * ptImpl = m_walletImpl->loadUnsignedTx(fileName.toStdString());
UnsignedTransaction * result = new UnsignedTransaction(ptImpl, m_walletImpl, this);
return result;
}
bool Wallet::submitTxFile(const QString &fileName) const
{
qDebug() << "Trying to submit " << fileName;
if (!m_walletImpl->submitTransaction(fileName.toStdString()))
return false;
// import key images
return m_walletImpl->importKeyImages(fileName.toStdString() + "_keyImages");
}
void Wallet::disposeTransaction(PendingTransaction *t)
@@ -309,6 +418,11 @@ void Wallet::disposeTransaction(PendingTransaction *t)
delete t;
}
void Wallet::disposeTransaction(UnsignedTransaction *t)
{
delete t;
}
TransactionHistory *Wallet::history() const
{
return m_history;
@@ -450,6 +564,40 @@ bool Wallet::verifySignedMessage(const QString &message, const QString &address,
return m_walletImpl->verifySignedMessage(message.toStdString(), address.toStdString(), signature.toStdString());
}
}
bool Wallet::parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector<QString> &unknown_parameters, QString &error)
{
std::string s_address, s_payment_id, s_tx_description, s_recipient_name, s_error;
std::vector<std::string> s_unknown_parameters;
bool res= m_walletImpl->parse_uri(uri.toStdString(), s_address, s_payment_id, amount, s_tx_description, s_recipient_name, s_unknown_parameters, s_error);
if(res)
{
address = QString::fromStdString(s_address);
payment_id = QString::fromStdString(s_payment_id);
tx_description = QString::fromStdString(s_tx_description);
recipient_name = QString::fromStdString(s_recipient_name);
for( const auto &p : s_unknown_parameters )
unknown_parameters.append(QString::fromStdString(p));
}
error = QString::fromStdString(s_error);
return res;
}
bool Wallet::rescanSpent()
{
return m_walletImpl->rescanSpent();
}
bool Wallet::useForkRules(quint8 required_version, quint64 earlyBlocks) const
{
if(m_connectionStatus == Wallet::ConnectionStatus_Disconnected)
return false;
try {
return m_walletImpl->useForkRules(required_version,earlyBlocks);
} catch (const std::exception &e) {
qDebug() << e.what();
return false;
}
}
Wallet::Wallet(Monero::Wallet *w, QObject *parent)
: QObject(parent)
@@ -473,6 +621,9 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
m_daemonBlockChainHeightTime.restart();
m_daemonBlockChainTargetHeightTime.restart();
m_initialized = false;
m_connectionStatusRunning = false;
m_daemonUsername = "";
m_daemonPassword = "";
}
Wallet::~Wallet()
@@ -480,7 +631,9 @@ Wallet::~Wallet()
qDebug("~Wallet: Closing wallet");
delete m_history;
m_history = NULL;
//Monero::WalletManagerFactory::getWalletManager()->closeWallet(m_walletImpl);
delete m_walletImpl;
m_walletImpl = NULL;
qDebug("m_walletImpl deleted");
}

View File

@@ -3,9 +3,12 @@
#include <QObject>
#include <QTime>
#include <QMutex>
#include <QtConcurrent/QtConcurrent>
#include "wallet/wallet2_api.h" // we need to have an access to the Monero::Wallet::Status enum here;
#include "PendingTransaction.h" // we need to have an access to the PendingTransaction::Priority enum here;
#include "UnsignedTransaction.h"
namespace Monero {
class Wallet; // forward declaration
@@ -24,7 +27,8 @@ class Wallet : public QObject
Q_PROPERTY(QString seed READ getSeed)
Q_PROPERTY(QString seedLanguage READ getSeedLanguage)
Q_PROPERTY(Status status READ status)
Q_PROPERTY(ConnectionStatus connected READ connected)
Q_PROPERTY(bool testnet READ testnet)
// Q_PROPERTY(ConnectionStatus connected READ connected)
Q_PROPERTY(bool synchronized READ synchronized)
Q_PROPERTY(QString errorString READ errorString)
Q_PROPERTY(QString address READ address)
@@ -36,7 +40,7 @@ class Wallet : public QObject
Q_PROPERTY(QString path READ path)
Q_PROPERTY(AddressBookModel * addressBookModel READ addressBookModel)
Q_PROPERTY(AddressBook * addressBook READ addressBook)
Q_PROPERTY(bool viewOnly READ viewOnly)
public:
@@ -69,8 +73,12 @@ public:
//! returns last operation's status
Status status() const;
//! returns true testnet wallet.
bool testnet() const;
//! returns whether the wallet is connected, and version status
ConnectionStatus connected() const;
Q_INVOKABLE ConnectionStatus connected(bool forceCheck = false);
void updateConnectionStatusAsync();
//! returns true if wallet was ever synchronized
bool synchronized() const;
@@ -93,10 +101,16 @@ public:
Q_INVOKABLE bool store(const QString &path = "");
//! initializes wallet
Q_INVOKABLE bool init(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering = false, quint64 restoreHeight = 0);
Q_INVOKABLE bool init(const QString &daemonAddress, quint64 upperTransactionLimit = 0, bool isRecovering = false, quint64 restoreHeight = 0);
//! initializes wallet asynchronously
Q_INVOKABLE void initAsync(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering = false, quint64 restoreHeight = 0);
Q_INVOKABLE void initAsync(const QString &daemonAddress, quint64 upperTransactionLimit = 0, bool isRecovering = false, quint64 restoreHeight = 0);
// Set daemon rpc user/pass
Q_INVOKABLE void setDaemonLogin(const QString &daemonUsername = "", const QString &daemonPassword = "");
//! create a view only wallet
Q_INVOKABLE bool createViewOnly(const QString &path, const QString &password) const;
//! connects to daemon
Q_INVOKABLE bool connectToDaemon();
@@ -110,6 +124,9 @@ public:
//! returns unlocked balance
Q_INVOKABLE quint64 unlockedBalance() const;
//! returns if view only wallet
Q_INVOKABLE bool viewOnly() const;
//! returns current wallet's block height
//! (can be less than daemon's blockchain height when wallet sync in progress)
Q_INVOKABLE quint64 blockChainHeight() const;
@@ -132,6 +149,10 @@ public:
//! return auto-refresh interval in seconds
Q_INVOKABLE int autoRefreshInterval() const;
// pause/resume refresh
Q_INVOKABLE void startRefresh() const;
Q_INVOKABLE void pauseRefresh() const;
//! creates transaction
Q_INVOKABLE PendingTransaction * createTransaction(const QString &dst_addr, const QString &payment_id,
quint64 amount, quint32 mixin_count,
@@ -156,9 +177,19 @@ public:
//! creates async sweep unmixable transaction
Q_INVOKABLE void createSweepUnmixableTransactionAsync();
//! Sign a transfer from file
Q_INVOKABLE UnsignedTransaction * loadTxFile(const QString &fileName);
//! Submit a transfer from file
Q_INVOKABLE bool submitTxFile(const QString &fileName) const;
//! deletes transaction and frees memory
Q_INVOKABLE void disposeTransaction(PendingTransaction * t);
//! deletes unsigned transaction and frees memory
Q_INVOKABLE void disposeTransaction(UnsignedTransaction * t);
//! returns transaction history
TransactionHistory * history() const;
@@ -183,6 +214,8 @@ public:
//! verify a signed message
Q_INVOKABLE bool verifySignedMessage(const QString &message, const QString &address, const QString &signature, bool filename = false) const;
//! Parse URI
Q_INVOKABLE bool parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector<QString> &unknown_parameters, QString &error);
//! saved payment id
QString paymentId() const;
@@ -191,8 +224,12 @@ public:
Q_INVOKABLE bool setUserNote(const QString &txid, const QString &note);
Q_INVOKABLE QString getUserNote(const QString &txid) const;
Q_INVOKABLE QString getTxKey(const QString &txid) const;
// Rescan spent outputs
Q_INVOKABLE bool rescanSpent();
// check if fork rules should be used
Q_INVOKABLE bool useForkRules(quint8 version, quint64 earlyBlocks = 0) const;
// TODO: setListenter() when it implemented in API
signals:
@@ -206,13 +243,14 @@ signals:
void moneySpent(const QString &txId, quint64 amount);
void moneyReceived(const QString &txId, quint64 amount);
void newBlock(quint64 height);
void unconfirmedMoneyReceived(const QString &txId, quint64 amount);
void newBlock(quint64 height, quint64 targetHeight);
void historyModelChanged() const;
// emitted when transaction is created async
void transactionCreated(PendingTransaction * transaction, QString address, QString paymentId, quint32 mixinCount);
void connectionStatusChanged() const;
void connectionStatusChanged(ConnectionStatus status) const;
private:
Wallet(QObject * parent = nullptr);
@@ -241,6 +279,10 @@ private:
mutable bool m_initialized;
AddressBook * m_addressBook;
mutable AddressBookModel * m_addressBookModel;
QMutex m_connectionStatusMutex;
bool m_connectionStatusRunning;
QString m_daemonUsername;
QString m_daemonPassword;
};

View File

@@ -2,6 +2,7 @@
#include "Wallet.h"
#include "wallet/wallet2_api.h"
#include "zxcvbn-c/zxcvbn.h"
#include "QRCodeImageProvider.h"
#include <QFile>
#include <QFileInfo>
#include <QDir>
@@ -63,13 +64,14 @@ void WalletManager::openWalletAsync(const QString &path, const QString &password
QFuture<Wallet*> future = QtConcurrent::run(this, &WalletManager::openWallet,
path, password, testnet);
QFutureWatcher<Wallet*> * watcher = new QFutureWatcher<Wallet*>();
watcher->setFuture(future);
connect(watcher, &QFutureWatcher<Wallet*>::finished,
this, [this, watcher]() {
QFuture<Wallet*> future = watcher->future();
watcher->deleteLater();
emit walletOpened(future.result());
});
watcher->setFuture(future);
}
@@ -85,6 +87,22 @@ Wallet *WalletManager::recoveryWallet(const QString &path, const QString &memo,
return m_currentWallet;
}
Wallet *WalletManager::createWalletFromKeys(const QString &path, const QString &language, bool testnet,
const QString &address, const QString &viewkey, const QString &spendkey,
quint64 restoreHeight)
{
QMutexLocker locker(&m_mutex);
if (m_currentWallet) {
qDebug() << "Closing open m_currentWallet" << m_currentWallet;
delete m_currentWallet;
m_currentWallet = NULL;
}
Monero::Wallet * w = m_pimpl->createWalletFromKeys(path.toStdString(), language.toStdString(), testnet, restoreHeight,
address.toStdString(), viewkey.toStdString(), spendkey.toStdString());
m_currentWallet = new Wallet(w);
return m_currentWallet;
}
QString WalletManager::closeWallet()
{
@@ -104,7 +122,6 @@ void WalletManager::closeWalletAsync()
{
QFuture<QString> future = QtConcurrent::run(this, &WalletManager::closeWallet);
QFutureWatcher<QString> * watcher = new QFutureWatcher<QString>();
watcher->setFuture(future);
connect(watcher, &QFutureWatcher<QString>::finished,
this, [this, watcher]() {
@@ -112,6 +129,7 @@ void WalletManager::closeWalletAsync()
watcher->deleteLater();
emit walletClosed(future.result());
});
watcher->setFuture(future);
}
bool WalletManager::walletExists(const QString &path) const
@@ -182,6 +200,16 @@ bool WalletManager::addressValid(const QString &address, bool testnet) const
return Monero::Wallet::addressValid(address.toStdString(), testnet);
}
bool WalletManager::keyValid(const QString &key, const QString &address, bool isViewKey, bool testnet) const
{
std::string error;
if(!Monero::Wallet::keyValid(key.toStdString(), address.toStdString(), isViewKey, testnet, error)){
qDebug() << QString::fromStdString(error);
return false;
}
return true;
}
QString WalletManager::paymentIdFromAddress(const QString &address, bool testnet) const
{
return QString::fromStdString(Monero::Wallet::paymentIdFromAddress(address.toStdString(), testnet));
@@ -227,6 +255,25 @@ double WalletManager::miningHashRate() const
return m_pimpl->miningHashRate();
}
bool WalletManager::isMining() const
{
if(!m_currentWallet->connected())
return false;
return m_pimpl->isMining();
}
bool WalletManager::startMining(const QString &address, quint32 threads, bool backgroundMining, bool ignoreBattery)
{
if(threads == 0)
threads = 1;
return m_pimpl->startMining(address.toStdString(), threads, backgroundMining, ignoreBattery);
}
bool WalletManager::stopMining()
{
return m_pimpl->stopMining();
}
QString WalletManager::resolveOpenAlias(const QString &address) const
{
bool dnssec_valid = false;
@@ -234,12 +281,23 @@ QString WalletManager::resolveOpenAlias(const QString &address) const
res = std::string(dnssec_valid ? "true" : "false") + "|" + res;
return QString::fromStdString(res);
}
bool WalletManager::parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector<QString> &unknown_parameters, QString &error)
{
if (m_currentWallet)
return m_currentWallet->parse_uri(uri, address, payment_id, amount, tx_description, recipient_name, unknown_parameters, error);
return false;
}
void WalletManager::setLogLevel(int logLevel)
{
Monero::WalletManagerFactory::setLogLevel(logLevel);
}
void WalletManager::setLogCategories(const QString &categories)
{
Monero::WalletManagerFactory::setLogCategories(categories.toStdString());
}
QString WalletManager::urlToLocalPath(const QUrl &url) const
{
return QDir::toNativeSeparators(url.toLocalFile());
@@ -265,6 +323,21 @@ double WalletManager::getPasswordStrength(const QString &password) const
return e;
}
bool WalletManager::saveQrCode(const QString &code, const QString &path) const
{
QSize size;
// 240 <=> mainLayout.qrCodeSize (Receive.qml)
return QRCodeImageProvider::genQrImage(code, &size).scaled(size.expandedTo(QSize(240, 240)), Qt::KeepAspectRatio).save(path, "PNG", 100);
}
QString WalletManager::checkUpdates(const QString &software, const QString &subdir) const
{
const std::tuple<bool, std::string, std::string, std::string, std::string> result = Monero::WalletManager::checkUpdates(software.toStdString(), subdir.toStdString());
if (!std::get<0>(result))
return QString("");
return QString::fromStdString(std::get<1>(result) + "|" + std::get<2>(result) + "|" + std::get<3>(result) + "|" + std::get<4>(result));
}
WalletManager::WalletManager(QObject *parent) : QObject(parent)
{
m_pimpl = Monero::WalletManagerFactory::getWalletManager();

View File

@@ -53,6 +53,14 @@ public:
Q_INVOKABLE Wallet * recoveryWallet(const QString &path, const QString &memo,
bool testnet = false, quint64 restoreHeight = 0);
Q_INVOKABLE Wallet * createWalletFromKeys(const QString &path,
const QString &language,
bool testnet,
const QString &address,
const QString &viewkey,
const QString &spendkey = "",
quint64 restoreHeight = 0);
/*!
* \brief closeWallet - closes current open wallet and frees memory
* \return wallet address
@@ -92,6 +100,8 @@ public:
Q_INVOKABLE bool paymentIdValid(const QString &payment_id) const;
Q_INVOKABLE bool addressValid(const QString &address, bool testnet) const;
Q_INVOKABLE bool keyValid(const QString &key, const QString &address, bool isViewKey, bool testnet) const;
Q_INVOKABLE QString paymentIdFromAddress(const QString &address, bool testnet) const;
Q_INVOKABLE QString checkPayment(const QString &address, const QString &txid, const QString &txkey, const QString &daemon_address) const;
@@ -103,11 +113,16 @@ public:
Q_INVOKABLE quint64 blockchainTargetHeight() const;
Q_INVOKABLE double miningHashRate() const;
Q_INVOKABLE bool isMining() const;
Q_INVOKABLE bool startMining(const QString &address, quint32 threads, bool backgroundMining, bool ignoreBattery);
Q_INVOKABLE bool stopMining();
// QML missing such functionality, implementing these helpers here
Q_INVOKABLE QString urlToLocalPath(const QUrl &url) const;
Q_INVOKABLE QUrl localPathToUrl(const QString &path) const;
void setLogLevel(int logLevel);
Q_INVOKABLE void setLogLevel(int logLevel);
Q_INVOKABLE void setLogCategories(const QString &categories);
Q_INVOKABLE quint64 add(quint64 x, quint64 y) const { return x + y; }
Q_INVOKABLE quint64 sub(quint64 x, quint64 y) const { return x - y; }
@@ -117,6 +132,9 @@ public:
Q_INVOKABLE double getPasswordStrength(const QString &password) const;
Q_INVOKABLE QString resolveOpenAlias(const QString &address) const;
Q_INVOKABLE bool parse_uri(const QString &uri, QString &address, QString &payment_id, uint64_t &amount, QString &tx_description, QString &recipient_name, QVector<QString> &unknown_parameters, QString &error);
Q_INVOKABLE bool saveQrCode(const QString &, const QString &) const;
Q_INVOKABLE QString checkUpdates(const QString &software, const QString &subdir) const;
signals:

View File

@@ -63,6 +63,11 @@ bool AddressBookModel::deleteRow(int row)
m_addressBook->deleteRow(row);
}
int AddressBookModel::lookupPaymentID(const QString &payment_id) const
{
return m_addressBook->lookupPaymentID(payment_id);
}
QHash<int, QByteArray> AddressBookModel::roleNames() const
{
QHash<int, QByteArray> roleNames = QAbstractListModel::roleNames();

View File

@@ -24,6 +24,7 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_INVOKABLE bool deleteRow(int row);
Q_INVOKABLE int lookupPaymentID(const QString &payment_id) const;
virtual QHash<int, QByteArray> roleNames() const override;
public slots:

View File

@@ -75,7 +75,15 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
result = tInfo->fee();
break;
case TransactionBlockHeightRole:
result = tInfo->blockHeight();
// Use NULL QVariant for transactions without height.
// Forces them to be displayed at top when sorted by blockHeight.
if (tInfo->blockHeight() != 0) {
result = tInfo->blockHeight();
}
break;
case TransactionConfirmationsRole:
result = tInfo->confirmations();
break;
case TransactionHashRole:
result = tInfo->hash();
@@ -121,6 +129,7 @@ QHash<int, QByteArray> TransactionHistoryModel::roleNames() const
roleNames.insert(TransactionAtomicAmountRole, "atomicAmount");
roleNames.insert(TransactionFeeRole, "fee");
roleNames.insert(TransactionBlockHeightRole, "blockHeight");
roleNames.insert(TransactionConfirmationsRole, "confirmations");
roleNames.insert(TransactionHashRole, "hash");
roleNames.insert(TransactionTimeStampRole, "timeStamp");
roleNames.insert(TransactionPaymentIdRole, "paymentId");

View File

@@ -25,6 +25,7 @@ public:
TransactionDisplayAmountRole,
TransactionFeeRole,
TransactionBlockHeightRole,
TransactionConfirmationsRole,
TransactionHashRole,
TransactionTimeStampRole,
TransactionPaymentIdRole,

View File

@@ -1233,7 +1233,7 @@ Description: </source>
</message>
<message>
<location filename="../main.qml" line="442"/>
<source>insufficient funds. Unlocked balance: %1</source>
<source>Insufficient funds. Unlocked balance: %1</source>
<translation type="unfinished"></translation>
</message>
<message>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,834 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="hi_IN">
<context>
<name>AddressBook</name>
<message>
<location filename="../pages/AddressBook.qml" line="47"/>
<source>Add new entry</source>
<translation> िि </translation>
</message>
<message>
<location filename="../pages/AddressBook.qml" line="56"/>
<location filename="../pages/AddressBook.qml" line="173"/>
<source>Address</source>
<translation></translation>
</message>
<message>
<location filename="../pages/AddressBook.qml" line="58"/>
<source>&lt;b&gt;Tip tekst test&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../pages/AddressBook.qml" line="77"/>
<source>Payment ID &lt;font size=&apos;2&apos;&gt;(Optional)&lt;/font&gt;</source>
<translation> &lt;font size=&apos;2&apos;&gt;(ि)&lt;/font&gt;</translation>
</message>
<message>
<location filename="../pages/AddressBook.qml" line="79"/>
<source>&lt;b&gt;Payment ID&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;A unique user name used in&lt;br/&gt;the address book. It is not a&lt;br/&gt;transfer of information sent&lt;br/&gt;during thevtransfer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../pages/AddressBook.qml" line="99"/>
<source>Description &lt;font size=&apos;2&apos;&gt;(Local database)&lt;/font&gt;</source>
<translation>ि &lt;font size=&apos;2&apos;&gt;( )&lt;/font&gt;</translation>
</message>
<message>
<location filename="../pages/AddressBook.qml" line="101"/>
<source>&lt;b&gt;Tip tekst test&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;test line 2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../pages/AddressBook.qml" line="126"/>
<source>ADD</source>
<translation></translation>
</message>
<message>
<location filename="../pages/AddressBook.qml" line="174"/>
<source>Payment ID</source>
<translation> </translation>
</message>
<message>
<location filename="../pages/AddressBook.qml" line="175"/>
<source>Description</source>
<translation>ि</translation>
</message>
</context>
<context>
<name>AddressBookTable</name>
<message>
<location filename="../components/AddressBookTable.qml" line="47"/>
<source>No more results</source>
<translation> ि ि </translation>
</message>
<message>
<location filename="../components/AddressBookTable.qml" line="106"/>
<source>Payment ID:</source>
<translation> :</translation>
</message>
</context>
<context>
<name>BasicPanel</name>
<message>
<location filename="../BasicPanel.qml" line="78"/>
<source>Locked Balance:</source>
<translation> ि:</translation>
</message>
<message>
<location filename="../BasicPanel.qml" line="92"/>
<source>78.9239845</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../BasicPanel.qml" line="116"/>
<source>Available Balance:</source>
<translation> ि:</translation>
</message>
<message>
<location filename="../BasicPanel.qml" line="130"/>
<source>2324.9239845</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../BasicPanel.qml" line="155"/>
<source>amount...</source>
<translation>ि...</translation>
</message>
<message>
<location filename="../BasicPanel.qml" line="163"/>
<source>SEND</source>
<translation></translation>
</message>
<message>
<location filename="../BasicPanel.qml" line="179"/>
<source>destination...</source>
<translation>...</translation>
</message>
<message>
<location filename="../BasicPanel.qml" line="191"/>
<source>Privacy level</source>
<translation> </translation>
</message>
<message>
<location filename="../BasicPanel.qml" line="212"/>
<source>payment ID (optional)...</source>
<translation> (ि)...</translation>
</message>
</context>
<context>
<name>Dashboard</name>
<message>
<location filename="../pages/Dashboard.qml" line="57"/>
<source>Quick transfer</source>
<translation> </translation>
</message>
<message>
<location filename="../pages/Dashboard.qml" line="89"/>
<source>SEND</source>
<translation></translation>
</message>
<message>
<location filename="../pages/Dashboard.qml" line="102"/>
<source>&lt;style type=&apos;text/css&apos;&gt;a {text-decoration: none; color: #FF6C3C; font-size: 14px;}&lt;/style&gt; lookng for security level and address book? go to &lt;a href=&apos;#&apos;&gt;Transfer&lt;/a&gt; tab</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DashboardTable</name>
<message>
<location filename="../components/DashboardTable.qml" line="47"/>
<source>No more results</source>
<translation> ि ि </translation>
</message>
<message>
<location filename="../components/DashboardTable.qml" line="137"/>
<source>Date</source>
<translation>िि</translation>
</message>
<message>
<location filename="../components/DashboardTable.qml" line="172"/>
<source>Balance</source>
<translation>ि</translation>
</message>
<message>
<location filename="../components/DashboardTable.qml" line="193"/>
<source>Amount</source>
<translation>ि</translation>
</message>
</context>
<context>
<name>History</name>
<message>
<location filename="../pages/History.qml" line="47"/>
<source>Filter trasactions history</source>
<translation> ि ि </translation>
</message>
<message>
<location filename="../pages/History.qml" line="56"/>
<source>Address</source>
<translation></translation>
</message>
<message>
<location filename="../pages/History.qml" line="58"/>
<location filename="../pages/History.qml" line="123"/>
<location filename="../pages/History.qml" line="143"/>
<location filename="../pages/History.qml" line="191"/>
<location filename="../pages/History.qml" line="225"/>
<location filename="../pages/History.qml" line="246"/>
<source>&lt;b&gt;Tip tekst test&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../pages/History.qml" line="77"/>
<source>Payment ID &lt;font size=&apos;2&apos;&gt;(Optional)&lt;/font&gt;</source>
<translation> &lt;font size=&apos;2&apos;&gt;(ि)&lt;/font&gt;</translation>
</message>
<message>
<location filename="../pages/History.qml" line="79"/>
<source>&lt;b&gt;Payment ID&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;A unique user name used in&lt;br/&gt;the address book. It is not a&lt;br/&gt;transfer of information sent&lt;br/&gt;during thevtransfer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../pages/History.qml" line="99"/>
<source>Description &lt;font size=&apos;2&apos;&gt;(Local database)&lt;/font&gt;</source>
<translation>ि &lt;font size=&apos;2&apos;&gt;( )&lt;/font&gt;</translation>
</message>
<message>
<location filename="../pages/History.qml" line="101"/>
<source>&lt;b&gt;Tip tekst test&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;test line 2</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../pages/History.qml" line="121"/>
<source>Date from</source>
<translation>िि </translation>
</message>
<message>
<location filename="../pages/History.qml" line="141"/>
<location filename="../pages/History.qml" line="244"/>
<source>To</source>
<translation></translation>
</message>
<message>
<location filename="../pages/History.qml" line="161"/>
<source>FILTER</source>
<translation>ि </translation>
</message>
<message>
<location filename="../pages/History.qml" line="170"/>
<source>Advance filtering</source>
<translation> ि</translation>
</message>
<message>
<location filename="../pages/History.qml" line="189"/>
<source>Type of transation</source>
<translation> </translation>
</message>
<message>
<location filename="../pages/History.qml" line="223"/>
<source>Amount from</source>
<translation>ि</translation>
</message>
</context>
<context>
<name>HistoryTable</name>
<message>
<location filename="../components/HistoryTable.qml" line="47"/>
<source>No more results</source>
<translation> ि ि </translation>
</message>
<message>
<location filename="../components/HistoryTable.qml" line="129"/>
<source>Payment ID:</source>
<translation> :</translation>
</message>
<message>
<location filename="../components/HistoryTable.qml" line="167"/>
<source>Date</source>
<translation>िि</translation>
</message>
<message>
<location filename="../components/HistoryTable.qml" line="202"/>
<source>Balance</source>
<translation>ि</translation>
</message>
<message>
<location filename="../components/HistoryTable.qml" line="223"/>
<source>Amount</source>
<translation>ि</translation>
</message>
</context>
<context>
<name>LeftPanel</name>
<message>
<location filename="../LeftPanel.qml" line="103"/>
<source>Balance</source>
<translation>ि</translation>
</message>
<message>
<location filename="../LeftPanel.qml" line="106"/>
<source>Test tip 1&lt;br/&gt;&lt;br/&gt;line 2</source>
<translation> 1&lt;br/&gt;&lt;br/&gt;line 2</translation>
</message>
<message>
<location filename="../LeftPanel.qml" line="138"/>
<source>Unlocked balance</source>
<translation> ि</translation>
</message>
<message>
<location filename="../LeftPanel.qml" line="141"/>
<source>Test tip 2&lt;br/&gt;&lt;br/&gt;line 2</source>
<translation> 2&lt;br/&gt;&lt;br/&gt;line 2</translation>
</message>
<message>
<location filename="../LeftPanel.qml" line="222"/>
<source>Transfer</source>
<translation></translation>
</message>
<message>
<location filename="../LeftPanel.qml" line="223"/>
<source>T</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../LeftPanel.qml" line="245"/>
<source>Receive</source>
<translation> </translation>
</message>
<message>
<location filename="../LeftPanel.qml" line="246"/>
<source>R</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NetworkStatusItem</name>
<message>
<location filename="../components/NetworkStatusItem.qml" line="58"/>
<source>Network status</source>
<translation> िि</translation>
</message>
<message>
<location filename="../components/NetworkStatusItem.qml" line="66"/>
<source>Connected</source>
<translation> ि </translation>
</message>
<message>
<location filename="../components/NetworkStatusItem.qml" line="66"/>
<source>Disconnected</source>
<translation>ि ि </translation>
</message>
</context>
<context>
<name>PrivacyLevelSmall</name>
<message>
<location filename="../components/PrivacyLevelSmall.qml" line="102"/>
<source>LOW</source>
<translation>ि</translation>
</message>
<message>
<location filename="../components/PrivacyLevelSmall.qml" line="113"/>
<source>MEDIUM</source>
<translation></translation>
</message>
<message>
<location filename="../components/PrivacyLevelSmall.qml" line="124"/>
<source>HIGH</source>
<translation></translation>
</message>
</context>
<context>
<name>Receive</name>
<message>
<location filename="../pages/Receive.qml" line="79"/>
<source>Address</source>
<translation></translation>
</message>
<message>
<location filename="../pages/Receive.qml" line="86"/>
<source>ReadOnly wallet address displayed here</source>
<translation> ि </translation>
</message>
<message>
<location filename="../pages/Receive.qml" line="106"/>
<source>Integrated address</source>
<translation> </translation>
</message>
<message>
<location filename="../pages/Receive.qml" line="115"/>
<source>ReadOnly wallet integrated address displayed here</source>
<translation> ि </translation>
</message>
<message>
<location filename="../pages/Receive.qml" line="136"/>
<source>Payment ID</source>
<translation> </translation>
</message>
<message>
<location filename="../pages/Receive.qml" line="144"/>
<source>PaymentID here</source>
<translation> </translation>
</message>
<message>
<location filename="../pages/Receive.qml" line="168"/>
<source>Generate</source>
<translation> </translation>
</message>
</context>
<context>
<name>RightPanel</name>
<message>
<location filename="../RightPanel.qml" line="58"/>
<source>Twitter</source>
<translation>ि</translation>
</message>
<message>
<location filename="../RightPanel.qml" line="59"/>
<source>News</source>
<translation></translation>
</message>
<message>
<location filename="../RightPanel.qml" line="60"/>
<source>Help</source>
<translation></translation>
</message>
<message>
<location filename="../RightPanel.qml" line="61"/>
<source>About</source>
<translation> </translation>
</message>
</context>
<context>
<name>SearchInput</name>
<message>
<location filename="../components/SearchInput.qml" line="69"/>
<source>Search by...</source>
<translation>ि ...</translation>
</message>
<message>
<location filename="../components/SearchInput.qml" line="230"/>
<source>SEARCH</source>
<translation></translation>
</message>
</context>
<context>
<name>TickDelegate</name>
<message>
<location filename="../components/TickDelegate.qml" line="55"/>
<source>LOW</source>
<translation>ि</translation>
</message>
<message>
<location filename="../components/TickDelegate.qml" line="56"/>
<source>MEDIUM</source>
<translation></translation>
</message>
<message>
<location filename="../components/TickDelegate.qml" line="57"/>
<source>HIGH</source>
<translation></translation>
</message>
</context>
<context>
<name>TitleBar</name>
<message>
<location filename="../components/TitleBar.qml" line="38"/>
<source>Monero - Donations</source>
<translation>Monero - </translation>
</message>
</context>
<context>
<name>Transfer</name>
<message>
<location filename="../pages/Transfer.qml" line="57"/>
<source>Amount</source>
<translation>ि</translation>
</message>
<message>
<location filename="../pages/Transfer.qml" line="67"/>
<source>Transaction priority</source>
<translation> ि</translation>
</message>
<message>
<location filename="../pages/Transfer.qml" line="89"/>
<source>Amount...</source>
<translation>ि....</translation>
</message>
<message>
<location filename="../pages/Transfer.qml" line="96"/>
<source>LOW</source>
<translation>ि</translation>
</message>
<message>
<location filename="../pages/Transfer.qml" line="97"/>
<source>MEDIUM</source>
<translation></translation>
</message>
<message>
<location filename="../pages/Transfer.qml" line="98"/>
<source>HIGH</source>
<translation></translation>
</message>
<message>
<location filename="../pages/Transfer.qml" line="127"/>
<source>Privacy Level</source>
<translation> </translation>
</message>
<message>
<location filename="../pages/Transfer.qml" line="153"/>
<source>Cost</source>
<translation></translation>
</message>
<message>
<location filename="../pages/Transfer.qml" line="167"/>
<source>&lt;style type=&apos;text/css&apos;&gt;a {text-decoration: none; color: #FF6C3C; font-size: 14px;}&lt;/style&gt; Address &lt;font size=&apos;2&apos;&gt; ( Type in or select from &lt;/font&gt; &lt;a href=&apos;#&apos;&gt;Address&lt;/a&gt;&lt;font size=&apos;2&apos;&gt; book )&lt;/font&gt;</source>
<translation type="unfinished">&lt;style type=&apos;text/css&apos;&gt;a {text-decoration: none; color: #FF6C3C; font-size: 14px;}&lt;/style&gt; &lt;font size=&apos;2&apos;&gt; ( Type in or select from &lt;/font&gt; &lt;a href=&apos;#&apos;&gt;&lt;/a&gt;&lt;font size=&apos;2&apos;&gt; ि )&lt;/font&gt;</translation>
</message>
<message>
<location filename="../pages/Transfer.qml" line="194"/>
<source>Payment ID &lt;font size=&apos;2&apos;&gt;( Optional )&lt;/font&gt;</source>
<translation> &lt;font size=&apos;2&apos;&gt;( ि )&lt;/font&gt;</translation>
</message>
<message>
<location filename="../pages/Transfer.qml" line="218"/>
<source>Description &lt;font size=&apos;2&apos;&gt;( An optional description that will be saved to the local address book if entered )&lt;/font&gt;</source>
<translation>ि &lt;font size=&apos;2&apos;&gt;( ि ि ि ि )&lt;/font&gt;</translation>
</message>
<message>
<location filename="../pages/Transfer.qml" line="239"/>
<source>SEND</source>
<translation></translation>
</message>
</context>
<context>
<name>WizardConfigure</name>
<message>
<location filename="../wizard/WizardConfigure.qml" line="79"/>
<source>Were almost there - lets just configure some Monero preferences</source>
<translation> ि - ि Monero ि ि </translation>
</message>
<message>
<location filename="../wizard/WizardConfigure.qml" line="97"/>
<source>Kickstart the Monero blockchain?</source>
<translation>Kickstart the Monero ?</translation>
</message>
<message>
<location filename="../wizard/WizardConfigure.qml" line="115"/>
<source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source>
<translation> ि ि ि ि िि ि ि ि </translation>
</message>
<message>
<location filename="../wizard/WizardConfigure.qml" line="127"/>
<source>Enable disk conservation mode?</source>
<translation>ि ?</translation>
</message>
<message>
<location filename="../wizard/WizardConfigure.qml" line="145"/>
<source>Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as a regular Monero instance. However, storing the full blockchain is beneficial to the security of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.</source>
<translation>ि ि- , ि ि Monero ि ि, Monero ि ि ि ि ि ि </translation>
</message>
<message>
<location filename="../wizard/WizardConfigure.qml" line="158"/>
<source>Allow background mining?</source>
<translation> ि ि ?</translation>
</message>
<message>
<location filename="../wizard/WizardConfigure.qml" line="176"/>
<source>Mining secures the Monero network, and also pays a small reward for the work done. This option will let Monero mine when your computer is on mains power and is idle. It will stop mining when you continue working.</source>
<translation>ि Monero ि , ि ि ि Monero िि ि </translation>
</message>
</context>
<context>
<name>WizardCreateWallet</name>
<message>
<location filename="../wizard/WizardCreateWallet.qml" line="90"/>
<source>A new wallet has been created for you</source>
<translation> ि </translation>
</message>
<message>
<location filename="../wizard/WizardCreateWallet.qml" line="91"/>
<source>This is the 25 word mnemonic for your wallet</source>
<translation> ि 25 </translation>
</message>
</context>
<context>
<name>WizardDonation</name>
<message>
<location filename="../wizard/WizardDonation.qml" line="93"/>
<source>Monero development is solely supported by donations</source>
<translation>Monero ि ि </translation>
</message>
<message>
<location filename="../wizard/WizardDonation.qml" line="113"/>
<source>Enable auto-donations of?</source>
<translation>- ?</translation>
</message>
<message>
<location filename="../wizard/WizardDonation.qml" line="153"/>
<source>% of my fee added to each transaction</source>
<translation>% </translation>
</message>
<message>
<location filename="../wizard/WizardDonation.qml" line="164"/>
<source>For every transaction, a small transaction fee is charged. This option lets you add an additional amount, as a percentage of that fee, to your transaction to support Monero development. For instance, a 50% autodonation take a transaction fee of 0.005 XMR and add a 0.0025 XMR to support Monero development.</source>
<translation> ि ि Monero ि ि ि ि िि ि ि ि, 50% - 0.005 XMR Monero ि ि ि 0.0025 XMR </translation>
</message>
<message>
<location filename="../wizard/WizardDonation.qml" line="176"/>
<source>Allow background mining?</source>
<translation> ि ि ?</translation>
</message>
<message>
<location filename="../wizard/WizardDonation.qml" line="194"/>
<source>Mining secures the Monero network, and also pays a small reward for the work done. This option will let Monero mine when your computer is on mains power and is idle. It will stop mining when you continue working.</source>
<translation>ि Monero ि , ि ि ि Monero िि ि </translation>
</message>
</context>
<context>
<name>WizardFinish</name>
<message>
<location filename="../wizard/WizardFinish.qml" line="41"/>
<source>&lt;b&gt;Language:&lt;/b&gt;</source>
<translation>&lt;b&gt;:&lt;/b&gt;</translation>
</message>
<message>
<location filename="../wizard/WizardFinish.qml" line="42"/>
<source>&lt;b&gt;Account name:&lt;/b&gt; </source>
<translation>&lt;b&gt; :&lt;/b&gt; </translation>
</message>
<message>
<location filename="../wizard/WizardFinish.qml" line="43"/>
<source>&lt;b&gt;Words:&lt;/b&gt; </source>
<translation>&lt;b&gt;:&lt;/b&gt; </translation>
</message>
<message>
<location filename="../wizard/WizardFinish.qml" line="44"/>
<source>&lt;b&gt;Wallet Path: &lt;/b&gt;</source>
<translation>&lt;b&gt; : &lt;/b&gt;</translation>
</message>
<message>
<location filename="../wizard/WizardFinish.qml" line="45"/>
<source>&lt;b&gt;Enable auto donation: &lt;/b&gt;</source>
<translation>&lt;b&gt; : &lt;/b&gt;</translation>
</message>
<message>
<location filename="../wizard/WizardFinish.qml" line="46"/>
<source>&lt;b&gt;Auto donation amount: &lt;/b&gt;</source>
<translation>&lt;b&gt; ि: &lt;/b&gt;</translation>
</message>
<message>
<location filename="../wizard/WizardFinish.qml" line="47"/>
<source>&lt;b&gt;Allow background mining: &lt;/b&gt;</source>
<translation>&lt;b&gt; ि ि : &lt;/b&gt;</translation>
</message>
<message>
<location filename="../wizard/WizardFinish.qml" line="52"/>
<source>An overview of your Monero configuration is below:</source>
<translation> Monero ि :</translation>
</message>
<message>
<location filename="../wizard/WizardFinish.qml" line="107"/>
<source>Youre all setup!</source>
<translation> ि !</translation>
</message>
</context>
<context>
<name>WizardMain</name>
<message>
<location filename="../wizard/WizardMain.qml" line="308"/>
<source>USE MONERO</source>
<translation>MONERO </translation>
</message>
</context>
<context>
<name>WizardManageWalletUI</name>
<message>
<location filename="../wizard/WizardManageWalletUI.qml" line="103"/>
<source>This is the name of your wallet. You can change it to a different name if youd like:</source>
<translation> ि :</translation>
</message>
<message>
<location filename="../wizard/WizardManageWalletUI.qml" line="125"/>
<source>My account name</source>
<translation> </translation>
</message>
<message>
<location filename="../wizard/WizardManageWalletUI.qml" line="175"/>
<source>Your wallet is stored in</source>
<translation> </translation>
</message>
<message>
<location filename="../wizard/WizardManageWalletUI.qml" line="187"/>
<source>Please choose a directory</source>
<translation> िि </translation>
</message>
</context>
<context>
<name>WizardMemoTextInput</name>
<message>
<location filename="../wizard/WizardMemoTextInput.qml" line="76"/>
<source>It is very important to write it down as this is the only backup you will need for your wallet. You will be asked to confirm the seed in the next screen to ensure it has copied down correctly.</source>
<translation> ि ि ि ि िि ि ि ि </translation>
</message>
</context>
<context>
<name>WizardOptions</name>
<message>
<location filename="../wizard/WizardOptions.qml" line="62"/>
<source>Welcome to Monero!</source>
<translation>Monero !</translation>
</message>
<message>
<location filename="../wizard/WizardOptions.qml" line="74"/>
<source>Please select one of the following options:</source>
<translation> ििि ि :</translation>
</message>
<message>
<location filename="../wizard/WizardOptions.qml" line="110"/>
<source>This is my first time, I want to&lt;br/&gt;create a new account</source>
<translation> ि , &lt;br/&gt; </translation>
</message>
<message>
<location filename="../wizard/WizardOptions.qml" line="141"/>
<source>I want to recover my account&lt;br/&gt;from my 24 work seed</source>
<translation> 24 &lt;br/&gt;ि </translation>
</message>
</context>
<context>
<name>WizardPassword</name>
<message>
<location filename="../wizard/WizardPassword.qml" line="51"/>
<source>Now that your wallet has been created, please set a password for the wallet</source>
<translation> ि , ि िि </translation>
</message>
<message>
<location filename="../wizard/WizardPassword.qml" line="53"/>
<source>Now that your wallet has been restored, please set a password for the wallet</source>
<translation> ि ि , ि िि </translation>
</message>
<message>
<location filename="../wizard/WizardPassword.qml" line="135"/>
<source>Note that this password cannot be recovered, and if forgotten you will need to restore your wallet from the mnemonic seed you were just given&lt;br/&gt;&lt;br/&gt;
Your password will be used to protect your wallet and to confirm actions, so make sure that your password is sufficiently secure.</source>
<translation> , ि , ि ि ि &lt;br/&gt;&lt;br/&gt;
ि ि ििि ि ि ि , ि ि </translation>
</message>
</context>
<context>
<name>WizardRecoveryWallet</name>
<message>
<location filename="../wizard/WizardRecoveryWallet.qml" line="78"/>
<source>My account name</source>
<translation> </translation>
</message>
<message>
<location filename="../wizard/WizardRecoveryWallet.qml" line="79"/>
<source>We&apos;re ready to recover your account</source>
<translation> ि ि </translation>
</message>
<message>
<location filename="../wizard/WizardRecoveryWallet.qml" line="80"/>
<source>Please enter your 25 word private key</source>
<translation> 25 </translation>
</message>
</context>
<context>
<name>WizardWelcome</name>
<message>
<location filename="../wizard/WizardWelcome.qml" line="69"/>
<source>Welcome</source>
<translation> </translation>
</message>
<message>
<location filename="../wizard/WizardWelcome.qml" line="82"/>
<source>Please choose a language and regional format.</source>
<translation> </translation>
</message>
</context>
<context>
<name>main</name>
<message>
<location filename="../main.qml" line="148"/>
<location filename="../main.qml" line="203"/>
<location filename="../main.qml" line="233"/>
<source>Error</source>
<translation>ि</translation>
</message>
<message>
<location filename="../main.qml" line="149"/>
<source>Couldn&apos;t open wallet: </source>
<translation> : </translation>
</message>
<message>
<location filename="../main.qml" line="204"/>
<source>Can&apos;t create transaction: </source>
<translation> : </translation>
</message>
<message>
<location filename="../main.qml" line="216"/>
<source>Confirmation</source>
<translation>ि</translation>
</message>
<message>
<location filename="../main.qml" line="217"/>
<source>Please confirm transaction:</source>
<translation> ि :</translation>
</message>
<message>
<location filename="../main.qml" line="218"/>
<source>Address: </source>
<translation>:</translation>
</message>
<message>
<location filename="../main.qml" line="219"/>
<source>Payment ID: </source>
<translation> :</translation>
</message>
<message>
<location filename="../main.qml" line="220"/>
<source>Amount: </source>
<translation>ि:</translation>
</message>
<message>
<location filename="../main.qml" line="221"/>
<source>Fee: </source>
<translation>:</translation>
</message>
<message>
<location filename="../main.qml" line="234"/>
<source>Couldn&apos;t send the money: </source>
<translation> : </translation>
</message>
<message>
<location filename="../main.qml" line="237"/>
<source>Information</source>
<translation></translation>
</message>
<message>
<location filename="../main.qml" line="238"/>
<source>Money sent successfully</source>
<translation> </translation>
</message>
<message>
<location filename="../main.qml" line="310"/>
<source>Initializing Wallet...</source>
<translation> ...</translation>
</message>
<message>
<location filename="../main.qml" line="336"/>
<source>Program setup wizard</source>
<translation> ि</translation>
</message>
<message>
<location filename="../main.qml" line="350"/>
<source>Monero - Donations</source>
<translation>Monero - </translation>
</message>
<message>
<location filename="../main.qml" line="389"/>
<source>send to the same destination</source>
<translation> </translation>
</message>
</context>
</TS>

Some files were not shown because too many files have changed in this diff Show More