Compare commits

...

418 Commits

Author SHA1 Message Date
luigi1111
3c69023135 Merge pull request #3037
67be96e Translations from weblate (Monero-Weblate)
2020-08-08 20:48:31 -05:00
luigi1111
fad8dab165 Merge pull request #3035
9ce88c6 build: prepare v0.16.0.3 (selsta)
2020-08-08 20:46:53 -05:00
Anonymous
67be96e6d5 Translations from weblate
Languages:

- German
Currently translated at 97.2% (669 of 688 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/de/

- Russian
Currently translated at 97.9% (673 of 687 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/ru/

- Romanian
Currently translated at 85.5% (588 of 687 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/ro/

- Czech
Currently translated at 54.1% (372 of 687 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/cs/

-  Chinese (Simplified)
Currently translated at 94.3% (648 of 687 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/zh_Hans/

- Norwegian Bokmål
Currently translated at 90.3% (621 of 687 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/nb_NO/

- Turkish
Currently translated at 82.3% (566 of 687 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/tr/

- Greek
Currently translated at 46.5% (320 of 687 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/el/

- Japanese
Currently translated at 86.8% (597 of 687 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/ja/

- Italian
Currently translated at 92.2% (632 of 685 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/it/

  All languages were updated:

    Found 690 source text(s) (12 new and 678 already existing)
    Removed 9 obsolete entries

  Translators:

* Italian

    * 8uDD4T
    * erciccione

* Romanian

    * Marius Tanislav

* Turkish

    * xmoreee

* Japanese

    * Lana

* French

    * Anonymous

* Czech

    * Michal Poupe
    * dskch83

* Chinese (Simplified)

    * anony_xmr
    * C3Pool
    * Muge Niu
    * Anonymous
    * razorshaman909

* Greek

    * Stavros
    * warraxxx
    * Georgios Apostolopoulos

* Norwegian Bokmål

    * bitbooz

Co-authored-by: GreenPiece <villa@posteo.net>
Co-authored-by: v1docq47 <chiptune@protonmail.ch>
Co-authored-by: Agent LvM <agent.lvm@gmail.com>
Co-authored-by: dskch83 <skarkadaniel@gmail.com>
Co-authored-by: razorshaman909 <work909ang@gmail.com>
Co-authored-by: Muge Niu <mugeniu12138@gmail.com>
Co-authored-by: C3Pool <hkfoan@gmail.com>
Co-authored-by: xmoreee <sskacarfun@gmail.com>
Co-authored-by: warraxxx <kpantelidis@hotmail.gr>
Co-authored-by: 8uDD4T <8uDD4T@protonmail.com>
2020-08-06 12:30:49 +02:00
selsta
9ce88c6aeb build: prepare v0.16.0.3 2020-08-05 14:24:27 +02:00
luigi1111
7eeda0a8f0 Merge pull request #3031
d1bde4f workflows: fix mac cmake (selsta)
2020-07-29 13:46:44 -05:00
luigi1111
9220937c4b Merge pull request #3027
0db4c36 QrScanThread: fix Qt 5.15 compability (selsta)
2020-07-29 13:35:36 -05:00
luigi1111
6aaf294f0b Merge pull request #3019
dcc040a WalletManager: instantiable QML type (xiphon)
2020-07-29 13:34:33 -05:00
luigi1111
721a0cbf91 Merge pull request #3018
352da92 QrCodeScanner: use parse_uri_to_object to parse scanned codes (xiphon)
2020-07-29 13:33:27 -05:00
selsta
d1bde4f8b2 workflows: fix mac cmake 2020-07-29 20:30:06 +02:00
selsta
0db4c36db0 QrScanThread: fix Qt 5.15 compability 2020-07-29 17:40:58 +02:00
xiphon
dcc040a119 WalletManager: instantiable QML type 2020-07-29 15:17:02 +00:00
luigi1111
63e32c4a83 Merge pull request #3017
99907e5 WalletManager: parse_uri_to_object extra parameters support (xiphon)
2020-07-29 09:53:31 -05:00
luigi1111
7972d8a219 Merge pull request #3015
e8bcabe cmake: fix static libraries linking (xiphon)
2020-07-29 09:50:05 -05:00
luigi1111
872b81fe39 Merge pull request #3014
829414e Transfer: fix 'Send' and 'Sweep' functionality (xiphon)
2020-07-29 09:49:04 -05:00
luigi1111
6136e88fcb Merge pull request #3013
085abb7 cmake: fix MacOS build (Qt installer) (xiphon)
2020-07-29 09:47:21 -05:00
luigi1111
c77637d141 Merge pull request #3012
410897c SettingsLog: add command history (rating89us)
2020-07-29 09:46:04 -05:00
luigi1111
0d047035fb Merge pull request #3007
13ee9b1 KeysFiles: fix WalletKeysFilesModel, should be instantiable QML type (xiphon)
2020-07-29 09:44:45 -05:00
luigi1111
b5aa659757 Merge pull request #3004
36262f0 version: use MONERO_VERSION_FULL const as monero core version (xiphon)
2020-07-29 09:42:24 -05:00
luigi1111
88d297d8cc Merge pull request #3002
f78c95b cmake: build bundle on macOS (selsta)
2020-07-29 09:38:55 -05:00
xiphon
352da92229 QrCodeScanner: use parse_uri_to_object to parse scanned codes 2020-07-16 17:30:00 +00:00
xiphon
99907e539a WalletManager: parse_uri_to_object extra parameters support 2020-07-16 17:28:00 +00:00
xiphon
e8bcabe66b cmake: fix static libraries linking 2020-07-15 23:26:14 +00:00
xiphon
829414ed01 Transfer: fix 'Send' and 'Sweep' functionality 2020-07-15 04:02:42 +00:00
xiphon
36262f029a version: use MONERO_VERSION_FULL const as monero core version 2020-07-15 03:45:03 +00:00
xiphon
13ee9b1f26 KeysFiles: fix WalletKeysFilesModel, should be instantiable QML type 2020-07-14 23:44:46 +00:00
xiphon
085abb798a cmake: fix MacOS build (Qt installer) 2020-07-14 23:36:30 +00:00
luigi1111
c137a6ea36 Merge pull request #3010
2fd3974 WalletManager: displayAmount should be static (xiphon)
2020-07-14 15:51:01 -05:00
luigi1111
2cea0fc669 Merge pull request #3009
7c50e1f PasswordDialog: focus on gui start (selsta)
2020-07-14 15:50:14 -05:00
luigi1111
aaa1cb47c0 Merge pull request #3006
dec5dcf KeysFiles: don't use WalletManager in findWallets (xiphon)
2020-07-14 15:49:19 -05:00
luigi1111
1577ce278b Merge pull request #3001
df885b6 cmake: set current monero-gui version (selsta)
2020-07-14 15:48:15 -05:00
luigi1111
9d48f96fc8 Merge pull request #2999
b22fb24 Donate to Monero feature (xmrdsc)
2020-07-14 15:47:29 -05:00
luigi1111
1a51e93e55 Merge pull request #2991
c9d36b1 cmake: translations deps handling, build translations as a library (xiphon)
d931022 cmake: implement MacOS 'release' build + CI support (xiphon)
2020-07-14 15:46:09 -05:00
luigi1111
b62b821002 Merge pull request #2989
8c8faf2 Support comma seperator for amount field, dynamically change to dot. Fixes #2951 (xmrdsc)
2020-07-14 15:45:01 -05:00
luigi1111
f3ee46175c Merge pull request #2935
f1e3926 WizardWalletInput: disallow (back)slash (selsta)
2020-07-14 15:43:58 -05:00
luigi1111
17a3c51a43 Merge pull request #2915
527adcb Utils: simplify for translations (selsta)
2020-07-14 15:43:08 -05:00
rating89us
410897ced7 SettingsLog: add command history 2020-07-14 22:38:54 +02:00
xiphon
2fd3974194 WalletManager: displayAmount should be static 2020-07-14 17:10:25 +00:00
selsta
7c50e1ff4b PasswordDialog: focus on gui start 2020-07-14 16:52:40 +02:00
xiphon
dec5dcf25c KeysFiles: don't use WalletManager in findWallets 2020-07-14 01:39:46 +00:00
xiphon
c9d36b1302 cmake: translations deps handling, build translations as a library 2020-07-09 16:42:32 +00:00
xiphon
d931022963 cmake: implement MacOS 'release' build + CI support 2020-07-09 15:23:04 +00:00
selsta
df885b6eaa cmake: set current monero-gui version 2020-07-09 08:13:08 +02:00
selsta
f78c95b73b cmake: build bundle on macOS 2020-07-09 08:12:36 +02:00
dsc
b22fb24e47 Donate to Monero feature 2020-07-08 22:50:48 +02:00
dsc
8c8faf29e4 Support comma seperator for amount field, dynamically change to dot. Fixes #2951 2020-07-08 22:14:28 +02:00
luigi1111
b7b1221221 Merge pull request #2997
f1b4eb6 history: remove trailing zeros in amount + fix amount display (rating89us)
2020-07-08 13:57:44 -05:00
luigi1111
38c3534ead Merge pull request #2996
d37c4dd history: fix search filter not working when there is a pending transaction (rating89us)
2020-07-08 13:56:35 -05:00
luigi1111
f631b75f0a Merge pull request #2994
50c22ca Mining: Indicate probability of finding a block in one day (glv2)
2020-07-08 13:55:27 -05:00
luigi1111
11fd19e0f8 Merge pull request #2988
2522ff1 Prevent textbox from turning active when window is not active. Fixes #2924 (xmrdsc)
2020-07-08 13:53:41 -05:00
luigi1111
1572b4cf79 Merge pull request #2978
fead82b RemoteNodeEdit: initialAddress, add square brackets on ipv6 input (xiphon)
2020-07-08 13:52:22 -05:00
luigi1111
10a47d783e Merge pull request #2977
f55bf48 cmake: fix git tag + commit detection and version.js generation (xiphon)
2020-07-08 13:51:19 -05:00
luigi1111
14cc1d096a Merge pull request #2976
a00ed6a cmake: implement translations support (xiphon)
2020-07-08 13:50:18 -05:00
luigi1111
840421fd7b Merge pull request #2974
7677103 docker: implement Docker Linux 'release-static' build (xiphon)
2020-07-08 13:49:07 -05:00
luigi1111
51739dfb22 Merge pull request #2949
1edc068 PasswordDialog: remove already defined z value (selsta)
2020-07-08 13:36:52 -05:00
luigi1111
be5e6772a4 Merge pull request #2948
53066ae QML: fix some Qt 5.15 warnings (selsta)
2020-07-08 13:35:55 -05:00
luigi1111
c869390272 Merge pull request #2940
c672d80 docs: add deploy readme (selsta)
2020-07-08 13:34:46 -05:00
Guillaume Le Vaillant
50c22ca300 Mining: Indicate probability of finding a block in one day 2020-07-08 19:30:27 +02:00
rating89us
f1b4eb6c56 history: remove trailing zeros in amount + fix amount display 2020-07-08 15:05:11 +02:00
rating89us
d37c4ddef2 history: fix search filter not working when there is a pending transaction 2020-07-08 15:01:19 +02:00
dsc
2522ff13fe Prevent textbox from turning active when window is not active. Fixes #2924 2020-07-07 15:33:54 +02:00
luigi1111
596b71b293 Merge pull request #2982
8159b75 cmake: fix monero-wallet-gui target dependencies (xiphon)
2020-07-05 23:45:33 -05:00
xiphon
8159b75be3 cmake: fix monero-wallet-gui target dependencies 2020-07-02 23:32:55 +00:00
xiphon
7677103f1b docker: implement Docker Linux 'release-static' build 2020-07-02 18:13:51 +00:00
xiphon
fead82b198 RemoteNodeEdit: initialAddress, add square brackets on ipv6 input 2020-07-02 13:39:56 +00:00
xiphon
f55bf48bad cmake: fix git tag + commit detection and version.js generation 2020-07-01 01:48:52 +00:00
luigi1111
e0faddf964 Merge pull request #2975
b54127e main: disable NetworkAccessBlockingFactory.h if Qt < 5.12 (selsta)
2020-06-30 14:43:32 -05:00
xiphon
a00ed6a75a cmake: implement translations support 2020-06-30 17:07:35 +00:00
selsta
b54127e997 main: disable NetworkAccessBlockingFactory.h if Qt < 5.12
Due to a potential Qt bug qrc:///lang/languages.xml gets
blocked resulting in broken translations.
2020-06-30 04:21:14 +02:00
selsta
c672d8016d docs: add deploy readme 2020-06-30 01:53:35 +02:00
luigi1111
ccd8eb1c3a Merge pull request #2967
1c62ede Revert 'main: update balance only when wallet is synced' (selsta)
2020-06-24 13:36:53 -05:00
luigi1111
d5b165bde2 Merge pull request #2966
34439af build: set submodule to v0.16.0.1 (selsta)
2020-06-24 13:34:33 -05:00
luigi1111
c978027933 Merge pull request #2964
e1e862b cmake: implement Linux 'release-static' build target (xiphon)
2020-06-24 13:10:35 -05:00
luigi1111
9deec4dad0 Merge pull request #2957
749460f README: update donation fund address (selsta)
2020-06-24 13:08:55 -05:00
luigi1111
e306992ce8 Merge pull request #2955
f64dcde simple mode: enable settings log tab (selsta)
2020-06-24 13:07:53 -05:00
luigi1111
19daa074ca Merge pull request #2909
66e7696 QML: disable networking (selsta)
2020-06-24 13:06:57 -05:00
selsta
1c62edeff4 Revert "main: update balance only when wallet is synced"
This reverts commit 333c9ee311.
2020-06-24 04:02:27 +02:00
selsta
34439af67e build: set submodule to v0.16.0.1 2020-06-24 03:59:45 +02:00
xiphon
e1e862bce4 cmake: implement Linux 'release-static' build target 2020-06-21 02:03:26 +00:00
luigi1111
0b2e74cdb5 Merge pull request #2963
a3fc675 cmake: fix x11 linking (xiphon)
2020-06-19 16:58:28 -05:00
luigi1111
3fee17e564 Merge pull request #2933
1e7d829 openpgp: fix gcc 5.4.0 compilation (xiphon)
2020-06-19 16:56:05 -05:00
xiphon
1e7d8293cb openpgp: fix gcc 5.4.0 compilation 2020-06-19 21:53:47 +00:00
xiphon
a3fc6754e0 cmake: fix x11 linking 2020-06-19 21:50:42 +00:00
luigi1111
8354c251c5 Merge pull request #2962
27532dc cmake: fix USE_DEVICE_TREZOR option (xiphon)
2020-06-19 16:16:57 -05:00
luigi1111
8f5053bd61 Merge pull request #2961
52c090b cmake: downgrade minimum required boost version to 1.58 (xiphon)
2020-06-19 16:16:08 -05:00
luigi1111
92b0a115f4 Merge pull request #2959
c0e0626 SettingsLayout: ask password for password relevant setting (selsta)
2020-06-19 16:15:20 -05:00
luigi1111
6a3e1aaf40 Merge pull request #2950
d18af7d LeftPanel: simpifly color binding (selsta)
2020-06-19 16:14:31 -05:00
luigi1111
c32e11d3e8 Merge pull request #2947
333c9ee main: update balance only when wallet is synced (rating89us)
2020-06-19 16:13:48 -05:00
luigi1111
9580c19da3 Merge pull request #2937
c6d5c5d workflows: update msys2 setup action v0 -> v1 (selsta)
2020-06-19 16:12:52 -05:00
xiphon
27532dc1bf cmake: fix USE_DEVICE_TREZOR option 2020-06-17 14:04:35 +00:00
selsta
c0e0626b84 SettingsLayout: ask password for password relevant setting 2020-06-17 10:01:42 +02:00
selsta
c6d5c5dc3a workflows: update msys2 setup action v0 -> v1 2020-06-15 23:07:48 +02:00
selsta
749460fb46 README: update donation fund address 2020-06-15 22:23:19 +02:00
luigi1111
c9ee76c2ee Merge pull request #2943
ef5d855 openpgp: implement public subkeys support (xiphon)
2020-06-15 15:11:56 -05:00
luigi1111
94dbf179d5 Merge pull request #2942
ff4de8e updater: use monero tools::sha256sum (xiphon)
2020-06-15 15:10:47 -05:00
luigi1111
7deecbfdf6 Merge pull request #2941
e6f3057 windeploy_helper: add libgcrypt and update 65 -> 67 (selsta)
2020-06-15 15:09:58 -05:00
luigi1111
29a742ba26 Merge pull request #2928
7f0c199 workflows: Windows CMake 'release-win64' target CI (xiphon)
2020-06-15 15:09:08 -05:00
luigi1111
47559e51be Merge pull request #2927
1580c3a DaemonManager: remove max-concurrency upper bound (selsta)
2020-06-15 15:07:59 -05:00
selsta
f64dcde600 simple mode: enable settings log tab 2020-06-15 13:17:42 +02:00
xiphon
52c090b82f cmake: downgrade minimum required boost version to 1.58 2020-06-14 12:30:40 +00:00
selsta
1edc068047 PasswordDialog: remove already defined z value
main already defines z
2020-06-13 04:47:17 +02:00
selsta
d18af7da72 LeftPanel: simpifly color binding 2020-06-13 03:34:16 +02:00
selsta
53066ae92b QML: fix some Qt 5.15 warnings 2020-06-12 03:10:32 +02:00
rating89us
333c9ee311 main: update balance only when wallet is synced 2020-06-12 00:08:04 +02:00
xiphon
ff4de8e8f7 updater: use monero tools::sha256sum 2020-06-10 15:11:15 +00:00
xiphon
ef5d855950 openpgp: implement public subkeys support 2020-06-10 12:48:55 +00:00
selsta
e6f30578c0 windeploy_helper: add libgcrypt and update 65 -> 67 2020-06-10 00:38:07 +02:00
selsta
f1e3926192 WizardWalletInput: disallow (back)slash 2020-06-04 18:33:07 +02:00
xiphon
7f0c19950b workflows: Windows CMake 'release-win64' target CI 2020-06-04 00:30:47 +00:00
selsta
1580c3a574 DaemonManager: remove max-concurrency upper bound 2020-05-29 13:58:53 +02:00
luigi1111
c8f4355e15 Merge pull request #2926
39561f8 cmake: workflows: implement 'release' Linux build target + CI (xiphon)
2020-05-28 12:55:08 -05:00
xiphon
39561f8ead cmake: workflows: implement 'release' Linux build target + CI 2020-05-28 14:51:52 +00:00
luigi1111
b15dbbb9b0 Merge pull request #2921
55cbc56 workflows: fix windows build (selsta)
2020-05-26 15:40:24 -05:00
luigi1111
a73a4363ec Update submodule to recent master (77a008f) 2020-05-26 13:10:17 -05:00
selsta
55cbc562b6 workflows: fix windows build 2020-05-24 23:34:31 +02:00
luigi1111
e6c4c32d01 Merge pull request #2919
c946905 OpenGL: Windows - fall back to software renderer if OpenGL < 2.1 (xiphon)
2020-05-21 12:42:00 -05:00
luigi1111
e36d4a918f Merge pull request #2917
43f0854 Translations from Weblate (Monero-Weblate)
2020-05-21 12:40:51 -05:00
luigi1111
0355ca2747 Merge pull request #2916
f38e460 build: set submodule to v0.16.0.0 (selsta)
2020-05-21 12:39:34 -05:00
xiphon
c946905907 OpenGL: Windows - fall back to software renderer if OpenGL < 2.1 2020-05-20 13:45:16 +00:00
luigi1111
a8bd2ab77e Merge pull request #2913
0de1ba9 Windows installer: Update for Nitrogen Nebula 0.16.0.0 (rbrunner7)
2020-05-18 12:30:09 -05:00
luigi1111
149e373367 Merge pull request #2912
1503885 cmake: always link libgcc, libstdc++ statically (xiphon)
2020-05-18 12:29:15 -05:00
luigi1111
fa3c8b5f89 Merge pull request #2911
754a968 build: release-win64 support (xiphon)
2020-05-18 12:28:20 -05:00
luigi1111
e0f6577afd Merge pull request #2910
efc9ad4 cmake: fix Qt 5.14+ build, link Qt5QmlModels if available (xiphon)
2020-05-18 12:26:49 -05:00
Anonymous
43f0854de9 Translations from Weblate
Credits:

* Ukrainian

    * reketen
    * TheFuzzStone

* Spanish

    * Michael Russo
    * kombometralla
    * CharlesCrisco
    * Anonymous
    * porokon7
    * Juanpaab

* Korean

    * enaSo97

* Croatian

    * TasmaniaKrama

* Finnish

    * vaa red

* Italian

    * 8uDD4T
    * Anonymous

* Chinese (Traditional)

    * Lafudoci

* Esperanto

    * Gilberto F da Silva

* Romanian

    * Marius Tanislav
    * Anonymous
    * Vlad G.

* Russian

    * Agent LvM
    * solevoy-psih
    * v1docq47
    * TheFuzzStone
    * Russian Bear
    * translator133

* Japanese

    * Scott Anecito

* Portuguese (Portugal)

    * Anonymous

* French

    * Anonymous
    * Viktor

* Czech

    * Anonymous

* Chinese (Simplified)

    * jindouyunz
    * anony_xmr
    * tan
    * Muge Niu
    * Anonymous
    * TE Scott
    * razorshaman909

* Bulgarian

    * Weblate Admin

* Arabic

    * Weblate Admin

* Slovenian

    * Matija Mazi

* Polish

    * To Ja
    * Anonymous

* Portuguese (Brazil)

    * ANMNQ
    * Nelson Renan
    * netrik182
    * Anonymous
    * Boçogrolho Tabúrcio Mendez
    * Asdrubal Petronidas Calhofos

* Norwegian Bokmål

    * bitbooz
    * Anonymous

* Dutch

    * Marcus

* Swedish

    * B
    * peter hermansson

* Danish

    * KforG
    * Poul
    * Anonymous

* German

    * Wobole
    * Anonymous
    * René Brunner
    * GreenPiece
2020-05-18 09:42:46 +00:00
selsta
f38e460842 build: set submodule to v0.16.0.0 2020-05-18 01:40:53 +02:00
selsta
527adcba17 Utils: simplify for translations 2020-05-16 18:11:39 +02:00
René Brunner
0de1ba9f51 Windows installer: Update for Nitrogen Nebula 0.16.0.0 2020-05-15 15:09:40 +02:00
selsta
66e769603c QML: disable networking 2020-05-15 06:21:08 +02:00
xiphon
15038850c2 cmake: always link libgcc, libstdc++ statically 2020-05-15 02:28:47 +00:00
xiphon
efc9ad45e4 cmake: fix Qt 5.14+ build, link Qt5QmlModels if available 2020-05-15 02:27:09 +00:00
xiphon
754a968706 build: release-win64 support 2020-05-15 02:24:14 +00:00
luigi1111
c20a0ef928 Merge pull request #2908
210248e cmake: disable '-pie' on Win with gcc (xiphon)
2020-05-14 16:06:39 -05:00
luigi1111
eab98e3a48 Merge pull request #2906
da4e0db cmake: rename monero-gui binary to monero-wallet-gui (xiphon)
2020-05-14 16:05:53 -05:00
luigi1111
2a8960bc2c Merge pull request #2905
f82948f cmake: drop '-std=c++0x' compiler flag (xiphon)
2020-05-14 16:05:04 -05:00
luigi1111
fe68f59763 Merge pull request #2903
9dd3f4f add isTrezor() function (rating89us)
2020-05-14 16:04:17 -05:00
luigi1111
80e8dd6aef Merge pull request #2901
72a3b34 Merchant: allow to exit when height < minHeight (selsta)
2020-05-14 16:03:22 -05:00
luigi1111
c82bd94bc3 Merge pull request #2899
abbe042 Filter out multiple blanks in seed input when counting words (rbrunner7)
2020-05-14 16:02:27 -05:00
luigi1111
28ca9503df Merge pull request #2897
d662e46 Merchant: display size warning when height < minHeight (rating89us)
2020-05-14 16:01:28 -05:00
luigi1111
73cc400ae8 Merge pull request #2896
bbc9ca8 Transfer: fix html paragraph tag (rating89us)
2020-05-14 16:00:43 -05:00
luigi1111
8b7438ace2 Merge pull request #2894
f7271d1 SettingsNode: add translation to Address and Port strings (rating89us)
2020-05-14 15:59:40 -05:00
xiphon
210248e6ef cmake: disable '-pie' on Win with gcc 2020-05-14 18:48:08 +00:00
xiphon
f82948f4b0 cmake: drop '-std=c++0x' compiler flag 2020-05-13 14:29:01 +00:00
xiphon
da4e0dbf0f cmake: rename monero-gui binary to monero-wallet-gui 2020-05-13 14:26:14 +00:00
rating89us
9dd3f4fecb add isTrezor() function 2020-05-13 13:22:49 +02:00
rbrunner7
abbe042c8a Filter out multiple blanks in seed input when counting words 2020-05-13 07:51:31 +02:00
selsta
72a3b346bb Merchant: allow to exit when height < minHeight 2020-05-12 20:43:46 +02:00
rating89us
d662e46146 Merchant: display size warning when height < minHeight 2020-05-11 00:42:45 +02:00
rating89us
bbc9ca8f08 Transfer: fix html paragraph tag 2020-05-10 23:48:48 +02:00
rating89us
f7271d1c7b SettingsNode: add translation to Address and Port strings 2020-05-09 19:31:36 +02:00
luigi1111
afe1ae9b9c Merge pull request #2892
b616a14 LanguageSidebar: fix white theme (selsta)
2020-05-08 12:27:37 -05:00
luigi1111
7f5b8ea0ad Merge pull request #2890
2f8c0ca Main: clear spendable funds message when closing wallet (rating89us)
2020-05-08 12:26:24 -05:00
luigi1111
aa5000f556 Merge pull request #2876
4354a76 StandardDropdown: drop Qt 5.8 workaround (xiphon)
2020-05-08 12:25:15 -05:00
luigi1111
8b6978b2a5 Merge pull request #2829
86d21a3 trezor: support new passphrase entry mechanism (ph4r05)
2020-05-08 12:21:59 -05:00
Dusan Klinec
86d21a34ba trezor: support new passphrase entry mechanism
- passphrase can be prompted also when wallet is running (thus added to the wallet listener)
- device/host decision is now made on the host
2020-05-08 18:40:17 +02:00
xiphon
4354a76df9 StandardDropdown: drop Qt 5.8 workaround 2020-05-07 21:55:44 +00:00
selsta
b616a14f88 LanguageSidebar: fix white theme 2020-05-07 21:04:03 +02:00
luigi1111
7536e922e9 Merge pull request #2885
8f70fb4 Transfer: improve warning message while connecting (selsta)
2020-05-07 10:49:44 -05:00
luigi1111
5bf0dd9684 Merge pull request #2884
c439d68 main: fix local node status check on closing uninitialized wallet (xiphon)
2020-05-07 10:31:35 -05:00
luigi1111
cdf4ce2d6f Merge pull request #2891
37a8bcb SimpleMode: use connection timer 'running' prop, fix daemon restart (xiphon)
2020-05-07 10:30:13 -05:00
xiphon
37a8bcb525 SimpleMode: use connection timer 'running' prop, fix daemon restart 2020-05-07 13:40:43 +00:00
rating89us
2f8c0ca499 Main: clear spendable funds message when closing wallet 2020-05-06 19:18:55 +02:00
luigi1111
38612c1285 Merge pull request #2881
487e706 Improved daemon sync progress bar (rbrunner7)
2020-05-06 00:41:41 -05:00
luigi1111
1d3a201077 Merge pull request #2879
ca79525 Slider component (xiphon)
503c1af SettingsLayout: implement autosave, enabled by default (10 minutes) (xiphon)
2020-05-06 00:40:36 -05:00
luigi1111
a91a4f51ab Merge pull request #2871
7db5de0 WizardAskPassword: drop custom password fields, use LineEdit (xiphon)
2020-05-06 00:39:26 -05:00
luigi1111
52fbbae484 Merge pull request #2883
f26f146 PasswordDialog: fix focus on open (selsta)
2020-05-06 00:38:20 -05:00
selsta
8f70fb4f79 Transfer: improve warning message while connecting 2020-05-05 13:12:10 +02:00
xiphon
c439d6814b main: fix local node status check on closing uninitialized wallet 2020-05-04 14:48:56 +00:00
selsta
f26f1469ca PasswordDialog: fix focus on open 2020-05-03 15:51:46 +02:00
rbrunner7
487e706f06 Improved daemon sync progress bar 2020-05-02 16:34:54 +02:00
xiphon
503c1af5f8 SettingsLayout: implement autosave, enabled by default (10 minutes) 2020-05-02 01:54:11 +00:00
xiphon
ca79525fdb Slider component 2020-05-02 01:54:05 +00:00
xiphon
7db5de082d WizardAskPassword: drop custom password fields, use LineEdit 2020-05-02 01:32:35 +00:00
luigi1111
ce6cc47afe Merge pull request #2845
7f9b28c WizardNav: use PageIndicator in wizardProgress (rating89us)
2020-05-01 15:51:48 -05:00
luigi1111
a10a94f51c Merge pull request #2866
5265e52 ProcessingSplash: new design (selsta)
2020-05-01 15:11:43 -05:00
luigi1111
1833c16e39 Merge pull request #2785
be954cc StandardDropdown: fix margins, text overlapping (xiphon)
2020-05-01 15:10:49 -05:00
luigi1111
d7207bfde3 Merge pull request #2874
387e643 Transfer: fix 'call method estimateTransactionFeeAsync of undefined' (xiphon)
2020-05-01 15:09:49 -05:00
selsta
5265e52b8b ProcessingSplash: new design 2020-05-01 22:09:27 +02:00
luigi1111
b6fdb709ba Merge pull request #2873
4a7ccd8 SettingsLayout: add check for updates checkbox (selsta)
2020-05-01 15:07:50 -05:00
luigi1111
9aef3bab33 Merge pull request #2870
2195c67 LineEdit: password mode, linking. PasswordDialog: use LineEdit (xiphon)
2020-05-01 15:06:46 -05:00
luigi1111
4b55197e18 Merge pull request #2848
c7f9ac9 LanguageSidebar: reenable (selsta)
3835387 wizard: add flags to language sidebar (mmbyday, selsta)
2020-05-01 15:04:55 -05:00
luigi1111
11617d2f76 Merge pull request #2846
2102e4b Merchant: fix confirmations (selsta)
b245d0a MerchantTrackingList: point out unconfirmed amount (selsta)
07ecca5 Merchant: fix payment URL (selsta)
3af99e9 Merchant: remove unused variables (selsta)
2020-05-01 15:03:04 -05:00
luigi1111
765e93cfd0 Merge pull request #2840
d31e661 Transfer: redesign advanced options (rating89us)
2020-05-01 14:58:56 -05:00
rating89us
d31e661cd1 Transfer: redesign advanced options 2020-05-01 11:48:53 +02:00
rating89us
7f9b28c05f WizardNav: use PageIndicator in wizardProgress 2020-05-01 11:40:47 +02:00
selsta
4a7ccd8d82 SettingsLayout: add check for updates checkbox 2020-05-01 03:46:58 +02:00
xiphon
be954cc2c4 StandardDropdown: fix margins, text overlapping 2020-05-01 01:30:40 +00:00
xiphon
387e643ae9 Transfer: fix 'call method estimateTransactionFeeAsync of undefined' 2020-04-29 22:33:08 +00:00
luigi1111
6f71d47806 Merge pull request #2868
5c13624 DaemonManager: drop unused 'initialized', 'm_has_daemon' members (xiphon)
2020-04-28 21:41:19 -05:00
luigi1111
135c970ad9 Merge pull request #2865
cfdba59 Wallet: implement async wallet storing (xiphon)
2020-04-28 21:40:17 -05:00
luigi1111
fd5d1f584e Merge pull request #2861
4b0dcb9 StandardDialog: reset button text on close (selsta)
2020-04-28 21:38:59 -05:00
xiphon
2195c67f58 LineEdit: password mode, linking. PasswordDialog: use LineEdit 2020-04-28 20:44:53 +00:00
xiphon
5c13624596 DaemonManager: drop unused 'initialized', 'm_has_daemon' members 2020-04-28 20:42:23 +00:00
xiphon
cfdba59584 Wallet: implement async wallet storing 2020-04-28 20:36:22 +00:00
luigi1111
4141832a4d Merge pull request #2869
3d24300 SettingsNode: forbid 'data-dir', 'bootstrap-daemon-address' flags (xiphon)
2020-04-28 15:24:11 -05:00
luigi1111
5f183da6e3 Merge pull request #2867
9748974 DaemonManager: fix memory leak (xiphon)
2020-04-28 15:23:03 -05:00
luigi1111
30c54b1c6e Merge pull request #2864
ce4cb65 WizardAskPassword: hide strength if getPasswordStrength is missing (xiphon)
2020-04-28 15:22:02 -05:00
luigi1111
c1da3d1c97 Merge pull request #2863
120b528 WizardDaemonSettings: bootstrap node address 'auto' special case (xiphon)
2020-04-28 15:21:19 -05:00
luigi1111
cbd03229dd Merge pull request #2862
33c1a6f repo: cleanup unused images (selsta)
2020-04-28 15:20:22 -05:00
luigi1111
2fc1b287dd Merge pull request #2860
fdb7f80 SettingsInfo: fix number string formatting (selsta)
2020-04-28 15:19:36 -05:00
luigi1111
7c8c6a116f Merge pull request #2856
a810bf3 CheckBox: add enabled property (selsta)
2020-04-28 15:18:51 -05:00
luigi1111
ef93139a80 Merge pull request #2855
b022735 main: add --disable-check-updates flag (selsta)
2020-04-28 15:17:57 -05:00
luigi1111
1b7844ec34 Merge pull request #2854
a99eef6 always use native directory separators in paths (xiphon)
2020-04-28 15:16:57 -05:00
luigi1111
8f63e8870f Merge pull request #2851
7ebdb88 README: list libgcrypt linux (selsta)
2020-04-28 15:16:10 -05:00
luigi1111
286c75aa5b Merge pull request #2850
9b98e0a checkUpates: installer support (Win), use GUI buildTag and version (xiphon)
2020-04-28 15:14:40 -05:00
luigi1111
0a4d65dd99 Merge pull request #2849
02eec35 src: fix qt 5.15 warnings (selsta)
2020-04-28 15:13:45 -05:00
luigi1111
83ccadb6a8 Merge pull request #2847
238b1b7 pages: remove legacy code (selsta)
2020-04-28 15:12:57 -05:00
luigi1111
eae7eff9db Merge pull request #2844
81d5dd1 Transfer: add offline transaction signing info in send button warning (rating89us)
2020-04-28 15:11:58 -05:00
selsta
2102e4be0d Merchant: fix confirmations 2020-04-28 19:30:22 +02:00
selsta
02eec351b9 src: fix qt 5.15 warnings 2020-04-28 19:00:53 +02:00
xiphon
ce4cb6512d WizardAskPassword: hide strength if getPasswordStrength is missing 2020-04-28 15:05:43 +00:00
xiphon
3d24300963 SettingsNode: forbid 'data-dir', 'bootstrap-daemon-address' flags 2020-04-27 13:18:23 +00:00
xiphon
9748974ce0 DaemonManager: fix memory leak 2020-04-27 12:46:15 +00:00
xiphon
120b5285fb WizardDaemonSettings: bootstrap node address "auto" special case 2020-04-26 01:14:29 +00:00
selsta
b022735506 main: add --disable-check-updates flag 2020-04-26 02:57:35 +02:00
selsta
33c1a6f4fc repo: cleanup unused images 2020-04-26 02:18:35 +02:00
selsta
4b0dcb95bf StandardDialog: reset button text on close 2020-04-25 21:10:25 +02:00
selsta
fdb7f806fa SettingsInfo: fix number string formatting 2020-04-25 20:55:32 +02:00
selsta
a810bf3eb7 CheckBox: add enabled property 2020-04-24 04:35:21 +02:00
xiphon
a99eef68f5 always use native directory separators in paths 2020-04-24 00:43:40 +00:00
selsta
7ebdb884a1 README: list libgcrypt linux 2020-04-23 23:31:43 +02:00
selsta
c7f9ac926b LanguageSidebar: reenable 2020-04-23 20:28:09 +02:00
xiphon
9b98e0a2f5 checkUpates: installer support (Win), use GUI buildTag and version 2020-04-23 16:08:10 +00:00
mmbyday
3835387eea wizard: add flags to language sidebar 2020-04-23 00:04:07 +02:00
selsta
238b1b777f pages: remove legacy code 2020-04-22 23:18:08 +02:00
selsta
3af99e91e4 Merchant: remove unused variables 2020-04-22 22:10:40 +02:00
selsta
07ecca5af4 Merchant: fix payment URL
This would previously get loaded on the Receive page.
2020-04-22 22:10:40 +02:00
selsta
b245d0af7a MerchantTrackingList: point out unconfirmed amount 2020-04-22 22:10:40 +02:00
luigi1111
585fb2810d Merge pull request #2843
5076757 SettingsLog: don't assign color to font family (selsta)
2020-04-22 13:37:34 -05:00
luigi1111
0784532001 Merge pull request #2842
1d5b940 Merchant: fix close button (selsta)
2020-04-22 13:36:37 -05:00
luigi1111
dcbdae0954 Merge pull request #2841
3563d44 Transfer: move address field to the top (rating89us)
2020-04-22 13:35:49 -05:00
luigi1111
2bef74fe8a Merge pull request #2838
ffceda9 SettingsLayout: add checkbox 'ask for password before sending a transaction' (rating89us)
2020-04-22 13:34:47 -05:00
rating89us
81d5dd1cae Transfer: add offline transaction signing info in send button warning 2020-04-21 20:57:55 +02:00
selsta
50767570f0 SettingsLog: don't assign color to font family 2020-04-21 20:02:23 +02:00
selsta
1d5b940349 Merchant: fix close button 2020-04-21 19:42:05 +02:00
rating89us
3563d44d99 Transfer: move address field to the top 2020-04-18 19:25:45 +02:00
rating89us
ffceda9159 SettingsLayout: add checkbox 'ask for password before sending a transaction' 2020-04-18 17:42:27 +02:00
luigi1111
a75a0fb8c5 Merge pull request #2839
fee81ba workflows: add trezor support ubuntu (selsta)
2020-04-17 22:10:21 -05:00
luigi1111
5fa64c34ec Merge pull request #2831
de6a9b6 Transfer: address book inline button, 2nd inline button, scan QR code button fixes (rating89us)
2020-04-17 22:09:18 -05:00
luigi1111
376421667a Merge pull request #2836
3f13a5c QRCodeScanner: don't load webcam on startup (mmbyday/selsta)
2020-04-17 20:53:46 -05:00
luigi1111
8a73fd241e Merge pull request #2835
a078705 QrScanThread: use sizeInBytes to fix warning (selsta)
2020-04-17 20:52:33 -05:00
luigi1111
9760886eff Merge pull request #2834
fb7470a build: find zbar header on macOS (selsta)
2020-04-17 20:49:18 -05:00
luigi1111
34089599cd Merge pull request #2833
e2c6ae6 AddressBook: remove leftover code (selsta)
2020-04-17 20:46:49 -05:00
luigi1111
4a7a98034e Merge pull request #2832
ea25b71 updater: fetch signed hashes from getmonero.org, verify downloads (xiphon)
2020-04-17 20:45:24 -05:00
luigi1111
79f78f48e2 Merge pull request #2830
5ebe3f5 Settings: move Merchant menu entry (tobtoht/selsta)
2020-04-17 20:43:40 -05:00
selsta
fee81ba210 workflows: add trezor support ubuntu 2020-04-16 22:53:33 +02:00
selsta
a078705ec6 QrScanThread: use sizeInBytes to fix warning 2020-04-16 19:11:29 +02:00
rating89us
de6a9b6779 Transfer: address book inline button, 2nd inline button, scan QR code button fixes
spacing fix
2020-04-16 13:25:28 +02:00
mmbyday
3f13a5c9a4 QRCodeScanner: don't load webcam on startup 2020-04-16 03:29:39 +02:00
selsta
fb7470a2a6 build: find zbar header on macOS 2020-04-16 03:13:33 +02:00
selsta
e2c6ae6472 AddressBook: remove leftover code 2020-04-16 02:08:32 +02:00
xiphon
ea25b71ca6 updater: fetch signed hashes from getmonero.org, verify downloads 2020-04-14 21:37:04 +00:00
thotbot
5ebe3f5092 Settings: move Merchant menu entry 2020-04-13 23:15:14 +02:00
luigi1111
8e4124f06a Merge pull request #2828
e1258e0 TitleBar: fix close icon fallback (selsta)
2020-04-13 15:49:17 -05:00
luigi1111
e47fd5f760 Merge pull request #2827
925cced README: add weblate's widget for translations status (erciccione)
2020-04-13 15:48:14 -05:00
luigi1111
8767c71107 Merge pull request #2825
94083e7 cmake: use monero core compilation and linking flags (xiphon)
2020-04-13 15:46:38 -05:00
luigi1111
2156a6533b Merge pull request #2824
5f27a45 '--verify-update', shasum support, OpenPGP signatures verification (xiphon)
2020-04-13 15:43:24 -05:00
luigi1111
7eac690d44 Merge pull request #2822
a49d579 build: fix MSYS2 folder detection (xiphon)
2020-04-13 15:40:42 -05:00
luigi1111
31adc6cfd6 Merge pull request #2821
6d7db13 Settings: rework wallet page (thotbot/xiphon)
2020-04-13 15:39:54 -05:00
luigi1111
d582fd338d Merge pull request #2819
6ed7fce UpdateDialog: implement update download functionality (xiphon)
2020-04-13 15:38:06 -05:00
luigi1111
eed51e3ffa Merge pull request #2772
48aab5c WalletManager: wallet recovery - seed offset passphrase support (xiphon)
2020-04-13 15:36:44 -05:00
luigi1111
6a889bdaa1 Merge pull request #2739
b5fafb5 Transfer: display estimated transaction fee, requires #6302 (xiphon)
2020-04-13 15:35:44 -05:00
xiphon
5f27a45910 '--verify-update', shasum support, OpenPGP signatures verification 2020-04-12 21:34:22 +00:00
selsta
e1258e0ada TitleBar: fix close icon fallback 2020-04-10 13:55:25 +02:00
erciccione
925cced7d7 README: add weblate's widget for translations status 2020-04-09 12:25:54 +02:00
xiphon
94083e746f cmake: use monero core compilation and linking flags 2020-04-08 02:31:16 +00:00
xiphon
a49d579bd3 build: fix MSYS2 folder detection 2020-04-06 17:22:34 +00:00
xiphon
6ed7fcec67 UpdateDialog: implement update download functionality 2020-04-06 16:59:33 +00:00
thotbot
6d7db135e7 Settings: rework wallet page 2020-04-05 13:07:11 +00:00
luigi1111
042400b83f Set submodule back to master 2020-04-04 14:30:32 -05:00
luigi1111
df54439972 Merge pull request #2818
a9fea24 workflows: retry on apt failure / increase timeout (selsta)
2020-04-04 13:22:37 -05:00
luigi1111
86252506f0 Merge pull request #2817
58987b2 network: provide common HTTP GET functionality with js callbacks (xiphon)
2020-04-04 13:21:23 -05:00
selsta
a9fea2462b workflows: retry on apt failure / increase timeout
Co-authored-by: xiphon <xiphon@protonmail.com>
2020-04-01 00:50:24 +02:00
xiphon
58987b2ec6 network: provide common HTTP GET functionality with js callbacks 2020-03-31 21:37:19 +00:00
luigi1111
aecd218d15 Merge pull request #2807
d07da76 MenuButton: add hover effect (xiphon)
2020-03-27 10:55:07 -05:00
luigi1111
856843b52a Merge pull request #2803
5872bc8 build: disable _FORTIFY_SOURCE when building without optimization (xiphon)
2020-03-27 10:53:46 -05:00
luigi1111
fc740a89ab Merge pull request #2801
dede10e Add QT Creator cache file to gitignore (tobtoht)
2020-03-27 10:19:31 -05:00
luigi1111
0643607ec3 Merge pull request #2792
d21c22b SettingsNode: blockchain location 'Reset' button (xiphon)
2020-03-27 10:16:58 -05:00
xiphon
5872bc8a2b build: disable _FORTIFY_SOURCE when building without optimization 2020-03-23 06:34:18 +00:00
xiphon
d07da76383 MenuButton: add hover effect 2020-03-14 01:19:08 +00:00
luigi1111
c092de97f2 Merge pull request #2805
c9e461d build: set submodule to v0.15.0.5 (selsta)
2020-03-10 18:58:00 -04:00
luigi1111
c84a8fb07d Merge pull request #2799
55b548f qt: drop Qt Network and Qt OpenSSL deps, use epee library instead (xiphon)
2020-03-10 18:56:04 -04:00
luigi1111
63b4566475 Merge pull request #2796
c7df74d README: add protobuf to linux instructions (selsta)
2020-03-10 18:50:54 -04:00
luigi1111
3699dc9f2e Merge pull request #2795
94a27b9 README: cleanup macOS instructions (selsta)
2020-03-10 18:49:22 -04:00
luigi1111
eee48ce74c Merge pull request #2797
b739cdd cmake: -static, -static-libgcc, -static-libstdc++ linker flags (xiphon)
2020-03-10 18:48:01 -04:00
luigi1111
9072f89a4e Merge pull request #2794
bf9b04b installers: fix warning (selsta)
2020-03-10 18:46:45 -04:00
selsta
c9e461dcb6 build: set submodule to v0.15.0.5 2020-03-09 20:50:16 +01:00
xiphon
55b548f31c qt: drop Qt Network and Qt OpenSSL deps, use epee library instead 2020-03-09 11:05:49 +00:00
thotbot
dede10ea1a Add QT Creator cache file to gitignore 2020-03-08 15:58:29 +00:00
xiphon
b739cdd52a cmake: -static, -static-libgcc, -static-libstdc++ linker flags 2020-03-06 11:54:16 +00:00
selsta
94a27b964a README: cleanup macOS instructions 2020-03-06 02:06:08 +01:00
selsta
c7df74dab7 README: add protobuf to linux instructions 2020-03-06 01:52:00 +01:00
selsta
bf9b04b126 installers: fix warning 2020-03-04 20:02:08 +01:00
xiphon
d21c22b444 SettingsNode: blockchain location 'Reset' button 2020-03-02 10:35:50 +00:00
luigi1111
cee56a7d23 Merge pull request #2789
dc3a99c Add and activate new language: Norwegian (erciccione)
2020-02-28 16:16:01 -05:00
luigi1111
c3a34227b7 Merge pull request #2788
566beea Add translations from Weblate + refresh + 1 new language: Norwegian (Monero-Weblate)
2020-02-28 16:14:19 -05:00
luigi1111
7a86856063 Merge pull request #2787
9deca92 fix multiple minor issues (c-style casts, default branch, etc.) (xiphon)
2020-02-28 16:11:15 -05:00
luigi1111
86f35992dc Merge pull request #2786
09ff85a main: show splash screen after passphrase entry (selsta)
2020-02-28 16:10:31 -05:00
luigi1111
cb84652c8e Merge pull request #2781
a0b6c8a PasswordDialog: don't skip equality check (selsta)
2020-02-28 16:09:36 -05:00
erciccione
dc3a99c9ca Add and activate new language: Norwegian 2020-02-28 14:08:23 +01:00
Weblate
566beeaf4b Add translations from Weblate + refresh + 1 new language: Norwegian
Refresh language files (Including monero-core.ts)

results:

Found 656 source text(s) (27 new and 629 already existing)
    Removed 18 obsolete entries

Translations:

Hungarian

Currently translated at 78.2% (506 of 647 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/hu/
Author: Zsolt András Kovács

Norwegian Bokmål

Currently translated at 100.0% (647 of 647 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/nb_NO/
Author: Chris
Reviewed by Luigi1111 and Rehrar in behalf of luigi1111's reviewer

Italian

Currently translated at 94.0% (608 of 647 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/it/
Author: Marco

    Ukrainian

    Currently translated at 93.2% (603 of 647 strings)
    Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/uk/
    Author: Agent LvM

    Portuguese (Brazil)

    Currently translated at 97.7% (632 of 647 strings)
    Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/pt_BR/
    Author: netrik182
2020-02-28 12:49:34 +00:00
xiphon
9deca92e07 fix multiple minor issues (c-style casts, default branch, etc.) 2020-02-28 10:25:57 +00:00
selsta
09ff85af44 main: show splash screen after passphrase entry 2020-02-27 18:39:35 +01:00
selsta
a0b6c8a397 PasswordDialog: don't skip equality check
credit to consistent-dream
2020-02-27 15:29:35 +01:00
luigi1111
44dfb80633 Merge pull request #2783
dfd8ff9 main: fix Trezor passphrase screen (selsta)
2020-02-26 14:52:44 -05:00
luigi1111
7067195c2f Merge pull request #2785
c14852c WizardController: invoke restart() after persistentSettings update (xiphon)
2020-02-26 14:51:10 -05:00
luigi1111
19cf510e62 Merge pull request #2784
57d3302 workflows: fix macOS build (selsta)
2020-02-26 14:17:57 -05:00
xiphon
c14852cbd7 WizardController: invoke restart() after persistentSettings update 2020-02-26 17:53:35 +00:00
selsta
57d330244b workflows: fix macOS build 2020-02-25 22:33:50 +01:00
selsta
dfd8ff9809 main: fix Trezor passphrase screen 2020-02-25 21:24:58 +01:00
luigi1111
b4a65c52cc Merge pull request #2778
636ca1c DaemonManager: async stop, simple mode wizard - show splash on stop (xiphon)
2020-02-19 22:17:04 -05:00
luigi1111
386c5e3d30 Merge pull request #2777
872b18d Simple mode: don't override bootstrap daemon textbox (selsta)
2020-02-19 22:16:13 -05:00
luigi1111
5069e6ecae Merge pull request #2776
98abdaa build: fix all warnings, treat warnings as errors (xiphon)
2020-02-19 22:15:08 -05:00
luigi1111
7c38a836d3 Merge pull request #2775
fbfc531 History: display Address Book names for known destination addresses (xiphon)
2020-02-19 22:13:53 -05:00
luigi1111
0731972499 Merge pull request #2774
0af7a43 macOS: add copyright notice (selsta)
2020-02-19 22:10:43 -05:00
luigi1111
f9b9d43ac1 Merge pull request #2773
478fdda macOS: add version to info.plist (selsta)
2020-02-19 22:09:43 -05:00
luigi1111
d1e431c5e8 Merge pull request #2769
98ab4ea misc: strip html out of translatable strings (selsta)
2020-02-19 22:07:38 -05:00
luigi1111
4c0996888a Merge pull request #2764
a20422d Transfer: allow to import key images using trusted remote node (xiphon)
2020-02-19 22:06:50 -05:00
luigi1111
a9d855ad00 Merge pull request #2584
d175070 installer: change blockchain folder string (selsta)
2020-02-19 22:05:43 -05:00
xiphon
636ca1c41d DaemonManager: async stop, simple mode wizard - show splash on stop 2020-02-16 15:01:17 +00:00
selsta
872b18d5af Simple mode: don't override bootstrap daemon textbox 2020-02-16 15:09:36 +01:00
xiphon
98abdaa5d5 build: fix all warnings, treat warnings as errors 2020-02-16 13:55:08 +00:00
xiphon
b5fafb55c9 Transfer: display estimated transaction fee, requires #6302 2020-02-16 11:55:36 +00:00
xiphon
fbfc5310d5 History: display Address Book names for known destination addresses 2020-02-15 15:57:38 +00:00
selsta
478fddaf57 macOS: add version to info.plist 2020-02-14 14:32:04 +01:00
selsta
d175070f55 installer: change blockchain folder string 2020-02-13 16:45:08 +01:00
selsta
0af7a4320d macOS: add copyright notice 2020-02-13 13:11:05 +01:00
xiphon
48aab5c6e5 WalletManager: wallet recovery - seed offset passphrase support 2020-02-12 13:49:26 +00:00
xiphon
a20422da74 Transfer: allow to import key images using trusted remote node 2020-02-06 15:14:38 +00:00
luigi1111
eb7fae92ef Merge pull request #2765
0629f06 DaemonManager: check monerod binary, error details on start failure (xiphon)
2020-02-05 21:42:11 -05:00
luigi1111
4b1a6eb49b Merge pull request #2718
e05e634 Keys: rename keys section to primary address & keys, add primary address (rating89us)
2020-02-05 21:41:07 -05:00
luigi1111
df614cd0a0 Merge pull request #2712
b4a6569 History: add filter options in search field (rating89us)
2020-02-05 21:40:17 -05:00
luigi1111
0adafaaa91 Merge pull request #2711
023951f Transfer: import key images always visible (rating89us)
2020-02-05 21:39:34 -05:00
luigi1111
467dd8b664 Merge pull request #2702
c7f272d Wizard: open wallet -> create wallet (rating89us)
2020-02-05 21:38:47 -05:00
luigi1111
dba48334e6 Merge pull request #2689
e5a6a50 Wizard: remove unnecessary periods (rating89us)
2020-02-05 21:37:35 -05:00
selsta
98ab4ea2aa misc: strip html out of translatable strings 2020-02-05 17:06:52 +01:00
xiphon
0629f06156 DaemonManager: check monerod binary, error details on start failure 2020-02-04 23:27:48 +00:00
rating89us
e05e6346ac Keys: rename keys section to primary address & keys, add primary address 2020-02-04 21:51:03 +01:00
luigi1111
d5469c8247 Merge pull request #2759
900f478 MenuButton: fix gradient (selsta)
2020-02-04 14:37:17 -05:00
luigi1111
080ec28eb4 Merge pull request #2758
742a465 AddressBook: thread-safety, fix use-after-free (xiphon)
2020-02-04 14:36:35 -05:00
luigi1111
8f197bc6ac Merge pull request #2756
b6d554e LeftPanel: NetworkStatusItem fixed at bottom left corner (rating89us)
2020-02-04 14:35:18 -05:00
luigi1111
82bc71c81d Merge pull request #2594
24ac001 main: fix warning (selsta)
2020-02-04 14:34:23 -05:00
luigi1111
5a4f27b375 Merge pull request #2592
163fa73 WizardOpenWallet1: fix warning (selsta)
2020-02-04 14:33:34 -05:00
rating89us
b6d554eebd LeftPanel: NetworkStatusItem fixed at bottom left corner 2020-02-02 18:51:50 +01:00
selsta
900f478abe MenuButton: fix gradient 2020-02-01 23:01:10 +01:00
xiphon
742a4659f4 AddressBook: thread-safety, fix use-after-free 2020-02-01 14:21:33 +00:00
luigi1111
35b7a5f6bb Merge pull request #2747
6940390 Wallet: implement 'Connecting' status, add 'disconnected' property (xiphon)
2020-01-30 16:32:56 -05:00
luigi1111
21e8c7ca17 Merge pull request #2749
e59e247 Merchant: strip html tags out of translatable string (xiphon)
2020-01-30 16:31:55 -05:00
luigi1111
8ef1b41093 Merge pull request #2748
8940d2b Translations from Weblate + Updated language files (Monero-Weblate)
2020-01-28 15:27:04 -05:00
luigi1111
911ff4288d Merge pull request #2746
7ebf50d Keys: stop displaying hw device msg in view-only wallets (rating89us)
2020-01-28 15:25:36 -05:00
luigi1111
6dd759de33 Merge pull request #2744
2c515ce History: address filter case insensitive (rating89us)
2020-01-28 15:24:34 -05:00
xiphon
e59e247048 Merchant: strip html tags out of translatable string 2020-01-28 16:33:01 +00:00
Weblate
8940d2b8d1 Translations from Weblate + Updated language files
Refresh:
Found 647 source text(s) (44 new and 603 already existing)
    Removed 45 obsolete entries

Translations:

Portuguese (Brazil)

Currently translated at 100.0% (648 of 648 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/pt_BR/

Korean

Currently translated at 37.3% (242 of 648 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/ko/

Spanish

Currently translated at 89.5% (580 of 648 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/es/

Swedish

Currently translated at 80.9% (524 of 648 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/sv/

Greek

Currently translated at 13.6% (88 of 648 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/el/

Dutch

Currently translated at 100.0% (648 of 648 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/nl/

Korean

Currently translated at 37.2% (241 of 648 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/ko/

Russian

Currently translated at 100.0% (648 of 648 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/ru/

Lithuanian

Currently translated at 61.1% (396 of 648 strings)
Translate-URL: https://translate.getmonero.org/projects/monero/gui-wallet/lt/
2020-01-28 15:44:40 +00:00
xiphon
6940390a5e Wallet: implement 'Connecting' status, add 'disconnected' property 2020-01-28 05:11:29 +00:00
rating89us
7ebf50dc6f Keys: stop displaying hw device msg in view-only wallets 2020-01-27 10:07:07 +01:00
rating89us
2c515ceb74 History: address filter case insensitive 2020-01-27 01:53:31 +01:00
luigi1111
39aa6e76b1 Merge pull request #2740
a3f5460 build: fix cmake command line ARCH def, add ARCH=native fallback (xiphon)
2e262d4 workflows: checkout v2 -> v1 (selsta)
2020-01-24 22:02:29 -05:00
luigi1111
aa5962519a Merge pull request #2733
f266480 Style: All button (transfer page) in white text (rating89us)
2020-01-24 21:59:47 -05:00
xiphon
a3f5460d12 build: fix cmake command line ARCH def, add ARCH=native fallback 2020-01-24 20:31:45 +01:00
selsta
2e262d41d7 workflows: checkout v2 -> v1 2020-01-24 13:16:22 +01:00
luigi1111
6de8547047 Merge pull request #2736
7e6fcff Update Arch Linux installation instructions (trulex)
2020-01-23 10:28:05 -05:00
luigi1111
59954df199 Merge pull request #2730
96106cc resources: drop JPEG images (xiphon)
2020-01-23 10:26:54 -05:00
luigi1111
8a66f7b6f7 Merge pull request #2729
ed9e061 cmake: set minimum required CMake version to 3.5 (Ubuntu 16.04 LTS) (xiphon)
2020-01-23 10:25:21 -05:00
luigi1111
a5e5bfad46 Merge pull request #2728
b56c0cd cmake: fix Linux detection (xiphon)
2020-01-23 10:24:36 -05:00
luigi1111
2058c78943 Merge pull request #2727
0043905 workflows: update checkout to v2 (selsta)
f36098d workflows: remove bundled boost (selsta)
2020-01-23 10:22:34 -05:00
luigi1111
4d279a5f02 Merge pull request #2726
fae5956 README: link to figma (design) (selsta)
2020-01-23 10:16:55 -05:00
luigi1111
29f0c4667c Merge pull request #2725
8dfd7a3 README: link to weblate (selsta)
2020-01-23 10:15:17 -05:00
luigi1111
f00b7b42c0 Merge pull request #2724
098e78f README: remove deprecated forum (selsta)
2020-01-23 10:14:27 -05:00
luigi1111
80a3da6efa Merge pull request #2723
4a30d1f Account: update label after rename (selsta)
2020-01-23 10:13:22 -05:00
luigi1111
2a1cd7dc01 Merge pull request #2719
148c1b9 Transfer: fix Send button state not being updated properly (xiphon)
2020-01-23 10:12:20 -05:00
luigi1111
9bc6e041ee Merge pull request #2717
cc22693 StandardDropdown: remove dots from upper corners (rating89us)
2020-01-23 10:10:52 -05:00
luigi1111
3bab6ccedf Merge pull request #2716
c4bdf56 Remove paste buttons (rating89us)
2020-01-23 10:09:47 -05:00
luigi1111
eebbd2b93e Merge pull request #2715
a8618b0 Pass -dead_strip and -dead_strip_dylibs on macOS (rex4539)
2020-01-23 10:08:50 -05:00
luigi1111
a807dcd5df Merge pull request #2714
50f3e67 Receive: buttons in rows + labels + 3D depth + FontAwesome icons (rating89us)
2020-01-23 10:06:51 -05:00
luigi1111
0009a886fe Merge pull request #2707
266b1f1 CheckBox: fix word wrap on windows (Qt 5.13.2) (selsta)
2020-01-22 17:25:52 -05:00
luigi1111
9c2bceaaed Merge pull request #2615
7cf0f21 build: support ARCH override for libwallet_merged (xiphon)
2020-01-22 17:21:40 -05:00
rating89us
50f3e67e81 Receive: buttons in rows + labels + 3D depth + FontAwesome icons 2020-01-19 17:29:49 -03:00
Darko Janković
7e6fcff3ee Update Arch Linux installation instructions 2020-01-19 17:32:27 +01:00
rating89us
f266480f7d Style: All button (transfer page) in white text 2020-01-18 14:12:25 -03:00
xiphon
96106cc818 resources: drop JPEG images 2020-01-17 11:58:51 +00:00
xiphon
ed9e061489 cmake: set minimum required CMake version to 3.5 (Ubuntu 16.04 LTS) 2020-01-17 11:01:30 +00:00
xiphon
b56c0cd8a2 cmake: fix Linux detection 2020-01-17 10:40:51 +00:00
selsta
f36098d60f workflows: remove bundled boost 2020-01-17 02:03:16 +01:00
selsta
00439052e6 workflows: update checkout to v2 2020-01-17 01:56:25 +01:00
selsta
fae5956bfb README: link to figma (design) 2020-01-17 00:41:48 +01:00
selsta
8dfd7a300d README: link to weblate 2020-01-17 00:36:27 +01:00
xiphon
7cf0f21ec0 build: support ARCH override for libwallet_merged 2020-01-16 13:54:52 +00:00
selsta
098e78f4ef README: remove deprecated forum 2020-01-16 03:58:20 +01:00
selsta
4a30d1fc38 Account: update label after rename 2020-01-15 22:41:39 +01:00
xiphon
148c1b9816 Transfer: fix Send button state not being updated properly 2020-01-15 13:52:40 +00:00
rating89us
cc22693504 StandardDropdown: remove dots from upper corners 2020-01-14 22:02:02 -03:00
rating89us
c4bdf5621c Remove paste buttons 2020-01-14 03:29:54 -03:00
Dimitris Apostolou
a8618b0471 Pass -dead_strip and -dead_strip_dylibs on macOS 2020-01-13 14:01:43 +02:00
rating89us
b4a6569e63 History: add filter options in search field 2020-01-12 16:20:20 -03:00
rating89us
e5a6a50e49 Wizard: remove unnecessary periods 2020-01-09 20:12:08 -03:00
rating89us
c7f272d86a Wizard: open wallet -> create wallet 2020-01-09 18:24:16 -03:00
rating89us
023951fd84 Transfer: import key images always visible
Closes #2687
2020-01-08 23:08:17 -03:00
luigi1111
ef2b0cfa4a Merge pull request #2709
a5b500c main: add blur to wizard password dialog (selsta)
2020-01-08 18:43:03 -05:00
luigi1111
fe08950b03 Merge pull request #2708
16fd1d1 windeploy: add libzstd and update libicu* (iDunk5400)
2020-01-08 18:40:42 -05:00
selsta
a5b500cd93 main: add blur to wizard password dialog 2020-01-08 21:56:15 +01:00
iDunk5400
16fd1d1eee windeploy: add libzstd and update libicu* 2020-01-08 21:47:04 +01:00
sebseb7
266b1f167d CheckBox: fix word wrap on windows (Qt 5.13.2) 2020-01-08 21:38:57 +01:00
luigi1111
40a1edbbcb Merge pull request #2695
5ca671e workflows: rename to be consistent with cli repo (selsta)
2020-01-06 11:21:25 -05:00
luigi1111
0999daf1f2 Merge pull request #2693
c98ffcc workflows: add windows support (selsta)
2020-01-06 11:20:29 -05:00
luigi1111
7462c64fe2 Merge pull request #2692
e74075b build: link ole32 on windows (selsta)
2020-01-06 11:17:47 -05:00
luigi1111
4920df95e3 Merge pull request #2691
916c0e4 workflows: fix macOS build (selsta)
2020-01-06 11:17:01 -05:00
luigi1111
6a453039ee Merge pull request #2694
118ad12 Update WizardCreateDevice1.qml (rating89us)
2020-01-02 10:52:18 -05:00
luigi1111
5281244b33 Merge pull request #2690
b626fcb build: autodetect MSYS2 install path, support non-standard location (xiphon)
2020-01-02 10:50:39 -05:00
luigi1111
525822f391 Merge pull request #2684
c765bbb build: define Boost_USE_STATIC_RUNTIME for static builds (xiphon)
2020-01-02 10:47:44 -05:00
luigi1111
23e3d82441 Merge pull request #2676
181866b Set minimum window size (tobtoht)
2020-01-02 10:46:18 -05:00
selsta
5ca671e5f5 workflows: rename to be consistent with cli repo 2019-12-31 00:20:49 +01:00
rating89us
118ad125c4 Update WizardCreateDevice1.qml 2019-12-30 13:47:45 -03:00
selsta
c98ffcca5d workflows: add windows support 2019-12-30 13:36:51 +01:00
selsta
e74075bb0e build: link ole32 on windows 2019-12-30 13:29:17 +01:00
selsta
916c0e4406 workflows: fix macOS build 2019-12-30 11:03:05 +01:00
xiphon
b626fcba08 build: autodetect MSYS2 install path, support non-standard location 2019-12-30 09:44:21 +00:00
xiphon
c765bbb1fd build: define Boost_USE_STATIC_RUNTIME for static builds 2019-12-24 11:25:17 +00:00
thotbot
181866ba4a Set minimum window size 2019-12-21 21:43:37 +00:00
selsta
24ac001daa main: fix warning 2019-12-14 03:37:44 +01:00
selsta
163fa733ae WizardOpenWallet1: fix warning 2019-12-14 03:18:26 +01:00
206 changed files with 58518 additions and 41690 deletions

1
.dockerignore Normal file
View File

@@ -0,0 +1 @@
*

View File

@@ -1,4 +1,4 @@
name: GUI build name: continuous-integration/gh-actions/gui
on: [push, pull_request] on: [push, pull_request]
@@ -6,29 +6,89 @@ jobs:
build-macos: build-macos:
runs-on: macOS-latest runs-on: macOS-latest
strategy:
fail-fast: false
matrix:
toolchain:
- name: "qmake"
cmd: "export PATH=$PATH:/usr/local/opt/qt/bin && ./build.sh"
- name: "cmake"
cmd: "USE_SINGLE_BUILDDIR=ON DEV_MODE=ON make release -j3"
name: build-macos-${{ matrix.toolchain.name }}
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
with:
submodules: recursive
- name: update brew and install dependencies - name: update brew and install dependencies
run: brew update && brew install boost hidapi zmq libpgm unbound libsodium miniupnpc ldns expat doxygen graphviz libunwind-headers protobuf qt5 run: brew update && brew install boost hidapi zmq libpgm miniupnpc ldns expat libunwind-headers protobuf qt5 pkg-config
- name: build - name: build
run: export PATH=$PATH:/usr/local/opt/qt/bin && ./build.sh run: ${{ matrix.toolchain.cmd }}
- name: test qml - name: test qml
run: build/release/bin/monero-wallet-gui.app/Contents/MacOS/monero-wallet-gui --test-qml run: build/release/bin/monero-wallet-gui.app/Contents/MacOS/monero-wallet-gui --test-qml
build-ubuntu: build-ubuntu:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
toolchain:
- name: "qmake"
cmd: "./build.sh"
- name: "cmake"
cmd: "USE_SINGLE_BUILDDIR=ON DEV_MODE=ON make release -j3"
name: build-ubuntu-${{ matrix.toolchain.name }}
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
with:
submodules: recursive
- name: remove bundled boost
run: sudo rm -rf /usr/local/share/boost
- name: set apt conf
run: |
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
- name: update apt - name: update apt
run: sudo apt update run: sudo apt update
- name: install monero dependencies - name: install monero dependencies
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler
- name: install monero gui dependencies - name: install monero gui dependencies
run: sudo apt -y install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-dialogs qml-module-qtquick-xmllistmodel qml-module-qt-labs-settings qml-module-qt-labs-folderlistmodel qttools5-dev-tools qml-module-qtquick-templates2 libqt5svg5-dev xvfb run: sudo apt -y install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-dialogs qml-module-qtquick-xmllistmodel qml-module-qt-labs-settings qml-module-qt-labs-folderlistmodel qttools5-dev-tools qml-module-qtquick-templates2 libqt5svg5-dev libgcrypt20-dev xvfb
- name: build - name: build
run: ./build.sh run: ${{ matrix.toolchain.cmd }}
- name: test qml - name: test qml
run: xvfb-run -a build/release/bin/monero-wallet-gui --test-qml run: xvfb-run -a build/release/bin/monero-wallet-gui --test-qml
build-windows:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
toolchain:
- name: "qmake"
cmd: "./build.sh release"
- name: "cmake"
cmd: "USE_SINGLE_BUILDDIR=ON DEV_MODE=ON make release-win64 -j2"
name: build-windows-${{ matrix.toolchain.name }}
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v1
with:
submodules: recursive
- uses: eine/setup-msys2@v1
with:
update: true
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb git mingw-w64-x86_64-qt5 mingw-w64-x86_64-libgcrypt
- name: build
run: |
sed -i 's/CONFIG\ +=\ qtquickcompiler//' monero-wallet-gui.pro
${{ matrix.toolchain.cmd }}
- name: test qml
run: build/release/bin/monero-wallet-gui --test-qml

1
.gitignore vendored
View File

@@ -13,6 +13,7 @@ monero-wallet-gui_plugin_import.cpp
monero-wallet-gui_qml_plugin_import.cpp monero-wallet-gui_qml_plugin_import.cpp
*.qmlc *.qmlc
*.jsc *.jsc
qml_qmlcache.qrc
### Vim ### ### Vim ###
# Swap # Swap

View File

@@ -1,22 +1,26 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.5)
project(monero-gui) project(monero-gui)
message(STATUS "Initiating compile using CMake ${CMAKE_VERSION}") message(STATUS "Initiating compile using CMake ${CMAKE_VERSION}")
set(VERSION_MAJOR "14") set(VERSION_MAJOR "16")
set(VERSION_MINOR "0") set(VERSION_MINOR "0")
set(VERSION_REVISION "3") set(VERSION_REVISION "3")
set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}") set(VERSION "0.${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}")
# libwallet requires a static build, so we only allow static compilation option(STATIC "Link libraries statically, requires static Qt")
set(STATIC ON)
option(USE_DEVICE_TREZOR ON) option(USE_DEVICE_TREZOR "Trezor support compilation" ON)
option(ENABLE_PASS_STRENGTH_METER "Disable zxcvbn" OFF) option(ENABLE_PASS_STRENGTH_METER "Disable zxcvbn" OFF)
option(WITH_SCANNER "Enable webcam QR scanner" OFF) option(WITH_SCANNER "Enable webcam QR scanner" OFF)
option(DEV_MODE "Checkout latest monero master on build" OFF) option(DEV_MODE "Checkout latest monero master on build" OFF)
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_SOURCE_DIR}/cmake") list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_SOURCE_DIR}/cmake")
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
include(CheckLinkerFlag)
include(FindCcache)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)
@@ -27,7 +31,6 @@ endif()
set(BUILD_GUI_DEPS ON) set(BUILD_GUI_DEPS ON)
set(ARCH "x86-64") set(ARCH "x86-64")
set(BUILD_64 ON) set(BUILD_64 ON)
set(INSTALL_VENDORED_LIBUNBOUND=ON)
function (add_c_flag_if_supported flag var) function (add_c_flag_if_supported flag var)
string(REPLACE "-" "_" supported ${flag}_c) string(REPLACE "-" "_" supported ${flag}_c)
@@ -78,14 +81,16 @@ endif()
add_subdirectory(monero) add_subdirectory(monero)
set_property(TARGET wallet_merged PROPERTY FOLDER "monero") set_property(TARGET wallet_merged PROPERTY FOLDER "monero")
get_directory_property(ARCH_WIDTH DIRECTORY "monero" DEFINITION ARCH_WIDTH) get_directory_property(ARCH_WIDTH DIRECTORY "monero" DEFINITION ARCH_WIDTH)
get_directory_property(UNBOUND_LIBRARY DIRECTORY "monero" DEFINITION UNBOUND_LIBRARY)
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug") if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DQT_NO_DEBUG) add_definitions(-DQT_NO_DEBUG)
endif() endif()
if(STATIC) if(STATIC)
message(STATUS "Initiating static build") message(STATUS "Initiating static build")
set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
add_definitions(-DMONERO_GUI_STATIC) add_definitions(-DMONERO_GUI_STATIC)
endif() endif()
@@ -134,6 +139,9 @@ monero_gui_add_library(gui_version SOURCES version.js DEPENDS genversiongui)
message(STATUS "${CMAKE_MODULE_PATH}") message(STATUS "${CMAKE_MODULE_PATH}")
# OpenSSL # OpenSSL
if(APPLE AND NOT OPENSSL_ROOT_DIR)
execute_process(COMMAND brew --prefix openssl OUTPUT_VARIABLE OPENSSL_ROOT_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
find_package(OpenSSL REQUIRED) find_package(OpenSSL REQUIRED)
message(STATUS "OpenSSL: Version ${OPENSSL_VERSION}") message(STATUS "OpenSSL: Version ${OPENSSL_VERSION}")
message(STATUS "OpenSSL: include dir at ${OPENSSL_INCLUDE_DIR}") message(STATUS "OpenSSL: include dir at ${OPENSSL_INCLUDE_DIR}")
@@ -165,7 +173,10 @@ message(STATUS "libhidapi: libraries at ${HIDAPI_LIBRARIES}")
if(DEBUG) if(DEBUG)
set(Boost_DEBUG ON) set(Boost_DEBUG ON)
endif() endif()
find_package(Boost 1.62 REQUIRED COMPONENTS if(APPLE AND NOT BOOST_ROOT)
execute_process(COMMAND brew --prefix boost OUTPUT_VARIABLE BOOST_ROOT OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
find_package(Boost 1.58 REQUIRED COMPONENTS
system system
filesystem filesystem
thread thread
@@ -176,7 +187,7 @@ find_package(Boost 1.62 REQUIRED COMPONENTS
program_options program_options
locale) locale)
if(LINUX) if(UNIX AND NOT APPLE)
find_package(X11 REQUIRED) find_package(X11 REQUIRED)
message(STATUS "X11_FOUND = ${X11_FOUND}") message(STATUS "X11_FOUND = ${X11_FOUND}")
message(STATUS "X11_INCLUDE_DIR = ${X11_INCLUDE_DIR}") message(STATUS "X11_INCLUDE_DIR = ${X11_INCLUDE_DIR}")
@@ -193,21 +204,6 @@ if(MINGW)
string(REGEX MATCH "^[^/]:/[^/]*" msys2_install_path "${CMAKE_C_COMPILER}") string(REGEX MATCH "^[^/]:/[^/]*" msys2_install_path "${CMAKE_C_COMPILER}")
message(STATUS "MSYS location: ${msys2_install_path}") message(STATUS "MSYS location: ${msys2_install_path}")
set(CMAKE_INCLUDE_PATH "${msys2_install_path}/mingw${ARCH_WIDTH}/include") set(CMAKE_INCLUDE_PATH "${msys2_install_path}/mingw${ARCH_WIDTH}/include")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/Qt/labs/folderlistmodel")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/Qt/labs/settings")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtGraphicalEffects")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtGraphicalEffects/private")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtMultimedia")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick.2")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Controls")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Controls.2")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Dialogs")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Dialogs/Private")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Layouts")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/PrivateWidgets")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Templates.2")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/Window.2")
link_directories("${msys2_install_path}/mingw${ARCH_WIDTH}/qml/QtQuick/XmlListModel")
# This is necessary because otherwise CMake will make Boost libraries -lfoo # This is necessary because otherwise CMake will make Boost libraries -lfoo
# rather than a full path. Unfortunately, this makes the shared libraries get # rather than a full path. Unfortunately, this makes the shared libraries get
# linked due to a bug in CMake which misses putting -static flags around the # linked due to a bug in CMake which misses putting -static flags around the
@@ -220,35 +216,66 @@ endif()
set(QT5_LIBRARIES set(QT5_LIBRARIES
Qt5Core Qt5Core
Qt5Quick Qt5Quick
Qt5QuickControls2
Qt5Widgets Qt5Widgets
Qt5Gui Qt5Gui
Qt5Network Qt5Network
Qt5Qml Qt5Qml
Qt5Multimedia
Qt5Xml
Qt5XmlPatterns
Qt5Svg Qt5Svg
Qt5Xml
) )
if(WITH_SCANNER)
list(APPEND QT5_LIBRARIES Qt5Multimedia)
endif()
if(APPLE)
list(APPEND QT5_LIBRARIES Qt5MacExtras)
if(NOT CMAKE_PREFIX_PATH)
execute_process(COMMAND brew --prefix qt5 OUTPUT_VARIABLE QT5_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
list(APPEND CMAKE_PREFIX_PATH ${QT5_DIR})
endif()
if(CMAKE_PREFIX_PATH)
include_directories(${CMAKE_PREFIX_PATH}/include)
endif()
endif()
find_package(PkgConfig REQUIRED)
# TODO: drop this once we switch to Qt 5.14+
pkg_check_modules(Qt5QmlModels_PKG_CONFIG QUIET Qt5QmlModels)
if(Qt5QmlModels_PKG_CONFIG_FOUND)
list(APPEND QT5_LIBRARIES Qt5QmlModels)
endif()
# TODO: drop this once we switch to Qt 5.12+
find_package(Qt5XmlPatterns QUIET)
if(Qt5XmlPatterns_FOUND)
list(APPEND QT5_LIBRARIES Qt5XmlPatterns)
endif()
foreach(QT5_MODULE ${QT5_LIBRARIES}) foreach(QT5_MODULE ${QT5_LIBRARIES})
find_package(${QT5_MODULE} REQUIRED) find_package(${QT5_MODULE} REQUIRED)
include_directories(${${QT5_MODULE}_INCLUDE_DIRS})
endforeach() endforeach()
find_package(PkgConfig) pkg_check_modules(QT5_PKG_CONFIG REQUIRED ${QT5_LIBRARIES})
if(PKGCONFIG_FOUND)
pkg_check_modules(QT5_PKG_CONFIG ${QT5_LIBRARIES})
if(QT5_PKG_CONFIG_FOUND) if(QT5_PKG_CONFIG_FOUND)
set(QT5_PKG_CONFIG "QT5_PKG_CONFIG") set(QT5_PKG_CONFIG "QT5_PKG_CONFIG")
if(STATIC) if(STATIC)
set(QT5_PKG_CONFIG "${QT5_PKG_CONFIG}_STATIC") set(QT5_PKG_CONFIG "${QT5_PKG_CONFIG}_STATIC")
endif()
set(QT5_LIBRARIES ${${QT5_PKG_CONFIG}_LIBRARIES} ${${QT5_PKG_CONFIG}_LDFLAGS_OTHER})
include_directories(${${QT5_PKG_CONFIG}_INCLUDE_DIRS})
link_directories(${${QT5_PKG_CONFIG}_LIBRARY_DIRS})
endif() endif()
if(APPLE)
list(JOIN ${QT5_PKG_CONFIG}_LDFLAGS_OTHER " " ${QT5_PKG_CONFIG}_LDFLAGS_OTHER)
list(JOIN ${QT5_PKG_CONFIG}_LIBRARIES " " ${QT5_PKG_CONFIG}_LIBRARIES)
endif()
set(QT5_LIBRARIES ${${QT5_PKG_CONFIG}_LIBRARIES} ${${QT5_PKG_CONFIG}_LDFLAGS_OTHER})
include_directories(${${QT5_PKG_CONFIG}_INCLUDE_DIRS})
link_directories(${${QT5_PKG_CONFIG}_LIBRARY_DIRS})
endif() endif()
list(APPEND QT5_LIBRARIES list(APPEND QT5_LIBRARIES
@@ -259,37 +286,95 @@ list(APPEND QT5_LIBRARIES
) )
if(STATIC) if(STATIC)
set(QT5_LIBRARIES set(QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/Qt/labs/folderlistmodel)
qtquickcontrols2plugin # has to be the first one, depends on Qt5QuickControls2 list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/Qt/labs/settings)
${QT5_LIBRARIES} list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtGraphicalEffects)
declarative_multimedia list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtGraphicalEffects/private)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtMultimedia)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtQuick.2)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtQuick/Controls)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtQuick/Controls.2)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtQuick/Dialogs)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtQuick/Dialogs/Private)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtQuick/Layouts)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtQuick/PrivateWidgets)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtQuick/Templates.2)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtQuick/Window.2)
list(APPEND QT5_EXTRA_PATHS ${QT5_PKG_CONFIG_Qt5Qml_PREFIX}/qml/QtQuick/XmlListModel)
set(QT5_EXTRA_LIBRARIES_LIST
qtquicktemplates2plugin
Qt5QuickTemplates2
qtquickcontrols2plugin
Qt5QuickControls2
dialogplugin dialogplugin
dialogsprivateplugin dialogsprivateplugin
qmlfolderlistmodelplugin qmlfolderlistmodelplugin
qmlsettingsplugin qmlsettingsplugin
qmlxmllistmodelplugin qmlxmllistmodelplugin
qquicklayoutsplugin qquicklayoutsplugin
Qt5EventDispatcherSupport )
Qt5FontDatabaseSupport
Qt5MultimediaQuick_p if(WITH_SCANNER)
Qt5PacketProtocol list(APPEND QT5_EXTRA_LIBRARIES_LIST
Qt5ThemeSupport declarative_multimedia
Qt5MultimediaQuick_p
)
endif()
list(APPEND QT5_EXTRA_LIBRARIES_LIST
qtgraphicaleffectsplugin qtgraphicaleffectsplugin
qtgraphicaleffectsprivate qtgraphicaleffectsprivate
qtquick2plugin qtquick2plugin
qtquickcontrolsplugin qtquickcontrolsplugin
qtquicktemplates2plugin
widgetsplugin widgetsplugin
windowplugin windowplugin
) )
set(QT5_EXTRA_LIBRARIES)
foreach(LIBRARY ${QT5_EXTRA_LIBRARIES_LIST})
find_library(${LIBRARY}_LIBRARY ${LIBRARY} PATHS ${QT5_EXTRA_PATHS} REQUIRED)
list(APPEND QT5_EXTRA_LIBRARIES ${${LIBRARY}_LIBRARY})
endforeach()
if(MINGW) if(MINGW)
list(APPEND QT5_LIBRARIES qtfreetype) list(APPEND QT5_EXTRA_LIBRARIES qtfreetype)
if(CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
list(APPEND QT5_LIBRARIES D3D11 Dwrite D2d1) list(APPEND QT5_EXTRA_LIBRARIES D3D11 Dwrite D2d1)
endif() endif()
endif() endif()
set(QT5_LIBRARIES
${QT5_EXTRA_LIBRARIES}
${QT5_LIBRARIES}
)
set(QT5_INTEGRATION_LIBRARIES_LIST
Qt5EventDispatcherSupport
Qt5PacketProtocol
Qt5ThemeSupport
Qt5FontDatabaseSupport
)
if(UNIX AND NOT APPLE)
list(APPEND QT5_INTEGRATION_LIBRARIES_LIST
Qt5XcbQpa
xcb-static
Qt5ServiceSupport
Qt5GlxSupport
)
endif()
foreach(LIBRARY ${QT5_INTEGRATION_LIBRARIES_LIST})
find_library(${LIBRARY}_LIBRARY ${LIBRARY} PATHS ${QT5_EXTRA_PATHS} REQUIRED)
list(APPEND QT5_LIBRARIES ${${LIBRARY}_LIBRARY})
endforeach()
if(UNIX AND NOT APPLE)
pkg_check_modules(X11XCB_XCBGLX_FONTCONFIG REQUIRED x11-xcb xcb-glx fontconfig)
list(APPEND QT5_LIBRARIES ${X11XCB_XCBGLX_FONTCONFIG_STATIC_LIBRARIES})
endif()
endif() endif()
message(STATUS "Using Boost include dir at ${Boost_INCLUDE_DIRS}") message(STATUS "Using Boost include dir at ${Boost_INCLUDE_DIRS}")
@@ -304,7 +389,9 @@ if(MINGW)
else() else()
set(ICU_LIBRARIES icuio icuin icuuc icudt icutu iconv) set(ICU_LIBRARIES icuio icuin icuuc icudt icutu iconv)
endif() endif()
elseif(APPLE OR OPENBSD OR ANDROID) elseif(APPLE)
set(EXTRA_LIBRARIES "-framework AppKit")
elseif(OPENBSD OR ANDROID)
set(EXTRA_LIBRARIES "") set(EXTRA_LIBRARIES "")
elseif(FREEBSD) elseif(FREEBSD)
set(EXTRA_LIBRARIES execinfo) set(EXTRA_LIBRARIES execinfo)
@@ -336,6 +423,8 @@ if(APPLE)
endif() endif()
# warnings # warnings
add_c_flag_if_supported(-Werror C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-Werror CXX_SECURITY_FLAGS)
add_c_flag_if_supported(-Wformat C_SECURITY_FLAGS) add_c_flag_if_supported(-Wformat C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-Wformat CXX_SECURITY_FLAGS) add_cxx_flag_if_supported(-Wformat CXX_SECURITY_FLAGS)
add_c_flag_if_supported(-Wformat-security C_SECURITY_FLAGS) add_c_flag_if_supported(-Wformat-security C_SECURITY_FLAGS)
@@ -366,7 +455,7 @@ if (NOT (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_C_COMPILER_VERSION VER
endif() endif()
# linker # linker
if (NOT (WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "GNU")) if (NOT APPLE AND NOT (WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "GNU"))
# Windows binaries die on startup with PIE when compiled with GCC # Windows binaries die on startup with PIE when compiled with GCC
add_linker_flag_if_supported(-pie LD_SECURITY_FLAGS) add_linker_flag_if_supported(-pie LD_SECURITY_FLAGS)
endif() endif()
@@ -381,13 +470,36 @@ if (noexecheap_SUPPORTED)
set(LD_SECURITY_FLAGS "${LD_SECURITY_FLAGS} -Wl,-z,noexecheap") set(LD_SECURITY_FLAGS "${LD_SECURITY_FLAGS} -Wl,-z,noexecheap")
endif() endif()
# some windows linker bits
if (WIN32)
add_linker_flag_if_supported(-Wl,--dynamicbase LD_SECURITY_FLAGS)
add_linker_flag_if_supported(-Wl,--nxcompat LD_SECURITY_FLAGS)
add_linker_flag_if_supported(-Wl,--high-entropy-va LD_SECURITY_FLAGS)
endif()
if(STATIC)
add_linker_flag_if_supported(-static-libgcc STATIC_FLAGS)
add_linker_flag_if_supported(-static-libstdc++ STATIC_FLAGS)
if(MINGW)
add_linker_flag_if_supported(-static STATIC_FLAGS)
endif()
endif()
# With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that
# is fixed in the code (Issue #847), force compiler to be conservative.
add_c_flag_if_supported(-fno-strict-aliasing C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-fno-strict-aliasing CXX_SECURITY_FLAGS)
add_c_flag_if_supported(-fPIC C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-fPIC CXX_SECURITY_FLAGS)
message(STATUS "Using C security hardening flags: ${C_SECURITY_FLAGS}") message(STATUS "Using C security hardening flags: ${C_SECURITY_FLAGS}")
message(STATUS "Using C++ security hardening flags: ${CXX_SECURITY_FLAGS}") message(STATUS "Using C++ security hardening flags: ${CXX_SECURITY_FLAGS}")
message(STATUS "Using linker security hardening flags: ${LD_SECURITY_FLAGS}") message(STATUS "Using linker security hardening flags: ${LD_SECURITY_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_SECURITY_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 ${C_SECURITY_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_SECURITY_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${CXX_SECURITY_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LD_SECURITY_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LD_SECURITY_FLAGS} ${STATIC_FLAGS}")
if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED) if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
if (APPLE) if (APPLE)
@@ -405,8 +517,6 @@ if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
endif() endif()
endif() endif()
add_subdirectory(translations)
add_subdirectory(src) add_subdirectory(src)
# Required to make wallet_merged build before the gui
add_dependencies(monero-gui wallet_merged)

64
DEPLOY.md Normal file
View File

@@ -0,0 +1,64 @@
# macOS:
Use macOS 10.12 - 10.13 for better backwards compability.
1. `HOMEBREW_OPTFLAGS="-march=core2" HOMEBREW_OPTIMIZATION_LEVEL="O0" brew install boost zmq libpgm miniupnpc libsodium expat libunwind-headers protobuf libgcrypt`
2. `HOMEBREW_OPTFLAGS="-march=core2" HOMEBREW_OPTIMIZATION_LEVEL="O0" brew install --HEAD hidapi`
3. Get the latest LTS from here: https://www.qt.io/offline-installers and install
4. `export PATH=$PATH:$HOME/Qt5.12.8/5.12.8/clang_64/bin`
5. `git clone https://github.com/monero-project/monero-gui`
6. `git checkout v0.X.Y.Z`
7. `sed -i '' s/ARCH=\"native\"/ARCH=\"x86-64\"/g get_libwallet_api.sh`
8. `sed -i '' s/-O2/-O0/g monero-wallet-gui.pro`
9. `./build.sh`
10. `cd build && make deploy`
11. `cd release/bin/monero-wallet-gui.app/Contents/PlugIns/imageformats/`
12. `cp ~/Qt5.12.8/5.12.8/clang_64/plugins/imageformats/libqsvg.dylib .`
13. `install_name_tool -change ~/Qt5.12.8/5.12.8/clang_64/clang_64/lib/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui libqsvg.dylib`
14. `install_name_tool -change ~/Qt5.12.8/5.12.8/clang_64/clang_64/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui libqsvg.dylib`
15. `install_name_tool -change ~/Qt5.12.8/5.12.8/clang_64/lib/QtSvg.framework/Versions/5/QtSvg @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui libqsvg.dylib`
16. `install_name_tool -change ~/Qt5.12.8/5.12.8/clang_64/clang_64/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui libqsvg.dylib`
17. Replace the `monerod` binary inside `monero-wallet-gui.app/Contents/MacOS/` with one built using deterministic builds / gitian.
## Codesigning and notarizing
1. Save the following text as `entitlements.plist`
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
</dict>
</plist>
```
2. `codesign --deep --force --verify --verbose --options runtime --timestamp --entitlements entitlements.plist --sign 'XXXXXXXXXX' monero-wallet-gui.app`
You can check if this step worked by using `codesign -dvvv monero-wallet-gui.app`
3. `hdiutil create -fs HFS+ -srcfolder monero-gui-v0.X.Y.Z -volname monero-wallet-gui monero-gui-mac-x64-v0.X.Y.Z.dmg`
4. `xcrun altool -t osx --file monero-gui-mac-x64-v0.X.Y.Z.dmg --primary-bundle-id org.monero-project.monero-wallet-gui.dmg --notarize-app --username email@address.org`
5. `xcrun altool --notarization-info aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee -u email@address.org`
6. `xcrun stapler staple -v monero-gui-mac-x64-v0.X.Y.Z.dmg`

185
Dockerfile Normal file
View File

@@ -0,0 +1,185 @@
FROM ubuntu:16.04
ARG THREADS=1
RUN apt update
RUN apt install -y automake git pkg-config python xutils-dev && \
git clone -b xorgproto-2020.1 --depth 1 https://gitlab.freedesktop.org/xorg/proto/xorgproto && \
cd xorgproto && \
git reset --hard c62e8203402cafafa5ba0357b6d1c019156c9f36 && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b 1.12 --depth 1 https://gitlab.freedesktop.org/xorg/proto/xcbproto && \
cd xcbproto && \
git reset --hard 6398e42131eedddde0d98759067dde933191f049 && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \
make -j$THREADS install
RUN apt install -y libtool-bin && \
git clone -b libXau-1.0.9 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxau && \
cd libxau && \
git reset --hard d9443b2c57b512cfb250b35707378654d86c7dea && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \
make -j$THREADS install
RUN apt install -y libpthread-stubs0-dev && \
git clone -b 1.12 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxcb && \
cd libxcb && \
git reset --hard d34785a34f28fa6a00f8ce00d87e3132ff0f6467 && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b v1.2.11 --depth 1 https://github.com/madler/zlib && \
cd zlib && \
git reset --hard cacf7f1d4e3d44d871b605da3b647f07d718623f && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --static && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b VER-2-10-2 --depth 1 https://git.sv.nongnu.org/r/freetype/freetype2.git && \
cd freetype2 && \
git reset --hard 132f19b779828b194b3fede187cee719785db4d8 && \
./autogen.sh && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static --with-zlib=no && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b R_2_2_9 --depth 1 https://github.com/libexpat/libexpat && \
cd libexpat/expat && \
git reset --hard a7bc26b69768f7fb24f0c7976fae24b157b85b13 && \
./buildconf.sh && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static && \
make -j$THREADS && \
make -j$THREADS install
RUN apt install -y autopoint gettext gperf libpng12-dev && \
git clone -b 2.13.92 --depth 1 https://gitlab.freedesktop.org/fontconfig/fontconfig && \
cd fontconfig && \
git reset --hard b1df1101a643ae16cdfa1d83b939de2497b1bf27 && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static --sysconfdir=/etc --localstatedir=/var && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b release-64-2 --depth 1 https://github.com/unicode-org/icu && \
cd icu/icu4c/source && \
git reset --hard e2d85306162d3a0691b070b4f0a73e4012433444 && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static --disable-tests --disable-samples && \
make -j$THREADS && \
make -j$THREADS install
RUN apt install -y wget && \
wget https://dl.bintray.com/boostorg/release/1.73.0/source/boost_1_73_0.tar.gz && \
echo "9995e192e68528793755692917f9eb6422f3052a53c5e13ba278a228af6c7acf boost_1_73_0.tar.gz" > hashsum.txt && \
sha256sum -c hashsum.txt && \
tar -xvzf boost_1_73_0.tar.gz && \
cd boost_1_73_0 && \
./bootstrap.sh && \
./b2 --with-atomic --with-system --with-filesystem --with-thread --with-date_time --with-chrono --with-regex --with-serialization --with-program_options --with-locale variant=release link=static runtime-link=static cflags='-fPIC' cxxflags='-fPIC' install -a --prefix=/usr
RUN wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz && \
echo "ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46 openssl-1.1.1g.tar.gz" > hashsum.txt && \
sha256sum -c hashsum.txt && \
tar -xzf openssl-1.1.1g.tar.gz && \
cd openssl-1.1.1g && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./config no-asm no-shared no-zlib-dynamic --openssldir=/usr && \
make -j$THREADS && \
make -j$THREADS install
RUN wget https://download.qt.io/archive/qt/5.9/5.9.7/single/qt-everywhere-opensource-src-5.9.7.tar.xz && \
echo "1c3852aa48b5a1310108382fb8f6185560cefc3802e81ecc099f4e62ee38516c qt-everywhere-opensource-src-5.9.7.tar.xz" > hashsum.txt && \
sha256sum -c hashsum.txt && \
tar -xf qt-everywhere-opensource-src-5.9.7.tar.xz
RUN apt install -y libgl1-mesa-dev libglib2.0-dev libxkbcommon-dev && \
cd qt-everywhere-opensource-src-5.9.7 && \
sed -ri s/\(Libs:.*\)/\\1\ -lexpat/ /usr/local/lib/pkgconfig/fontconfig.pc && \
sed -ri s/\(Libs:.*\)/\\1\ -lz/ /usr/local/lib/pkgconfig/freetype2.pc && \
sed -ri s/\(Libs:.*\)/\\1\ -lXau/ /usr/local/lib/pkgconfig/xcb.pc && \
./configure --prefix=/usr -platform linux-g++-64 -opensource -confirm-license -release -static -no-avx \
-opengl desktop -qpa xcb -system-freetype -fontconfig -glib \
-no-dbus -no-openssl -no-sql-sqlite -no-use-gold-linker \
-qt-harfbuzz -qt-libjpeg -qt-libpng -qt-pcre -qt-zlib \
-skip qt3d -skip qtandroidextras -skip qtcanvas3d -skip qtcharts -skip qtconnectivity -skip qtdatavis3d \
-skip qtdoc -skip qtgamepad -skip qtlocation -skip qtmacextras -skip qtnetworkauth -skip qtpurchasing \
-skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport -skip qtspeech -skip qttools \
-skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview \
-skip qtwinextras -skip qtx11extras -skip gamepad -skip serialbus -skip location -skip webengine \
-nomake examples -nomake tests -nomake tools && \
make -j$THREADS && \
make -j$THREADS install
RUN cd qt-everywhere-opensource-src-5.9.7/qttools/src/linguist/lrelease && \
qmake && \
make -j$THREADS && \
make -j$THREADS install
RUN apt install -y libudev-dev && \
git clone -b v1.0.23 --depth 1 https://github.com/libusb/libusb && \
cd libusb && \
git reset --hard e782eeb2514266f6738e242cdcb18e3ae1ed06fa && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b hidapi-0.9.0 --depth 1 https://github.com/libusb/hidapi && \
cd hidapi && \
git reset --hard 7da5cc91fc0d2dbe4df4f08cd31f6ca1a262418f && \
./bootstrap && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b libX11-1.6.9 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libx11 && \
cd libx11 && \
git reset --hard db7cca17ad7807e92a928da9d4c68a00f4836da2 && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b libXext-1.3.4 --depth 1 https://gitlab.freedesktop.org/xorg/lib/libxext && \
cd libxext && \
git reset --hard ebb167f34a3514783966775fb12573c4ed209625 && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./autogen.sh --disable-shared --enable-static && \
make -j$THREADS && \
make -j$THREADS install
RUN apt install -y libsodium-dev && \
git clone -b v4.3.2 --depth 1 https://github.com/zeromq/libzmq && \
cd libzmq && \
git reset --hard a84ffa12b2eb3569ced199660bac5ad128bff1f0 && \
./autogen.sh && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static --disable-libunwind --with-libsodium && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b libgpg-error-1.38 --depth 1 git://git.gnupg.org/libgpg-error.git && \
cd libgpg-error && \
git reset --hard 71d278824c5fe61865f7927a2ed1aa3115f9e439 && \
./autogen.sh && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static --disable-doc --disable-tests && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b libgcrypt-1.8.5 --depth 1 git://git.gnupg.org/libgcrypt.git && \
cd libgcrypt && \
git reset --hard 56606331bc2a80536db9fc11ad53695126007298 && \
./autogen.sh && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --disable-shared --enable-static --disable-doc && \
make -j$THREADS && \
make -j$THREADS install
RUN git clone -b v3.10.0 --depth 1 https://github.com/protocolbuffers/protobuf && \
cd protobuf && \
git reset --hard 6d4e7fd7966c989e38024a8ea693db83758944f1 && \
./autogen.sh && \
CFLAGS='-fPIC' CXXFLAGS='-fPIC' ./configure --enable-static --disable-shared && \
make -j$THREADS && \
make -j$THREADS install
RUN apt install -y cmake libusb-1.0-0-dev

View File

@@ -64,7 +64,6 @@ Rectangle {
signal addressBookClicked() signal addressBookClicked()
signal miningClicked() signal miningClicked()
signal signClicked() signal signClicked()
signal merchantClicked()
signal accountClicked() signal accountClicked()
function selectItem(pos) { function selectItem(pos) {
@@ -72,7 +71,6 @@ Rectangle {
if(pos === "History") menuColumn.previousButton = historyButton if(pos === "History") menuColumn.previousButton = historyButton
else if(pos === "Transfer") menuColumn.previousButton = transferButton else if(pos === "Transfer") menuColumn.previousButton = transferButton
else if(pos === "Receive") menuColumn.previousButton = receiveButton else if(pos === "Receive") menuColumn.previousButton = receiveButton
else if(pos === "Merchant") menuColumn.previousButton = merchantButton
else if(pos === "AddressBook") menuColumn.previousButton = addressBookButton else if(pos === "AddressBook") menuColumn.previousButton = addressBookButton
else if(pos === "Mining") menuColumn.previousButton = miningButton else if(pos === "Mining") menuColumn.previousButton = miningButton
else if(pos === "TxKey") menuColumn.previousButton = txkeyButton else if(pos === "TxKey") menuColumn.previousButton = txkeyButton
@@ -265,6 +263,10 @@ Rectangle {
anchors.leftMargin: 58 anchors.leftMargin: 58
anchors.baseline: currencyLabel.baseline anchors.baseline: currencyLabel.baseline
color: MoneroComponents.Style.blackTheme ? "white" : "black" color: MoneroComponents.Style.blackTheme ? "white" : "black"
Binding on color {
when: balancePart1MouseArea.containsMouse || balancePart2MouseArea.containsMouse
value: MoneroComponents.Style.orange
}
text: { text: {
if (persistentSettings.fiatPriceEnabled && persistentSettings.fiatPriceToggle) { if (persistentSettings.fiatPriceEnabled && persistentSettings.fiatPriceToggle) {
return balanceFiatString.split('.')[0] + "." return balanceFiatString.split('.')[0] + "."
@@ -286,14 +288,6 @@ Rectangle {
hoverEnabled: true hoverEnabled: true
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onEntered: {
balancePart1.color = MoneroComponents.Style.orange
balancePart2.color = MoneroComponents.Style.orange
}
onExited: {
balancePart1.color = Qt.binding(function() { return MoneroComponents.Style.blackTheme ? "white" : "black" })
balancePart2.color = Qt.binding(function() { return MoneroComponents.Style.blackTheme ? "white" : "black" })
}
onClicked: { onClicked: {
console.log("Copied to clipboard"); console.log("Copied to clipboard");
clipboard.setText(balancePart1.text + balancePart2.text); clipboard.setText(balancePart1.text + balancePart2.text);
@@ -307,7 +301,7 @@ Rectangle {
anchors.left: balancePart1.right anchors.left: balancePart1.right
anchors.leftMargin: 2 anchors.leftMargin: 2
anchors.baseline: currencyLabel.baseline anchors.baseline: currencyLabel.baseline
color: MoneroComponents.Style.blackTheme ? "white" : "black" color: balancePart1.color
text: { text: {
if (persistentSettings.fiatPriceEnabled && persistentSettings.fiatPriceToggle) { if (persistentSettings.fiatPriceEnabled && persistentSettings.fiatPriceToggle) {
return balanceFiatString.split('.')[1] return balanceFiatString.split('.')[1]
@@ -317,11 +311,10 @@ Rectangle {
} }
font.pixelSize: 16 font.pixelSize: 16
MouseArea { MouseArea {
id: balancePart2MouseArea
hoverEnabled: true hoverEnabled: true
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onEntered: balancePart1MouseArea.entered()
onExited: balancePart1MouseArea.exited()
onClicked: balancePart1MouseArea.clicked(mouse) onClicked: balancePart1MouseArea.clicked(mouse)
} }
} }
@@ -348,7 +341,7 @@ Rectangle {
id:flicker id:flicker
contentHeight: menuColumn.height contentHeight: menuColumn.height
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: networkStatus.top anchors.bottom: progressBar.visible ? progressBar.top : networkStatus.top
width: parent.width width: parent.width
boundsBehavior: isMac ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds boundsBehavior: isMac ? Flickable.DragAndOvershootBounds : Flickable.StopAtBounds
clip: true clip: true
@@ -454,30 +447,6 @@ Rectangle {
anchors.leftMargin: 20 anchors.leftMargin: 20
} }
// ------------- Merchant tab ---------------
MoneroComponents.MenuButton {
id: merchantButton
visible: appWindow.walletMode >= 2
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Merchant") + translationManager.emptyString
symbol: qsTr("U") + translationManager.emptyString
under: receiveButton
onClicked: {
parent.previousButton.checked = false
parent.previousButton = merchantButton
panel.merchantClicked()
}
}
MoneroComponents.MenuButtonDivider {
visible: merchantButton.present && appWindow.walletMode >= 2
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 20
}
// ------------- History tab --------------- // ------------- History tab ---------------
MoneroComponents.MenuButton { MoneroComponents.MenuButton {
@@ -644,22 +613,11 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
anchors.leftMargin: 0 anchors.leftMargin: 0
anchors.rightMargin: 0 anchors.rightMargin: 0
anchors.bottom: networkStatus.top; anchors.bottom: progressBar.visible ? progressBar.top : networkStatus.top
height: 10 height: 10
color: "transparent" color: "transparent"
} }
MoneroComponents.NetworkStatusItem {
id: networkStatus
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 5
anchors.rightMargin: 0
anchors.bottom: (progressBar.visible)? progressBar.top : parent.bottom;
connected: Wallet.ConnectionStatus_Disconnected
height: 48
}
MoneroComponents.ProgressBar { MoneroComponents.ProgressBar {
id: progressBar id: progressBar
anchors.left: parent.left anchors.left: parent.left
@@ -667,17 +625,29 @@ Rectangle {
anchors.bottom: daemonProgressBar.top anchors.bottom: daemonProgressBar.top
height: 48 height: 48
syncType: qsTr("Wallet") + translationManager.emptyString syncType: qsTr("Wallet") + translationManager.emptyString
visible: networkStatus.connected visible: !appWindow.disconnected
} }
MoneroComponents.ProgressBar { MoneroComponents.ProgressBar {
id: daemonProgressBar id: daemonProgressBar
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: networkStatus.top
syncType: qsTr("Daemon") + translationManager.emptyString syncType: qsTr("Daemon") + translationManager.emptyString
visible: networkStatus.connected visible: !appWindow.disconnected
height: 62 height: 62
} }
MoneroComponents.NetworkStatusItem {
id: networkStatus
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 5
anchors.rightMargin: 0
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
connected: Wallet.ConnectionStatus_Disconnected
height: 48
}
} }
} }

View File

@@ -28,13 +28,21 @@ clean:
scanner: scanner:
mkdir -p build && cd build && cmake -D ARCH="x86-64" -D DEV_MODE=$(or ${DEV_MODE},ON) -D WITH_SCANNER=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release .. && $(MAKE) mkdir -p build && cd build && cmake -D ARCH="x86-64" -D DEV_MODE=$(or ${DEV_MODE},ON) -D WITH_SCANNER=ON -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release .. && $(MAKE)
release:
mkdir -p $(builddir)/release && cd $(builddir)/release && cmake -D DEV_MODE=$(or ${DEV_MODE},OFF) -D ARCH="x86-64" -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
release-static:
mkdir -p $(builddir)/release && cd $(builddir)/release && cmake -D STATIC=ON -D DEV_MODE=$(or ${DEV_MODE},OFF) -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release $(topdir) && $(MAKE)
debug-static-win64: debug-static-win64:
mkdir -p $(builddir)/debug && cd $(builddir)/debug && cmake -D STATIC=ON -G "MSYS Makefiles" -D DEV_MODE=$(or ${DEV_MODE},ON) -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Debug -D BUILD_TAG="win-x64" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys64 -D MINGW=ON $(topdir) && $(MAKE) mkdir -p $(builddir)/debug && cd $(builddir)/debug && cmake -D STATIC=ON -G "MSYS Makefiles" -D DEV_MODE=$(or ${DEV_MODE},ON) -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Debug -D BUILD_TAG="win-x64" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=$(shell cd ${MINGW_PREFIX}/.. && pwd -W) -D MINGW=ON $(topdir) && $(MAKE)
debug-static-mac64: debug-static-mac64:
mkdir -p $(builddir)/debug mkdir -p $(builddir)/debug
cd $(builddir)/debug && cmake -D STATIC=ON -D DEV_MODE=$(or ${DEV_MODE},ON) -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="mac-x64" $(topdir) && $(MAKE) cd $(builddir)/debug && cmake -D STATIC=ON -D DEV_MODE=$(or ${DEV_MODE},ON) -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=release -D BUILD_TAG="mac-x64" $(topdir) && $(MAKE)
release-static-win64: release-static-win64:
mkdir -p $(builddir)/release && cd $(builddir)/release && cmake -D STATIC=ON -G "MSYS Makefiles" -D DEV_MODE=$(or ${DEV_MODE},OFF) -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="win-x64" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys64 -D MINGW=ON $(topdir) && $(MAKE) mkdir -p $(builddir)/release && cd $(builddir)/release && cmake -D STATIC=ON -G "MSYS Makefiles" -D DEV_MODE=$(or ${DEV_MODE},OFF) -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="win-x64" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=$(shell cd ${MINGW_PREFIX}/.. && pwd -W) -D MINGW=ON $(topdir) && $(MAKE)
release-win64:
mkdir -p $(builddir)/release && cd $(builddir)/release && cmake -D STATIC=OFF -G "MSYS Makefiles" -D DEV_MODE=$(or ${DEV_MODE},OFF) -D ARCH="x86-64" -D BUILD_64=ON -D CMAKE_BUILD_TYPE=Release -D BUILD_TAG="win-x64" -D CMAKE_TOOLCHAIN_FILE=$(topdir)/cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=$(shell cd ${MINGW_PREFIX}/.. && pwd -W) -D MINGW=ON $(topdir) && $(MAKE)

View File

@@ -50,7 +50,10 @@ Rectangle {
property alias contentHeight: mainFlickable.contentHeight property alias contentHeight: mainFlickable.contentHeight
property alias flickable: mainFlickable property alias flickable: mainFlickable
property Transfer transferView: Transfer { } property Transfer transferView: Transfer {
onPaymentClicked: root.paymentClicked(address, paymentId, amount, mixinCount, priority, description)
onSweepUnmixableClicked: root.sweepUnmixableClicked()
}
property Receive receiveView: Receive { } property Receive receiveView: Receive { }
property Merchant merchantView: Merchant { } property Merchant merchantView: Merchant { }
property TxKey txkeyView: TxKey { } property TxKey txkeyView: TxKey { }
@@ -260,18 +263,4 @@ Rectangle {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: borderLeft.right anchors.left: borderLeft.right
} }
/* connect "payment" click */
Connections {
ignoreUnknownSignals: false
target: transferView
onPaymentClicked : {
console.log("MiddlePanel: paymentClicked")
paymentClicked(address, paymentId, amount, mixinCount, priority, description)
}
onSweepUnmixableClicked : {
console.log("MiddlePanel: sweepUnmixableClicked")
sweepUnmixableClicked()
}
}
} }

View File

@@ -5,11 +5,11 @@ Copyright (c) 2014-2019, The Monero Project
## Development resources ## Development resources
- Web: [getmonero.org](https://getmonero.org) - Web: [getmonero.org](https://getmonero.org)
- Forum: [forum.getmonero.org](https://forum.getmonero.org)
- Mail: [dev@getmonero.org](mailto:dev@getmonero.org) - Mail: [dev@getmonero.org](mailto:dev@getmonero.org)
- Github: [https://github.com/monero-project/monero-gui](https://github.com/monero-project/monero-gui) - Github: [https://github.com/monero-project/monero-gui](https://github.com/monero-project/monero-gui)
- IRC: [#monero-dev on Freenode](irc://chat.freenode.net/#monero-dev) - IRC: [#monero-dev on Freenode](irc://chat.freenode.net/#monero-dev)
- Translation platform (Weblate): [translate.getmonero.org](https://translate.getmonero.org) - Translation platform (Weblate): [translate.getmonero.org](https://translate.getmonero.org)
- UI Design: [Monero-GUI on Figma](https://www.figma.com/file/DplJ2DDQfIKiuRvolHX2hN/Monero-GUI)
## Vulnerability response ## Vulnerability response
@@ -36,7 +36,7 @@ As with many development projects, the repository on Github is considered to be
Monero is a 100% community-sponsored endeavor. If you want to join our efforts, the easiest thing you can do is support the project financially. Both Monero and Bitcoin donations can be made to **donate.getmonero.org** if using a client that supports the [OpenAlias](https://openalias.org) standard. Monero is a 100% community-sponsored endeavor. If you want to join our efforts, the easiest thing you can do is support the project financially. Both Monero and Bitcoin donations can be made to **donate.getmonero.org** if using a client that supports the [OpenAlias](https://openalias.org) standard.
The Monero donation address is: `44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A` (viewkey: `f359631075708155cc3d92a32b75a7d02a5dcf27756707b47a2b31b21c389501`) The Monero donation address is: `888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H` (viewkey: `f359631075708155cc3d92a32b75a7d02a5dcf27756707b47a2b31b21c389501`)
The Bitcoin donation address is: `1KTexdemPdxSBcG55heUuTjDRYqbC5ZL8H` The Bitcoin donation address is: `1KTexdemPdxSBcG55heUuTjDRYqbC5ZL8H`
@@ -58,16 +58,20 @@ See [LICENSE](LICENSE).
## Translations ## Translations
Do you speak a second language and would like to help translate the Monero GUI? Check out Pootle, our localization platform, at [translate.getmonero.org](https://translate.getmonero.org/projects/monero-gui/). Choose the language and suggest a translation for a string or review an existing one. The Localization Workgroup made [a guide with step-by-step instructions](https://github.com/monero-ecosystem/monero-translations/blob/master/pootle.md) for Pootle. Do you speak a second language and would like to help translate the Monero GUI? Check out Weblate, our localization platform, at [translate.getmonero.org](https://translate.getmonero.org/). Choose the language and suggest a translation for a string or review an existing one. The Localization Workgroup made [a guide with step-by-step instructions](https://github.com/monero-ecosystem/monero-translations/blob/master/weblate.md) for Weblate.
&nbsp;
If you need help/support or any info you can contact the localization workgroup on the IRC channel #monero-translations (relayed on matrix/riot and MatterMost) or by email at translate[at]getmonero[dot]org. For more info about the Localization workgroup: [github.com/monero-ecosystem/monero-translations](https://github.com/monero-ecosystem/monero-translations) If you need help/support or any info you can contact the localization workgroup on the IRC channel #monero-translations (relayed on matrix/riot and MatterMost) or by email at translate[at]getmonero[dot]org. For more info about the Localization workgroup: [github.com/monero-ecosystem/monero-translations](https://github.com/monero-ecosystem/monero-translations)
Status of the translations:
<a href="https://translate.getmonero.org/engage/monero/?utm_source=widget">
<img src="https://translate.getmonero.org/widgets/monero/-/gui-wallet/horizontal-auto.svg" alt="Translation status" />
</a>
## Installing the Monero GUI from a package ## Installing the Monero GUI from a package
Packages are available for Packages are available for
* Arch Linux via AUR: [monero-wallet-qt](https://aur.archlinux.org/packages/monero-wallet-qt/) * Arch Linux: pacman -S monero-gui
* Void Linux: xbps-install -S monero-core * Void Linux: xbps-install -S monero-core
* GuixSD: guix package -i monero-core * GuixSD: guix package -i monero-core
@@ -77,6 +81,28 @@ Packaging for your favorite distribution would be a welcome contribution!
*Note*: Qt 5.9.7 is the minimum version required to build the GUI. *Note*: Qt 5.9.7 is the minimum version required to build the GUI.
### Building Linux static binaries with Docker (any OS)
1. Install Docker [https://docs.docker.com/engine/install/](https://docs.docker.com/engine/install/)
2. Clone the repository
```
git clone --recursive https://github.com/monero-project/monero-gui.git
```
3. Prepare build environment
```
cd monero-gui
docker build --tag monero:build-env-gui --build-arg THREADS=4 .
```
\* `4` - number of CPU threads to use
4. Build
```
docker run --rm -it -v <MONERO_GUI_DIR_FULL_PATH>:/monero-gui -w /monero-gui monero:build-env-gui sh -c 'USE_SINGLE_BUILDDIR=ON DEV_MODE=ON make release-static -j4'
```
\* `<MONERO_GUI_DIR_FULL_PATH>` - absolute path to `monero-gui` directory
\* `4` - number of CPU threads to use
5. Monero GUI Linux static binaries will be placed in `monero-gui/build/release/bin` directory
### On Linux: ### On Linux:
(Tested on Ubuntu 17.10 x64, Ubuntu 18.04 x64 and Gentoo x64) (Tested on Ubuntu 17.10 x64, Ubuntu 18.04 x64 and Gentoo x64)
@@ -85,15 +111,15 @@ Packaging for your favorite distribution would be a welcome contribution!
- For Debian distributions (Debian, Ubuntu, Mint, Tails...) - For Debian distributions (Debian, Ubuntu, Mint, Tails...)
`sudo apt install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev` `sudo apt install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler libgcrypt20-dev`
- For Gentoo - For Gentoo
`sudo emerge app-arch/xz-utils app-doc/doxygen dev-cpp/gtest dev-libs/boost dev-libs/expat dev-libs/openssl dev-util/cmake media-gfx/graphviz net-dns/unbound net-libs/ldns net-libs/miniupnpc net-libs/zeromq sys-libs/libunwind dev-libs/libsodium dev-libs/hidapi` `sudo emerge app-arch/xz-utils app-doc/doxygen dev-cpp/gtest dev-libs/boost dev-libs/expat dev-libs/openssl dev-util/cmake media-gfx/graphviz net-dns/unbound net-libs/ldns net-libs/miniupnpc net-libs/zeromq sys-libs/libunwind dev-libs/libsodium dev-libs/hidapi dev-libs/libgcrypt`
- For Fedora - For Fedora
`sudo dnf install make automake cmake gcc-c++ boost-devel miniupnpc-devel graphviz doxygen unbound-devel libunwind-devel pkgconfig openssl-devel libcurl-devel hidapi-devel libusb-devel zeromq-devel` `sudo dnf install make automake cmake gcc-c++ boost-devel miniupnpc-devel graphviz doxygen unbound-devel libunwind-devel pkgconfig openssl-devel libcurl-devel hidapi-devel libusb-devel zeromq-devel libgcrypt-devel`
2. Install Qt: 2. Install Qt:
@@ -145,26 +171,12 @@ The executable can be found in the build/release/bin folder.
3. Install [monero](https://github.com/monero-project/monero) dependencies: 3. Install [monero](https://github.com/monero-project/monero) dependencies:
`brew install boost` `brew install boost hidapi zmq libpgm miniupnpc ldns expat libunwind-headers protobuf libgcrypt`
`brew install openssl` - to install openssl headers
`brew install pkgconfig`
`brew install cmake`
`brew install zeromq`
*Note*: If cmake can not find zmq.hpp file on OS X, installing `zmq.hpp` from https://github.com/zeromq/cppzmq to `/usr/local/include` should fix that error.
4. Install Qt: 4. Install Qt:
`brew install qt5` (or download QT 5.9.7+ from [qt.io](https://www.qt.io/download-open-source/)) `brew install qt5` (or download QT 5.9.7+ 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`
5. Add the Qt bin directory to your path 5. Add the Qt bin directory to your path
- Example for Qt: `export PATH=$PATH:$HOME/Qt/5.9.7/clang_64/bin` - Example for Qt: `export PATH=$PATH:$HOME/Qt/5.9.7/clang_64/bin`
@@ -184,18 +196,7 @@ The executable can be found in the build/release/bin folder.
The executable can be found in the `build/release/bin` folder. The executable can be found in the `build/release/bin` folder.
**Note:** Workaround for "ERROR: Xcode not set up properly" For building an application bundle see `DEPLOY.md`.
Edit `$HOME/Qt/5.9.7/clang_64/mkspecs/features/mac/default_pre.prf`
replace
`isEmpty($$list($$system("/usr/bin/xcrun -find xcrun 2>/dev/null")))`
with
`isEmpty($$list($$system("/usr/bin/xcrun -find xcodebuild 2>/dev/null")))`
More info: http://stackoverflow.com/a/35098040/1683164
### On Windows: ### On Windows:
@@ -208,7 +209,7 @@ The Monero GUI on Windows is 64 bits only; 32-bit Windows GUI builds are not off
3. Install MSYS2 packages for Monero dependencies; the needed 64-bit packages have `x86_64` in their names 3. Install MSYS2 packages for Monero dependencies; the needed 64-bit packages have `x86_64` in their names
``` ```
pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb mingw-w64-x86_64-libgcrypt
``` ```
Optional : To build the flag `WITH_SCANNER` Optional : To build the flag `WITH_SCANNER`

View File

@@ -100,11 +100,8 @@ fi
# force version update # force version update
get_tag get_tag
echo "var GUI_VERSION = \"$TAGNAME\"" > version.js GUI_VERSION=$(echo "$TAGNAME" | sed 's/^v\([[:digit:]]\)/\1/')
pushd "$MONERO_DIR" echo "var GUI_VERSION = \"$GUI_VERSION\"" > version.js
get_tag
popd
echo "var GUI_MONERO_VERSION = \"$TAGNAME\"" >> version.js
cd build cd build
if ! QMAKE=$(find_command qmake qmake-qt5); then if ! QMAKE=$(find_command qmake qmake-qt5); then

56
cmake/FindCcache.cmake Normal file
View File

@@ -0,0 +1,56 @@
# Copyright (c) 2014-2020, 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.
# - Try to find readline include dirs and libraries
#
# Automatically finds ccache build accelerator, if it's found in PATH.
#
# Usage of this module as follows:
#
# project(monero)
# include(FindCcache) # Include AFTER the project() macro to be able to reach the CMAKE_CXX_COMPILER variable
#
# Properties modified by this module:
#
# GLOBAL PROPERTY RULE_LAUNCH_COMPILE set to ccache, when ccache found
# GLOBAL PROPERTY RULE_LAUNCH_LINK set to ccache, when ccache found
find_program(CCACHE_FOUND ccache)
if (CCACHE_FOUND)
set(TEMP_CPP_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test-program.cpp")
file(WRITE "${TEMP_CPP_FILE}" "int main() { return 0; }")
execute_process(COMMAND "${CCACHE_FOUND}" "${CMAKE_CXX_COMPILER}" "${TEMP_CPP_FILE}" RESULT_VARIABLE RET)
if (${RET} EQUAL 0)
message("found usable ccache: ${CCACHE_FOUND}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_FOUND}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE_FOUND}")
else()
message("found ccache ${CCACHE_FOUND}, but is UNUSABLE! Return code: ${RET}")
endif()
else()
message("ccache NOT found!")
endif()

View File

@@ -28,37 +28,40 @@
# #
# Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers # Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
# Check what commit we're on function (git_get_version_tag git directory result_var)
execute_process(COMMAND "${GIT}" rev-parse --short=9 HEAD RESULT_VARIABLE RET OUTPUT_VARIABLE COMMIT OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND "${git}" rev-parse --short HEAD
WORKING_DIRECTORY ${directory}
OUTPUT_VARIABLE COMMIT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT COMMIT)
message(WARNING "${directory}: cannot determine current commit. Make sure that you are building from a Git working tree")
set(${result_var} "unknown" PARENT_SCOPE)
return()
endif()
if(RET) execute_process(COMMAND "${git}" describe --tags --exact-match
# Something went wrong, set the version tag to -unknown WORKING_DIRECTORY ${directory}
OUTPUT_VARIABLE TAG
message(WARNING "Cannot determine current commit. Make sure that you are building either from a Git working tree or from a source archive.") OUTPUT_STRIP_TRAILING_WHITESPACE
set(VERSIONTAG "unknown") )
configure_file("src/version.js.in" "${TO}") if(TAG)
else() message(STATUS "${directory}: building tagged release ${TAG}-${COMMIT}")
string(SUBSTRING ${COMMIT} 0 9 COMMIT) set(${result_var} "${TAG}-${COMMIT}" PARENT_SCOPE)
message(STATUS "You are currently on commit ${COMMIT}") return()
endif()
# Get all the tags
execute_process(COMMAND "${GIT}" rev-list --tags --max-count=1 --abbrev-commit RESULT_VARIABLE RET OUTPUT_VARIABLE TAGGEDCOMMIT OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT TAGGEDCOMMIT)
message(WARNING "Cannot determine most recent tag. Make sure that you are building either from a Git working tree or from a source archive.")
set(VERSIONTAG "${COMMIT}")
else()
message(STATUS "The most recent tag was at ${TAGGEDCOMMIT}")
# Check if we're building that tagged commit or a different one
if(COMMIT STREQUAL TAGGEDCOMMIT)
message(STATUS "You are building a tagged release")
set(VERSIONTAG "release")
else()
message(STATUS "You are ahead of or behind a tagged release")
set(VERSIONTAG "${COMMIT}")
endif()
endif()
configure_file("src/version.js.in" "${TO}") execute_process(COMMAND "${git}" describe --tags --long
endif() WORKING_DIRECTORY ${directory}
OUTPUT_VARIABLE MOST_RECENT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(MOST_RECENT_TAG)
message(STATUS "${directory}: ahead of or behind a tagged release, building ${MOST_RECENT_TAG}")
set(${result_var} "${MOST_RECENT_TAG}" PARENT_SCOPE)
return()
endif()
message(STATUS "${directory}: building ${COMMIT} commit")
set(${result_var} "${COMMIT}" PARENT_SCOPE)
endfunction()

View File

@@ -26,9 +26,8 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # 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. # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function (write_static_version_header hash) function (write_static_version_header VERSION_TAG_GUI)
set(VERSIONTAG "${hash}") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/version.js.in" "${CMAKE_CURRENT_SOURCE_DIR}/version.js")
configure_file("${CMAKE_SOURCE_DIR}/version.js.in" "${CMAKE_SOURCE_DIR}/version.js")
endfunction () endfunction ()
find_package(Git QUIET) find_package(Git QUIET)
@@ -37,16 +36,14 @@ if ("$Format:$" STREQUAL "")
write_static_version_header("release") write_static_version_header("release")
elseif (GIT_FOUND OR Git_FOUND) elseif (GIT_FOUND OR Git_FOUND)
message(STATUS "Found Git: ${GIT_EXECUTABLE}") message(STATUS "Found Git: ${GIT_EXECUTABLE}")
add_custom_command(
OUTPUT "${CMAKE_SOURCE_DIR}/version.js" include(GitGetVersionTag)
COMMAND "${CMAKE_COMMAND}" git_get_version_tag(${GIT_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR} VERSION_TAG_GUI)
"-D" "GIT=${GIT_EXECUTABLE}" STRING(REGEX REPLACE "^v([0-9])" "\\1" VERSION_TAG_GUI ${VERSION_TAG_GUI})
"-D" "TO=${CMAKE_SOURCE_DIR}/version.js" write_static_version_header(${VERSION_TAG_GUI})
"-P" "cmake/GenVersionGui.cmake"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
else() else()
message(STATUS "WARNING: Git was not found!") message(STATUS "WARNING: Git was not found!")
write_static_version_header("unknown") write_static_version_header("unknown")
endif () endif ()
add_custom_target(genversiongui ALL add_custom_target(genversiongui ALL
DEPENDS "${CMAKE_SOURCE_DIR}/version.js") DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/version.js")

View File

@@ -0,0 +1,106 @@
import QtQuick 2.9
import QtQuick.Layouts 1.1
import FontAwesome 1.0
import "../components" as MoneroComponents
RowLayout {
id: advancedOptionsItem
property alias title: title.text
property alias button1: button1
property alias button2: button2
property alias button3: button3
property alias helpTextLarge: helpTextLarge
property alias helpTextSmall: helpTextSmall
RowLayout {
id: titlecolumn
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
Layout.preferredWidth: 195
Layout.maximumWidth: 195
Layout.leftMargin: 10
MoneroComponents.Label {
id: title
fontSize: 14
}
MoneroComponents.Label {
id: iconLabel
fontSize: 12
text: FontAwesome.questionCircle
fontFamily: FontAwesome.fontFamily
opacity: 0.3
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: helpText.visible = !helpText.visible
onEntered: parent.opacity = 0.4
onExited: parent.opacity = 0.3
}
}
Rectangle {
id: separator
Layout.fillWidth: true
height: 10
color: "transparent"
}
}
ColumnLayout {
Layout.fillWidth: false
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
spacing: 4
RowLayout {
Layout.fillWidth: false
spacing: 12
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
StandardButton {
id: button1
small: true
visible: button1.text
}
StandardButton {
id: button2
small: true
visible: button2.text
}
StandardButton {
id: button3
small: true
visible: button3.text
}
}
ColumnLayout {
id: helpText
visible: false
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
MoneroComponents.TextPlain {
id: helpTextLarge
visible: helpTextLarge.text
font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 13
color: MoneroComponents.Style.defaultFontColor
}
MoneroComponents.TextPlain {
id: helpTextSmall
visible: helpTextSmall.text
Layout.leftMargin: 5
textFormat: Text.RichText
font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 12
color: MoneroComponents.Style.defaultFontColor
}
}
}
}

View File

@@ -74,7 +74,7 @@ Item {
visible: checkBox.border visible: checkBox.border
anchors.fill: parent anchors.fill: parent
radius: 3 radius: 3
color: "transparent" color: checkBox.enabled ? "transparent" : MoneroComponents.Style.inputBoxBackgroundDisabled
border.color: border.color:
if(checkBox.checked){ if(checkBox.checked){
return MoneroComponents.Style.inputBorderColorActive; return MoneroComponents.Style.inputBorderColorActive;
@@ -108,7 +108,7 @@ Item {
font.pixelSize: checkBox.fontSize font.pixelSize: checkBox.fontSize
color: MoneroComponents.Style.defaultFontColor color: MoneroComponents.Style.defaultFontColor
textFormat: Text.RichText textFormat: Text.RichText
wrapMode: Text.Wrap wrapMode: Text.NoWrap
} }
} }

View File

@@ -117,7 +117,7 @@ Item {
Connections { Connections {
target: datePicker target: datePicker
onCurrentDateChanged: { function onCurrentDateChanged() {
dateInput.setDate(datePicker.currentDate) dateInput.setDate(datePicker.currentDate)
} }
} }

View File

@@ -0,0 +1,104 @@
// Copyright (c) 2014-2020, 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.9
import "." as MoneroComponents
Item {
id: root
property var onAcceptedCallback
property var onWalletEntryCallback
property var onRejectedCallback
function open(canEnterOnDevice_) {
var canEnterOnDevice = canEnterOnDevice_ !== null ? canEnterOnDevice_ : canEnterOnDevice
root.visible = true;
if (canEnterOnDevice) {
entryChooserDialog.okText = qsTr("Hardware wallet")
entryChooserDialog.cancelText = qsTr("Computer")
entryChooserDialog.open()
} else {
openPassphraseDialog()
}
}
function openPassphraseDialog() {
root.visible = true
passphraseDialog.openPassphraseDialog()
}
function close() {
root.visible = false;
if (entryChooserDialog.visible)
entryChooserDialog.close()
if (passphraseDialog.visible)
passphraseDialog.close()
}
StandardDialog {
id: entryChooserDialog
title: qsTr("Hardware wallet passphrase") + translationManager.emptyString
text: qsTr("Please select where you want to enter passphrase.\nIt is recommended to enter passphrase on the hardware wallet for better security.") + translationManager.emptyString
onAccepted: {
if (onWalletEntryCallback){
onWalletEntryCallback()
}
}
onRejected: {
openPassphraseDialog()
}
onCloseCallback: {
root.close()
}
}
PasswordDialog {
id: passphraseDialog
anchors.fill: parent
passphraseDialogMode: true
onAcceptedPassphrase: {
if (onAcceptedCallback)
onAcceptedCallback(passphraseDialog.password);
}
onRejectedPassphrase: {
if (onRejectedCallback)
onRejectedCallback();
}
onCloseCallback: {
root.close()
}
}
}

View File

@@ -53,6 +53,7 @@ Item {
property alias fontPixelSize: inlineText.font.pixelSize property alias fontPixelSize: inlineText.font.pixelSize
property alias fontFamily: inlineText.font.family property alias fontFamily: inlineText.font.family
property alias buttonColor: rect.color property alias buttonColor: rect.color
property alias buttonHeight: rect.height
signal clicked() signal clicked()
function doClick() { function doClick() {

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2014-2019, The Monero Project // Copyright (c) 2014-2020, The Monero Project
// //
// All rights reserved. // All rights reserved.
// //
@@ -53,7 +53,7 @@ Drawer {
y: titleBar.height y: titleBar.height
background: Rectangle { background: Rectangle {
color: "#0d0d0d" color: MoneroComponents.Style.blackTheme ? "#0d0d0d" : "white"
width: parent.width width: parent.width
} }
@@ -79,9 +79,24 @@ Drawer {
width: sideBar.width width: sideBar.width
height: 32 height: 32
Rectangle {
id: flagRect
height: 24
width: 24
anchors.left: parent.left
anchors.leftMargin: 4
anchors.verticalCenter: parent.verticalCenter
color: "transparent"
Image {
anchors.fill: parent
source: flag
}
}
MoneroComponents.TextPlain { MoneroComponents.TextPlain {
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 16 anchors.leftMargin: 30
font.bold: true font.bold: true
font.pixelSize: 14 font.pixelSize: 14
color: MoneroComponents.Style.defaultFontColor color: MoneroComponents.Style.defaultFontColor
@@ -118,8 +133,10 @@ Drawer {
// set wizard language settings // set wizard language settings
wizard.language_locale = locale; wizard.language_locale = locale;
wizard.language_wallet = wallet_language; wizard.language_wallet = wallet_language;
wizard.language_language = display_name + " (" + locale_spl[1] + ") "; wizard.language_language = display_name;
sideBar.close()
appWindow.showStatusMessage(qsTr("Language changed."), 3);
appWindow.toggleLanguageView();
} }
hoverEnabled: true hoverEnabled: true
onEntered: { onEntered: {
@@ -134,15 +151,8 @@ Drawer {
} }
} }
ScrollIndicator.vertical: ScrollIndicator { ScrollBar.vertical: ScrollBar {
// @TODO: QT 5.9 introduces `policy: ScrollBar.AlwaysOn` onActiveChanged: if (!active && !isMac) active = true
active: true
contentItem.opacity: 0.7
onActiveChanged: {
if (!active) {
active = true;
}
}
} }
} }
} }

View File

@@ -26,6 +26,7 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // 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. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import FontAwesome 1.0
import QtQuick 2.9 import QtQuick 2.9
import QtGraphicalEffects 1.0 import QtGraphicalEffects 1.0
@@ -36,6 +37,10 @@ Item {
property alias input: input property alias input: input
property alias text: input.text property alias text: input.text
property bool password: false
property bool passwordHidden: true
property var passwordLinked: null
property alias placeholderText: placeholderLabel.text property alias placeholderText: placeholderLabel.text
property bool placeholderCenter: false property bool placeholderCenter: false
property string placeholderFontFamily: MoneroComponents.Style.fontRegular.name property string placeholderFontFamily: MoneroComponents.Style.fontRegular.name
@@ -48,7 +53,6 @@ Item {
property alias validator: input.validator property alias validator: input.validator
property alias readOnly : input.readOnly property alias readOnly : input.readOnly
property alias cursorPosition: input.cursorPosition property alias cursorPosition: input.cursorPosition
property alias echoMode: input.echoMode
property alias inlineButton: inlineButtonId property alias inlineButton: inlineButtonId
property alias inlineButtonText: inlineButtonId.text property alias inlineButtonText: inlineButtonId.text
property alias inlineIcon: inlineIcon.visible property alias inlineIcon: inlineIcon.visible
@@ -109,6 +113,31 @@ Item {
} }
} }
function isPasswordHidden() {
if (password) {
return passwordHidden;
}
if (passwordLinked) {
return passwordLinked.passwordHidden;
}
return false;
}
function reset() {
text = "";
if (!passwordLinked) {
passwordHidden = true;
}
}
function passwordToggle() {
if (passwordLinked) {
passwordLinked.passwordHidden = !passwordLinked.passwordHidden;
} else {
passwordHidden = !passwordHidden;
}
}
MoneroComponents.TextPlain { MoneroComponents.TextPlain {
id: inputLabel id: inputLabel
anchors.top: parent.top anchors.top: parent.top
@@ -210,6 +239,27 @@ Item {
onTextChanged: item.textUpdated() onTextChanged: item.textUpdated()
topPadding: 10 topPadding: 10
bottomPadding: 10 bottomPadding: 10
echoMode: isPasswordHidden() ? TextInput.Password : TextInput.Normal
MoneroComponents.Label {
visible: password || passwordLinked
fontSize: 20
text: isPasswordHidden() ? FontAwesome.eye : FontAwesome.eyeSlash
opacity: eyeMouseArea.containsMouse ? 0.9 : 0.7
fontFamily: FontAwesome.fontFamily
anchors.right: parent.right
anchors.rightMargin: 15
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: 1
MouseArea {
id: eyeMouseArea
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onClicked: passwordToggle()
}
}
} }
MoneroComponents.InlineButton { MoneroComponents.InlineButton {

View File

@@ -87,6 +87,8 @@ ColumnLayout {
property alias inlineButton: inlineButtonId property alias inlineButton: inlineButtonId
property bool inlineButtonVisible: false property bool inlineButtonVisible: false
property alias inlineButton2: inlineButton2Id
property bool inlineButton2Visible: false
signal labelButtonClicked(); signal labelButtonClicked();
signal inputLabelLinkActivated(); signal inputLabelLinkActivated();
@@ -202,5 +204,12 @@ ColumnLayout {
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 8 anchors.rightMargin: 8
} }
MoneroComponents.InlineButton {
id: inlineButton2Id
visible: (inlineButton2Id.text || inlineButton2Id.icon) && inlineButton2Visible ? true : false
anchors.right: parent.right
anchors.rightMargin: inlineButtonVisible ? 48 : 8
}
} }
} }

View File

@@ -62,7 +62,7 @@ Rectangle {
height: present ? ((appWindow.height >= 800) ? 44 : 38 ) : 0 height: present ? ((appWindow.height >= 800) ? 44 : 38 ) : 0
LinearGradient { LinearGradient {
visible: isOpenGL && button.checked || numSelectedChildren > 0 visible: isOpenGL && (button.checked || buttonArea.containsMouse)
height: parent.height height: parent.height
width: 260 width: 260
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@@ -75,13 +75,15 @@ Rectangle {
GradientStop { position: 0.0; color: MoneroComponents.Style.menuButtonGradientStart } GradientStop { position: 0.0; color: MoneroComponents.Style.menuButtonGradientStart }
GradientStop { position: 1.0; color: MoneroComponents.Style.menuButtonGradientStop } GradientStop { position: 1.0; color: MoneroComponents.Style.menuButtonGradientStop }
} }
opacity: button.checked ? 1 : 0.3
} }
// fallback hover effect when opengl is not available // fallback hover effect when opengl is not available
Rectangle { Rectangle {
visible: !isOpenGL && button.checked visible: !isOpenGL && (button.checked || buttonArea.containsMouse)
anchors.fill: parent anchors.fill: parent
color: MoneroComponents.Style.menuButtonFallbackBackgroundColor color: MoneroComponents.Style.menuButtonFallbackBackgroundColor
opacity: button.checked ? 1 : 0.3
} }
// button decorations that are subject to leftMargin offsets // button decorations that are subject to leftMargin offsets

View File

@@ -39,23 +39,25 @@ Rectangle {
property var connected: Wallet.ConnectionStatus_Disconnected property var connected: Wallet.ConnectionStatus_Disconnected
function getConnectionStatusString(status) { function getConnectionStatusString(status) {
if (status == Wallet.ConnectionStatus_Connected) { switch (status) {
if(!appWindow.daemonSynced) case Wallet.ConnectionStatus_Connected:
return qsTr("Synchronizing") if (!appWindow.daemonSynced)
if(persistentSettings.useRemoteNode) return qsTr("Synchronizing");
return qsTr("Remote node") if (persistentSettings.useRemoteNode)
return appWindow.isMining ? qsTr("Connected") + " + " + qsTr("Mining"): qsTr("Connected") return qsTr("Remote node");
return appWindow.isMining ? qsTr("Connected") + " + " + qsTr("Mining"): qsTr("Connected");
case Wallet.ConnectionStatus_WrongVersion:
return qsTr("Wrong version");
case Wallet.ConnectionStatus_Disconnected:
if (appWindow.walletMode <= 1) {
return qsTr("Searching node") + translationManager.emptyString;
}
return qsTr("Disconnected");
case Wallet.ConnectionStatus_Connecting:
return qsTr("Connecting");
default:
return qsTr("Invalid connection status");
} }
if (status == Wallet.ConnectionStatus_WrongVersion)
return qsTr("Wrong version")
if (status == Wallet.ConnectionStatus_Disconnected){
if(appWindow.walletMode <= 1){
return qsTr("Searching node") + translationManager.emptyString;
}
return qsTr("Disconnected")
}
return qsTr("Invalid connection status")
} }
RowLayout { RowLayout {
@@ -159,9 +161,9 @@ Rectangle {
opacity: iconItem.opacity * (refreshMouseArea.visible ? 1 : 0.5) opacity: iconItem.opacity * (refreshMouseArea.visible ? 1 : 0.5)
text: FontAwesome.random text: FontAwesome.random
visible: ( visible: (
item.connected != Wallet.ConnectionStatus_Disconnected && !appWindow.disconnected &&
!persistentSettings.useRemoteNode && !persistentSettings.useRemoteNode &&
persistentSettings.bootstrapNodeAddress == "auto" (persistentSettings.bootstrapNodeAddress == "auto" || persistentSettings.walletMode < 2)
) )
MouseArea { MouseArea {

View File

@@ -41,9 +41,7 @@ import "../js/Utils.js" as Utils
Item { Item {
id: root id: root
visible: false visible: false
z: parent.z + 2
property bool isHidden: true
property alias password: passwordInput1.text property alias password: passwordInput1.text
property string walletName property string walletName
property string errorText property string errorText
@@ -61,13 +59,11 @@ Item {
signal closeCallback() signal closeCallback()
function _openInit(walletName, errorText) { function _openInit(walletName, errorText) {
isHidden = true
capsLockTextLabel.visible = oshelper.isCapsLock(); capsLockTextLabel.visible = oshelper.isCapsLock();
passwordInput1.echoMode = TextInput.Password passwordInput1.reset();
passwordInput2.echoMode = TextInput.Password passwordInput2.reset();
passwordInput1.text = "" if(!appWindow.currentWallet || appWindow.active)
passwordInput2.text = "" passwordInput1.input.forceActiveFocus();
passwordInput1.forceActiveFocus();
root.walletName = walletName ? walletName : "" root.walletName = walletName ? walletName : ""
errorTextLabel.text = errorText ? errorText : ""; errorTextLabel.text = errorText ? errorText : "";
leftPanel.enabled = false leftPanel.enabled = false
@@ -116,10 +112,29 @@ Item {
closeCallback(); closeCallback();
} }
function toggleIsHidden() { function onOk() {
passwordInput1.echoMode = isHidden ? TextInput.Normal : TextInput.Password; if (!passwordDialogMode && passwordInput1.text !== passwordInput2.text) {
passwordInput2.echoMode = isHidden ? TextInput.Normal : TextInput.Password; return;
isHidden = !isHidden; }
root.close()
if (passwordDialogMode) {
root.accepted()
} else if (newPasswordDialogMode) {
root.acceptedNewPassword()
} else if (passphraseDialogMode) {
root.acceptedPassphrase()
}
}
function onCancel() {
root.close()
if (passwordDialogMode) {
root.rejected()
} else if (newPasswordDialogMode) {
root.rejectedNewPassword()
} else if (passphraseDialogMode) {
root.rejectedPassphrase()
}
} }
ColumnLayout { ColumnLayout {
@@ -184,15 +199,11 @@ Item {
text: qsTr("CAPSLOCKS IS ON.") + translationManager.emptyString; text: qsTr("CAPSLOCKS IS ON.") + translationManager.emptyString;
} }
MoneroComponents.Input { MoneroComponents.LineEdit {
id: passwordInput1 id: passwordInput1
password: true
Layout.topMargin: 6 Layout.topMargin: 6
Layout.fillWidth: true Layout.fillWidth: true
horizontalAlignment: TextInput.AlignLeft
verticalAlignment: TextInput.AlignVCenter
font.family: MoneroComponents.Style.fontLight.name
font.pixelSize: 24
echoMode: TextInput.Password
KeyNavigation.tab: { KeyNavigation.tab: {
if (passwordDialogMode) { if (passwordDialogMode) {
return okButton return okButton
@@ -200,78 +211,12 @@ Item {
return passwordInput2 return passwordInput2
} }
} }
implicitHeight: 50
bottomPadding: 10
leftPadding: 10
topPadding: 10
color: MoneroComponents.Style.defaultFontColor
selectionColor: MoneroComponents.Style.textSelectionColor
selectedTextColor: MoneroComponents.Style.textSelectedColor
onTextChanged: capsLockTextLabel.visible = oshelper.isCapsLock(); onTextChanged: capsLockTextLabel.visible = oshelper.isCapsLock();
background: Rectangle {
radius: 2
color: MoneroComponents.Style.blackTheme ? "black" : "#A9FFFFFF"
border.color: MoneroComponents.Style.inputBorderColorInActive
border.width: 1
MoneroEffects.ColorTransition {
targetObj: parent
blackColor: "black"
whiteColor: "#A9FFFFFF"
}
MoneroComponents.Label {
fontSize: 20
text: isHidden ? FontAwesome.eye : FontAwesome.eyeSlash
opacity: 0.7
fontFamily: FontAwesome.fontFamily
anchors.right: parent.right
anchors.rightMargin: 15
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: 1
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onClicked: {
toggleIsHidden();
}
onEntered: {
parent.opacity = 0.9
parent.fontSize = 24
}
onExited: {
parent.opacity = 0.7
parent.fontSize = 20
}
}
}
}
Keys.enabled: root.visible Keys.enabled: root.visible
Keys.onEnterPressed: Keys.onReturnPressed(event) Keys.onEnterPressed: root.onOk()
Keys.onReturnPressed: { Keys.onReturnPressed: root.onOk()
root.close() Keys.onEscapePressed: root.onCancel()
if (passwordDialogMode) {
root.accepted()
} else if (newPasswordDialogMode) {
root.acceptedNewPassword()
} else if (passphraseDialogMode) {
root.acceptedPassphrase()
}
}
Keys.onEscapePressed: {
root.close()
if (passwordDialogMode) {
root.rejected()
} else if (newPasswordDialogMode) {
root.rejectedNewPassword()
} else if (passphraseDialogMode) {
root.rejectedPassphrase()
}
}
} }
// padding // padding
@@ -295,81 +240,19 @@ Item {
color: MoneroComponents.Style.defaultFontColor color: MoneroComponents.Style.defaultFontColor
} }
MoneroComponents.Input { MoneroComponents.LineEdit {
id: passwordInput2 id: passwordInput2
passwordLinked: passwordInput1
visible: !passwordDialogMode visible: !passwordDialogMode
Layout.topMargin: 6 Layout.topMargin: 6
Layout.fillWidth: true Layout.fillWidth: true
horizontalAlignment: TextInput.AlignLeft
verticalAlignment: TextInput.AlignVCenter
font.family: MoneroComponents.Style.fontLight.name
font.pixelSize: 24
echoMode: TextInput.Password
KeyNavigation.tab: okButton KeyNavigation.tab: okButton
implicitHeight: 50
bottomPadding: 10
leftPadding: 10
topPadding: 10
color: MoneroComponents.Style.defaultFontColor
selectionColor: MoneroComponents.Style.textSelectionColor
selectedTextColor: MoneroComponents.Style.textSelectedColor
onTextChanged: capsLockTextLabel.visible = oshelper.isCapsLock(); onTextChanged: capsLockTextLabel.visible = oshelper.isCapsLock();
background: Rectangle {
radius: 2
border.color: MoneroComponents.Style.inputBorderColorInActive
border.width: 1
color: MoneroComponents.Style.blackTheme ? "black" : "#A9FFFFFF"
MoneroComponents.Label {
fontSize: 20
text: isHidden ? FontAwesome.eye : FontAwesome.eyeSlash
opacity: 0.7
fontFamily: FontAwesome.fontFamily
anchors.right: parent.right
anchors.rightMargin: 15
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: 1
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onClicked: {
toggleIsHidden()
}
onEntered: {
parent.opacity = 0.9
parent.fontSize = 24
}
onExited: {
parent.opacity = 0.7
parent.fontSize = 20
}
}
}
}
Keys.enabled: root.visible Keys.enabled: root.visible
Keys.onEnterPressed: Keys.onReturnPressed(event) Keys.onEnterPressed: root.onOk()
Keys.onReturnPressed: { Keys.onReturnPressed: root.onOk()
if (passwordInput1.text === passwordInput2.text) { Keys.onEscapePressed: root.onCancel()
root.close()
if (newPasswordDialogMode) {
root.acceptedNewPassword()
} else if (passphraseDialogMode) {
root.acceptedPassphrase()
}
}
}
Keys.onEscapePressed: {
root.close()
if (newPasswordDialogMode) {
root.rejectedNewPassword()
} else if (passphraseDialogMode) {
root.rejectedPassphrase()
}
}
} }
// padding // padding
@@ -394,16 +277,7 @@ Item {
small: true small: true
text: qsTr("Cancel") + translationManager.emptyString text: qsTr("Cancel") + translationManager.emptyString
KeyNavigation.tab: passwordInput1 KeyNavigation.tab: passwordInput1
onClicked: { onClicked: onCancel()
root.close()
if (passwordDialogMode) {
root.rejected()
} else if (newPasswordDialogMode) {
root.rejectedNewPassword()
} else if (passphraseDialogMode) {
root.rejectedPassphrase()
}
}
} }
MoneroComponents.StandardButton { MoneroComponents.StandardButton {
@@ -412,16 +286,7 @@ Item {
text: qsTr("Ok") + translationManager.emptyString text: qsTr("Ok") + translationManager.emptyString
KeyNavigation.tab: cancelButton KeyNavigation.tab: cancelButton
enabled: (passwordDialogMode == true) ? true : passwordInput1.text === passwordInput2.text enabled: (passwordDialogMode == true) ? true : passwordInput1.text === passwordInput2.text
onClicked: { onClicked: onOk()
root.close()
if (passwordDialogMode) {
root.accepted()
} else if (newPasswordDialogMode) {
root.acceptedNewPassword()
} else if (passphraseDialogMode) {
root.acceptedPassphrase()
}
}
} }
} }
} }

View File

@@ -29,21 +29,23 @@
import QtQuick 2.9 import QtQuick 2.9
import QtQuick.Window 2.1 import QtQuick.Window 2.1
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import "../components" as MoneroComponents import "../components" as MoneroComponents
Rectangle { Rectangle {
id: root id: root
color: MoneroComponents.Style.blackTheme ? "white" : "transparent" color: MoneroComponents.Style.blackTheme ? "black" : "white"
visible: false visible: false
radius: 10
border.color: MoneroComponents.Style.blackTheme ? Qt.rgba(255, 255, 255, 0.25) : Qt.rgba(0, 0, 0, 0.25)
border.width: 1
z: 11 z: 11
property alias messageText: messageTitle.text property alias messageText: messageTitle.text
property alias heightProgressText : heightProgress.text
width: 200 width: 100
height: 100 height: 50
opacity: 0.7
function show() { function show() {
root.visible = true; root.visible = true;
@@ -56,44 +58,55 @@ Rectangle {
ColumnLayout { ColumnLayout {
id: rootLayout id: rootLayout
anchors.left: parent.left anchors.centerIn: parent
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 30 anchors.leftMargin: 30
anchors.rightMargin: 30 anchors.rightMargin: 30
spacing: 12 spacing: 21
BusyIndicator { Item {
running: parent.visible
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
Layout.preferredHeight: 80
Image {
id: imgLogo
width: 60
height: 60
anchors.centerIn: parent
source: "qrc:///images/monero-vector.svg"
mipmap: true
}
BusyIndicator {
running: parent.visible
anchors.centerIn: imgLogo
style: BusyIndicatorStyle {
indicator: Image {
visible: control.running
source: "qrc:///images/busy-indicator.png"
RotationAnimator on rotation {
running: control.running
loops: Animation.Infinite
duration: 1000
from: 0
to: 360
}
}
}
}
} }
MoneroComponents.TextPlain { MoneroComponents.TextPlain {
id: messageTitle id: messageTitle
text: "Please wait..." text: qsTr("Please wait...") + translationManager.emptyString
font { font.pixelSize: 24
pixelSize: 22
}
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
Layout.fillWidth: true Layout.fillWidth: true
themeTransition: false themeTransition: false
color: "black" color: MoneroComponents.Style.defaultFontColor
}
MoneroComponents.TextPlain {
id: heightProgress
font {
pixelSize: 18
}
horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
Layout.fillWidth: true
themeTransition: false
color: "black"
} }
} }
} }

View File

@@ -42,7 +42,7 @@ Rectangle {
function updateProgress(currentBlock,targetBlock, blocksToSync, statusTxt){ function updateProgress(currentBlock,targetBlock, blocksToSync, statusTxt){
if(targetBlock > 0) { if(targetBlock > 0) {
var remaining = (currentBlock < targetBlock) ? targetBlock - currentBlock : 0 var remaining = (currentBlock < targetBlock) ? targetBlock - currentBlock : 0
var progressLevel = (blocksToSync > 0 && blocksToSync != remaining) ? (100*(blocksToSync - remaining)/blocksToSync).toFixed(0) : (100*(currentBlock / targetBlock)).toFixed(0) var progressLevel = (blocksToSync > 0 ) ? (100*(blocksToSync - remaining)/blocksToSync).toFixed(0) : 100
fillLevel = progressLevel fillLevel = progressLevel
if(typeof statusTxt != "undefined" && statusTxt != "") { if(typeof statusTxt != "undefined" && statusTxt != "") {
progressText.text = statusTxt; progressText.text = statusTxt;

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2014-2018, The Monero Project // Copyright (c) 2014-2020, The Monero Project
// //
// All rights reserved. // All rights reserved.
// //
@@ -53,6 +53,7 @@ Rectangle {
script: { script: {
root.visible = true root.visible = true
camera.captureMode = Camera.CaptureStillImage camera.captureMode = Camera.CaptureStillImage
camera.cameraState = Camera.ActiveState
camera.start() camera.start()
finder.enabled = true finder.enabled = true
} }
@@ -65,6 +66,7 @@ Rectangle {
camera.stop() camera.stop()
root.visible = false root.visible = false
finder.enabled = false finder.enabled = false
camera.cameraState = Camera.UnloadedState
} }
} }
} }
@@ -74,6 +76,7 @@ Rectangle {
id: camera id: camera
objectName: "qrCameraQML" objectName: "qrCameraQML"
captureMode: Camera.CaptureStillImage captureMode: Camera.CaptureStillImage
cameraState: Camera.UnloadedState
focus { focus {
focusMode: Camera.FocusContinuous focusMode: Camera.FocusContinuous
@@ -83,9 +86,14 @@ Rectangle {
id : finder id : finder
objectName: "QrFinder" objectName: "QrFinder"
onDecoded : { onDecoded : {
root.qrcode_decoded(address, payment_id, amount, tx_description, recipient_name, extra_parameters) const parsed = walletManager.parse_uri_to_object(data);
root.state = "Stopped" if (!parsed.error) {
} root.qrcode_decoded(parsed.address, parsed.payment_id, parsed.amount, parsed.tx_description, parsed.recipient_name, parsed.extra_parameters);
root.state = "Stopped";
} else {
onNotifyError(parsed.error);
}
}
onNotifyError : { onNotifyError : {
if( warning ) if( warning )
messageDialog.icon = StandardIcon.Critical messageDialog.icon = StandardIcon.Critical

View File

@@ -43,6 +43,9 @@ GridLayout {
property alias daemonAddrLabelText: daemonAddr.labelText property alias daemonAddrLabelText: daemonAddr.labelText
property alias daemonPortLabelText: daemonPort.labelText property alias daemonPortLabelText: daemonPort.labelText
property string initialAddress: ""
property var initialHostPort: initialAddress.match(/^(.*?)(?:\:?(\d*))$/)
// TODO: LEGACY; remove these placeHolder variables when // TODO: LEGACY; remove these placeHolder variables when
// the wizards get redesigned to the black-theme // the wizards get redesigned to the black-theme
property string placeholderFontFamily: MoneroComponents.Style.fontRegular.name property string placeholderFontFamily: MoneroComponents.Style.fontRegular.name
@@ -58,6 +61,9 @@ GridLayout {
property bool lineEditFontBold: false property bool lineEditFontBold: false
property int lineEditFontSize: 15 property int lineEditFontSize: 15
// Author: David M. Syzdek https://github.com/syzdek https://gist.github.com/syzdek/6086792
readonly property var ipv6Regex: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe08:(:[0-9a-fA-F]{1,4}){2,2}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/
signal editingFinished() signal editingFinished()
signal textChanged() signal textChanged()
@@ -91,8 +97,12 @@ GridLayout {
fontColor: lineEditFontColor fontColor: lineEditFontColor
fontBold: lineEditFontBold fontBold: lineEditFontBold
fontSize: lineEditFontSize fontSize: lineEditFontSize
onEditingFinished: root.editingFinished() onEditingFinished: {
text = text.replace(ipv6Regex, "[$1]");
root.editingFinished();
}
onTextChanged: root.textChanged() onTextChanged: root.textChanged()
text: initialHostPort[1]
} }
LineEdit { LineEdit {
@@ -114,5 +124,6 @@ GridLayout {
onEditingFinished: root.editingFinished() onEditingFinished: root.editingFinished()
onTextChanged: root.textChanged() onTextChanged: root.textChanged()
text: initialHostPort[2]
} }
} }

View File

@@ -1,41 +1,71 @@
import QtQuick 2.9 import QtQuick 2.9
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import FontAwesome 1.0
import "../components" as MoneroComponents import "../components" as MoneroComponents
ColumnLayout { ColumnLayout {
property alias buttonText: button.text id: settingsListItem
property alias description: description.text property alias iconText: iconLabel.text
property alias title: title.text property alias description: area.text
property alias title: header.text
property bool isLast: false
signal clicked() signal clicked()
id: settingsListItem
Layout.fillWidth: true Layout.fillWidth: true
spacing: 0 spacing: 0
Rectangle { Rectangle {
// divider id: root
Layout.preferredHeight: 1
Layout.fillWidth: true Layout.fillWidth: true
Layout.bottomMargin: 8 Layout.minimumHeight: 75
color: MoneroComponents.Style.dividerColor Layout.preferredHeight: rect.height + 15
opacity: MoneroComponents.Style.dividerOpacity color: "transparent"
}
RowLayout { Rectangle {
Layout.fillWidth: true id: divider
spacing: 0 anchors.topMargin: 0
anchors.left: parent.left
anchors.right: parent.right
height: 1
color: MoneroComponents.Style.dividerColor
opacity: MoneroComponents.Style.dividerOpacity
}
ColumnLayout { Rectangle {
Layout.fillWidth: true id: rect
Layout.alignment: Qt.AlignVCenter width: parent.width
spacing: 0 height: header.height + area.contentHeight
color: "transparent";
anchors.left: parent.left
anchors.bottomMargin: 4
anchors.topMargin: 4
anchors.verticalCenter: parent.verticalCenter
Rectangle {
id: icon
color: "transparent"
height: 32
width: 32
anchors.left: parent.left
anchors.leftMargin: 16
anchors.verticalCenter: parent.verticalCenter
MoneroComponents.Label {
id: iconLabel
fontSize: 32
fontFamily: FontAwesome.fontFamilySolid
anchors.centerIn: parent
fontColor: MoneroComponents.Style.defaultFontColor
styleName: "Solid"
}
}
MoneroComponents.TextPlain { MoneroComponents.TextPlain {
id: title id: header
Layout.fillWidth: true anchors.left: icon.right
Layout.preferredHeight: 20 anchors.leftMargin: 16
Layout.topMargin: 8 anchors.top: parent.top
color: MoneroComponents.Style.defaultFontColor color: MoneroComponents.Style.defaultFontColor
opacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.8 opacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.8
font.bold: true font.bold: true
@@ -43,23 +73,43 @@ ColumnLayout {
font.pixelSize: 16 font.pixelSize: 16
} }
MoneroComponents.TextPlainArea { Text {
id: description id: area
anchors.top: header.bottom
anchors.topMargin: 4
anchors.left: icon.right
anchors.leftMargin: 16
color: MoneroComponents.Style.dimmedFontColor color: MoneroComponents.Style.dimmedFontColor
colorBlackTheme: MoneroComponents.Style._b_dimmedFontColor font.family: MoneroComponents.Style.fontRegular.name
colorWhiteTheme: MoneroComponents.Style._w_dimmedFontColor font.pixelSize: 15
Layout.fillWidth: true
horizontalAlignment: TextInput.AlignLeft horizontalAlignment: TextInput.AlignLeft
wrapMode: Text.WordWrap;
leftPadding: 0
topPadding: 0
width: parent.width - (icon.width + icon.anchors.leftMargin + anchors.leftMargin)
} }
} }
MoneroComponents.StandardButton { Rectangle {
id: button id: bottomDivider
small: true anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
height: 1
color: MoneroComponents.Style.dividerColor
opacity: MoneroComponents.Style.dividerOpacity
visible: settingsListItem.isLast
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
hoverEnabled: true
onEntered: root.color = MoneroComponents.Style.titleBarButtonHoverColor
onExited: root.color = "transparent"
onClicked: { onClicked: {
settingsListItem.clicked() settingsListItem.clicked()
} }
width: 135
} }
} }
} }

68
components/Slider.qml Normal file
View File

@@ -0,0 +1,68 @@
import QtQuick 2.9
import QtQuick.Controls 2.0 as QtQuickControls
import QtQuick.Layouts 1.1
import "../components" as MoneroComponents
ColumnLayout {
property alias from: slider.from
property alias stepSize: slider.stepSize
property alias to: slider.to
property alias value: slider.value
property alias text: label.text
signal moved()
spacing: 0
Text {
id: label
color: MoneroComponents.Style.defaultFontColor
font.pixelSize: 14
Layout.fillWidth: true
}
QtQuickControls.Slider {
id: slider
leftPadding: 0
snapMode: QtQuickControls.Slider.SnapAlways
background: Rectangle {
x: parent.leftPadding
y: parent.topPadding + parent.availableHeight / 2 - height / 2
implicitWidth: 200
implicitHeight: 4
width: parent.availableWidth
height: implicitHeight
radius: 2
color: MoneroComponents.Style.progressBarBackgroundColor
Rectangle {
width: parent.visualPosition * parent.width
height: parent.height
color: MoneroComponents.Style.green
radius: 2
}
}
handle: Rectangle {
x: parent.leftPadding + parent.visualPosition * (parent.availableWidth - width)
y: parent.topPadding + parent.availableHeight / 2 - height / 2
implicitWidth: 18
implicitHeight: 18
radius: 8
color: parent.pressed ? "#f0f0f0" : "#f6f6f6"
border.color: MoneroComponents.Style.grey
}
onMoved: parent.moved()
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
}
}
}

View File

@@ -33,11 +33,17 @@ import "../components" as MoneroComponents
Item { Item {
id: button id: button
property bool primary: true
property string rightIcon: "" property string rightIcon: ""
property string rightIconInactive: "" property string rightIconInactive: ""
property string textColor: button.enabled? MoneroComponents.Style.buttonTextColor: MoneroComponents.Style.buttonTextColorDisabled property color textColor: !button.enabled
? MoneroComponents.Style.buttonTextColorDisabled
: primary
? MoneroComponents.Style.buttonTextColor
: MoneroComponents.Style.buttonSecondaryTextColor;
property bool small: false property bool small: false
property alias text: label.text property alias text: label.text
property alias fontBold: label.font.bold
property int fontSize: { property int fontSize: {
if(small) return 14; if(small) return 14;
else return 16; else return 16;
@@ -70,7 +76,9 @@ Item {
when: buttonArea.containsMouse || button.focus when: buttonArea.containsMouse || button.focus
PropertyChanges { PropertyChanges {
target: buttonRect target: buttonRect
color: MoneroComponents.Style.buttonBackgroundColorHover color: primary
? MoneroComponents.Style.buttonBackgroundColorHover
: MoneroComponents.Style.buttonSecondaryBackgroundColorHover
} }
}, },
State { State {
@@ -78,7 +86,9 @@ Item {
when: button.enabled when: button.enabled
PropertyChanges { PropertyChanges {
target: buttonRect target: buttonRect
color: MoneroComponents.Style.buttonBackgroundColor color: primary
? MoneroComponents.Style.buttonBackgroundColor
: MoneroComponents.Style.buttonSecondaryBackgroundColor
} }
}, },
State { State {

View File

@@ -90,6 +90,10 @@ Rectangle {
function close() { function close() {
root.visible = false; root.visible = false;
// reset button text
okButton.text = qsTr("OK")
cancelButton.text = qsTr("Cancel")
closeCallback(); closeCallback();
} }

View File

@@ -58,11 +58,6 @@ Item {
onExpandedChanged: if(expanded) appWindow.currentItem = dropdown onExpandedChanged: if(expanded) appWindow.currentItem = dropdown
// Workaroud for suspected memory leak in 5.8 causing malloc crash on app exit
function update() {
firstColText.text = columnid.currentIndex < repeater.model.rowCount() ? qsTr(repeater.model.get(columnid.currentIndex).column1) + translationManager.emptyString : ""
}
Item { Item {
id: head id: head
anchors.left: parent.left anchors.left: parent.left
@@ -80,15 +75,17 @@ Item {
} }
MoneroComponents.TextPlain { MoneroComponents.TextPlain {
id: firstColText
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 12 anchors.leftMargin: 12
anchors.right: dropIndicator.left
anchors.rightMargin: 12
elide: Text.ElideRight elide: Text.ElideRight
font.family: MoneroComponents.Style.fontRegular.name font.family: MoneroComponents.Style.fontRegular.name
font.bold: dropdown.headerFontBold font.bold: dropdown.headerFontBold
font.pixelSize: dropdown.fontHeaderSize font.pixelSize: dropdown.fontHeaderSize
color: dropdown.textColor color: dropdown.textColor
text: columnid.currentIndex < repeater.model.count ? qsTr(repeater.model.get(columnid.currentIndex).column1) + translationManager.emptyString : ""
} }
Item { Item {
@@ -96,7 +93,8 @@ Item {
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
width: 32 anchors.rightMargin: 12
width: dropdownIcon.width
Image { Image {
id: dropdownIcon id: dropdownIcon
@@ -137,20 +135,6 @@ Item {
height: dropdown.expanded ? columnid.height : 0 height: dropdown.expanded ? columnid.height : 0
color: dropdown.pressedColor color: dropdown.pressedColor
Rectangle {
anchors.left: parent.left
anchors.top: parent.top
width: 3; height: 3
color: dropdown.pressedColor
}
Rectangle {
anchors.right: parent.right
anchors.top: parent.top
width: 3; height: 3
color: dropdown.pressedColor
}
Behavior on height { Behavior on height {
NumberAnimation { duration: 100; easing.type: Easing.InQuad } NumberAnimation { duration: 100; easing.type: Easing.InQuad }
} }
@@ -228,7 +212,6 @@ Item {
popup.close() popup.close()
columnid.currentIndex = index columnid.currentIndex = index
changed(); changed();
dropdown.update()
} }
} }
} }

View File

@@ -29,6 +29,7 @@ QtObject {
property string textSelectedColor: blackTheme ? _b_textSelectedColor : _w_textSelectedColor property string textSelectedColor: blackTheme ? _b_textSelectedColor : _w_textSelectedColor
property string inputBoxBackground: blackTheme ? _b_inputBoxBackground : _w_inputBoxBackground property string inputBoxBackground: blackTheme ? _b_inputBoxBackground : _w_inputBoxBackground
property string inputBoxBackgroundDisabled: blackTheme ? _b_inputBoxBackgroundDisabled : _w_inputBoxBackgroundDisabled
property string inputBoxBackgroundError: blackTheme ? _b_inputBoxBackgroundError : _w_inputBoxBackgroundError property string inputBoxBackgroundError: blackTheme ? _b_inputBoxBackgroundError : _w_inputBoxBackgroundError
property string inputBoxColor: blackTheme ? _b_inputBoxColor : _w_inputBoxColor property string inputBoxColor: blackTheme ? _b_inputBoxColor : _w_inputBoxColor
property string legacy_placeholderFontColor: blackTheme ? _b_legacy_placeholderFontColor : _w_legacy_placeholderFontColor property string legacy_placeholderFontColor: blackTheme ? _b_legacy_placeholderFontColor : _w_legacy_placeholderFontColor
@@ -43,6 +44,9 @@ QtObject {
property string buttonInlineBackgroundColor: blackTheme ? _b_buttonInlineBackgroundColor : _w_buttonInlineBackgroundColor property string buttonInlineBackgroundColor: blackTheme ? _b_buttonInlineBackgroundColor : _w_buttonInlineBackgroundColor
property string buttonTextColor: blackTheme ? _b_buttonTextColor : _w_buttonTextColor property string buttonTextColor: blackTheme ? _b_buttonTextColor : _w_buttonTextColor
property string buttonTextColorDisabled: blackTheme ? _b_buttonTextColorDisabled : _w_buttonTextColorDisabled property string buttonTextColorDisabled: blackTheme ? _b_buttonTextColorDisabled : _w_buttonTextColorDisabled
property string buttonSecondaryBackgroundColor: "#d9d9d9"
property string buttonSecondaryBackgroundColorHover: "#a6a6a6"
property string buttonSecondaryTextColor: "#4d4d4d"
property string dividerColor: blackTheme ? _b_dividerColor : _w_dividerColor property string dividerColor: blackTheme ? _b_dividerColor : _w_dividerColor
property real dividerOpacity: blackTheme ? _b_dividerOpacity : _w_dividerOpacity property real dividerOpacity: blackTheme ? _b_dividerOpacity : _w_dividerOpacity
@@ -85,6 +89,7 @@ QtObject {
property string _b_textSelectedColor: "white" property string _b_textSelectedColor: "white"
property string _b_inputBoxBackground: "black" property string _b_inputBoxBackground: "black"
property string _b_inputBoxBackgroundDisabled: Qt.rgba(255, 255, 255, 0.10)
property string _b_inputBoxBackgroundError: "#FFDDDD" property string _b_inputBoxBackgroundError: "#FFDDDD"
property string _b_inputBoxColor: "white" property string _b_inputBoxColor: "white"
property string _b_legacy_placeholderFontColor: "#BABABA" property string _b_legacy_placeholderFontColor: "#BABABA"
@@ -123,7 +128,7 @@ QtObject {
property string _b_menuButtonImageRightColor: "white" property string _b_menuButtonImageRightColor: "white"
property string _b_menuButtonImageRightSource: "qrc:///images/right.svg" property string _b_menuButtonImageRightSource: "qrc:///images/right.svg"
property string _b_menuButtonImageDotArrowSource: "qrc:///images/arrow-right-medium-white.png" property string _b_menuButtonImageDotArrowSource: "qrc:///images/arrow-right-medium-white.png"
property string _b_inlineButtonTextColor: "black" property string _b_inlineButtonTextColor: "white"
property string _b_inlineButtonBorderColor: "black" property string _b_inlineButtonBorderColor: "black"
property string _b_appWindowBackgroundColor: "white" property string _b_appWindowBackgroundColor: "white"
property string _b_appWindowBorderColor: "#313131" property string _b_appWindowBorderColor: "#313131"
@@ -141,6 +146,7 @@ QtObject {
property string _w_textSelectedColor: "black" property string _w_textSelectedColor: "black"
property string _w_inputBoxBackground: "white" property string _w_inputBoxBackground: "white"
property string _w_inputBoxBackgroundDisabled: Qt.rgba(0, 0, 0, 0.20)
property string _w_inputBoxBackgroundError: "#FFDDDD" property string _w_inputBoxBackgroundError: "#FFDDDD"
property string _w_inputBoxColor: "black" property string _w_inputBoxColor: "black"
property string _w_legacy_placeholderFontColor: "#BABABA" property string _w_legacy_placeholderFontColor: "#BABABA"
@@ -179,7 +185,7 @@ QtObject {
property string _w_menuButtonImageRightColorActive: "#FA6800" property string _w_menuButtonImageRightColorActive: "#FA6800"
property string _w_menuButtonImageRightColor: "#808080" property string _w_menuButtonImageRightColor: "#808080"
property string _w_menuButtonImageDotArrowSource: "qrc:///images/arrow-right-medium-white.png" property string _w_menuButtonImageDotArrowSource: "qrc:///images/arrow-right-medium-white.png"
property string _w_inlineButtonTextColor: "white" property string _w_inlineButtonTextColor: "black"
property string _w_inlineButtonBorderColor: "transparent" property string _w_inlineButtonBorderColor: "transparent"
property string _w_appWindowBackgroundColor: "black" property string _w_appWindowBackgroundColor: "black"
property string _w_appWindowBorderColor: "#dedede" property string _w_appWindowBorderColor: "#dedede"

View File

@@ -309,8 +309,8 @@ Rectangle {
width: 16 width: 16
image: MoneroComponents.Style.titleBarCloseSource image: MoneroComponents.Style.titleBarCloseSource
color: MoneroComponents.Style.defaultFontColor color: MoneroComponents.Style.defaultFontColor
fontAwesomeFallbackIcon: FontAwesome.timesRectangle fontAwesomeFallbackIcon: FontAwesome.times
fontAwesomeFallbackSize: 18 fontAwesomeFallbackSize: 21
fontAwesomeFallbackOpacity: MoneroComponents.Style.blackTheme ? 0.8 : 0.6 fontAwesomeFallbackOpacity: MoneroComponents.Style.blackTheme ? 0.8 : 0.6
opacity: 0.75 opacity: 0.75
} }

203
components/UpdateDialog.qml Normal file
View File

@@ -0,0 +1,203 @@
// Copyright (c) 2020, 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.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.1
import moneroComponents.Downloader 1.0
import "../components" as MoneroComponents
Popup {
id: updateDialog
property bool active: false
property bool allowed: true
property string error: ""
property string filename: ""
property string hash: ""
property double progress: url && downloader.total > 0 ? downloader.loaded * 100 / downloader.total : 0
property string url: ""
property bool valid: false
property string version: ""
background: Rectangle {
border.color: MoneroComponents.Style.appWindowBorderColor
border.width: 1
color: MoneroComponents.Style.middlePanelBackgroundColor
}
closePolicy: Popup.NoAutoClose
padding: 20
visible: active && allowed
function show(version, url, hash) {
updateDialog.error = "";
updateDialog.hash = hash;
updateDialog.url = url;
updateDialog.valid = false;
updateDialog.version = version;
updateDialog.active = true;
}
ColumnLayout {
id: mainLayout
spacing: updateDialog.padding
Text {
color: MoneroComponents.Style.defaultFontColor
font.bold: true
font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 18
text: qsTr("New Monero version v%1 is available.").arg(updateDialog.version)
}
Text {
id: errorText
color: "red"
font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 18
text: updateDialog.error
visible: text
}
Text {
id: statusText
color: updateDialog.valid ? MoneroComponents.Style.green : MoneroComponents.Style.defaultFontColor
font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 18
visible: !errorText.visible
text: {
if (!updateDialog.url) {
return qsTr("Please visit getmonero.org for details") + translationManager.emptyString;
}
if (downloader.active) {
return "%1 (%2%)"
.arg(qsTr("Downloading"))
.arg(updateDialog.progress.toFixed(1))
+ translationManager.emptyString;
}
if (updateDialog.valid) {
return qsTr("Update downloaded, signature verified") + translationManager.emptyString;
}
return qsTr("Do you want to download and verify new version?") + translationManager.emptyString;
}
}
Rectangle {
id: progressBar
color: MoneroComponents.Style.lightGreyFontColor
height: 3
Layout.fillWidth: true
visible: updateDialog.valid || downloader.active
Rectangle {
color: MoneroComponents.Style.buttonBackgroundColor
height: parent.height
width: parent.width * updateDialog.progress / 100
}
}
RowLayout {
Layout.alignment: Qt.AlignRight
spacing: parent.spacing
MoneroComponents.StandardButton {
id: cancelButton
fontBold: false
primary: !updateDialog.url
text: {
if (!updateDialog.url) {
return qsTr("Ok") + translationManager.emptyString;
}
if (updateDialog.valid || downloader.active || errorText.visible) {
return qsTr("Cancel") + translationManager.emptyString;
}
return qsTr("Download later") + translationManager.emptyString;
}
onClicked: {
downloader.cancel();
updateDialog.active = false;
}
}
MoneroComponents.StandardButton {
id: downloadButton
KeyNavigation.tab: cancelButton
fontBold: false
text: (updateDialog.error ? qsTr("Retry") : qsTr("Download")) + translationManager.emptyString
visible: updateDialog.url && !updateDialog.valid && !downloader.active
onClicked: {
updateDialog.error = "";
updateDialog.filename = updateDialog.url.replace(/^.*\//, '');
const downloadingStarted = downloader.get(updateDialog.url, updateDialog.hash, function(error) {
if (error) {
console.error("Download failed", error);
updateDialog.error = qsTr("Download failed") + translationManager.emptyString;
} else {
updateDialog.valid = true;
}
});
if (!downloadingStarted) {
updateDialog.error = qsTr("Failed to start download") + translationManager.emptyString;
}
}
}
MoneroComponents.StandardButton {
id: saveButton
KeyNavigation.tab: cancelButton
fontBold: false
onClicked: {
const fullPath = oshelper.openSaveFileDialog(
qsTr("Save as") + translationManager.emptyString,
oshelper.downloadLocation(),
updateDialog.filename);
if (!fullPath) {
return;
}
if (downloader.saveToFile(fullPath)) {
cancelButton.clicked();
oshelper.openContainingFolder(fullPath);
} else {
updateDialog.error = qsTr("Save operation failed") + translationManager.emptyString;
}
}
text: qsTr("Save to file") + translationManager.emptyString
visible: updateDialog.valid
}
}
}
Downloader {
id: downloader
}
}

View File

@@ -149,6 +149,7 @@ Object {
property string caretUp : "\uf0d8" property string caretUp : "\uf0d8"
property string cartArrowDown : "\uf218" property string cartArrowDown : "\uf218"
property string cartPlus : "\uf217" property string cartPlus : "\uf217"
property string cashRegister: "\uf788"
property string cc : "\uf20a" property string cc : "\uf20a"
property string ccAmex : "\uf1f3" property string ccAmex : "\uf1f3"
property string ccDinersClub : "\uf24c" property string ccDinersClub : "\uf24c"

View File

@@ -17,7 +17,7 @@ if [ ! -d $MONERO_DIR/src ]; then
fi fi
git submodule update --remote git submodule update --remote
git -C $MONERO_DIR fetch git -C $MONERO_DIR fetch
git -C $MONERO_DIR checkout v0.15.0.1 git -C $MONERO_DIR checkout v0.16.0.3
# get monero core tag # get monero core tag
pushd $MONERO_DIR pushd $MONERO_DIR
@@ -140,13 +140,40 @@ platform=$(get_platform)
# default make executable # default make executable
make_exec="make" make_exec="make"
if [ -z "$ARCH" ]; then
ARCH="native"
if [ "$platform" == "darwin" ]; then
if [ "$STATIC" == true ]; then
ARCH="x86-64"
fi
elif [ "$platform" == "linux64" ]; then
if [ "$ANDROID" == true ]; then
ARCH="armv7-a"
elif [ "$STATIC" == true ]; then
ARCH="x86-64"
fi
elif [ "$platform" == "linux32" ]; then
if [ "$STATIC" == true ]; then
ARCH="i686"
fi
elif [ "$platform" == "linuxarmv7" ]; then
ARCH="armv7-a"
elif [ "$platform" == "mingw32" ]; then
ARCH="i686"
elif [ "$platform" == "mingw64" ]; then
ARCH="x86-64"
fi
fi
echo "Building for ARCH=$ARCH"
## OS X ## OS X
if [ "$platform" == "darwin" ]; then if [ "$platform" == "darwin" ]; then
echo "Configuring build for MacOS.." echo "Configuring build for MacOS.."
if [ "$STATIC" == true ]; then 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_TAG="mac-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="$ARCH" -D BUILD_64=ON -D BUILD_TAG="mac-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
else else
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_TAG="mac-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D ARCH="$ARCH" -D BUILD_TAG="mac-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
fi fi
## LINUX 64 ## LINUX 64
@@ -154,38 +181,38 @@ elif [ "$platform" == "linux64" ]; then
echo "Configuring build for Linux x64" echo "Configuring build for Linux x64"
if [ "$ANDROID" == true ]; then if [ "$ANDROID" == true ]; then
echo "Configuring build for Android on Linux host" 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 $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="$ARCH" -D ANDROID=true -D BUILD_GUI_DEPS=ON -D USE_LTO=OFF -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
elif [ "$STATIC" == true ]; then 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_TAG="linux-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="$ARCH" -D BUILD_64=ON -D BUILD_TAG="linux-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
else else
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_TAG="linux-x64" -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D ARCH="$ARCH" -D BUILD_TAG="linux-x64" -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
fi fi
## LINUX 32 ## LINUX 32
elif [ "$platform" == "linux32" ]; then elif [ "$platform" == "linux32" ]; then
echo "Configuring build for Linux i686" echo "Configuring build for Linux i686"
if [ "$STATIC" == true ]; then 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 $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="$ARCH" -D BUILD_64=OFF -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
else else
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D ARCH="$ARCH" -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
fi fi
## LINUX ARMv7 ## LINUX ARMv7
elif [ "$platform" == "linuxarmv7" ]; then elif [ "$platform" == "linuxarmv7" ]; then
echo "Configuring build for Linux armv7" echo "Configuring build for Linux armv7"
if [ "$STATIC" == true ]; then 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 $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D BUILD_TESTS=OFF -D ARCH="$ARCH" -D STATIC=ON -D BUILD_64=OFF -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
else else
cmake -D BUILD_TESTS=OFF -D ARCH="armv7-a" -D -D BUILD_64=OFF -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D BUILD_TESTS=OFF -D ARCH="$ARCH" -D -D BUILD_64=OFF -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
fi fi
## LINUX other ## LINUX other
elif [ "$platform" == "linux" ]; then elif [ "$platform" == "linux" ]; then
echo "Configuring build for Linux general" echo "Configuring build for Linux general"
if [ "$STATIC" == true ]; then 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 $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="$ARCH" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
else else
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D ARCH="$ARCH" -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
fi fi
## Windows 64 ## Windows 64
@@ -194,21 +221,21 @@ elif [ "$platform" == "mingw64" ]; then
# Do something under Windows NT platform # Do something under Windows NT platform
echo "Configuring build for MINGW64.." echo "Configuring build for MINGW64.."
BOOST_ROOT=/mingw64/boost BOOST_ROOT=/mingw64/boost
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D BOOST_ROOT="$BOOST_ROOT" -D ARCH="x86-64" -D BUILD_TAG="win-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" -D CMAKE_TOOLCHAIN_FILE=../../cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys64 ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D BOOST_ROOT="$BOOST_ROOT" -D ARCH="$ARCH" -D BUILD_TAG="win-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" -D CMAKE_TOOLCHAIN_FILE=../../cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=$(cd $MINGW_PREFIX/.. && pwd -W) ../..
## Windows 32 ## Windows 32
elif [ "$platform" == "mingw32" ]; then elif [ "$platform" == "mingw32" ]; then
# Do something under Windows NT platform # Do something under Windows NT platform
echo "Configuring build for MINGW32.." echo "Configuring build for MINGW32.."
BOOST_ROOT=/mingw32/boost BOOST_ROOT=/mingw32/boost
cmake -D CMAKE_BUILD_TYPE=$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 $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" -D CMAKE_TOOLCHAIN_FILE=../../cmake/32-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys32 ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D Boost_DEBUG=ON -D BOOST_ROOT="$BOOST_ROOT" -D ARCH="$ARCH" -D BUILD_64=OFF -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" -D CMAKE_TOOLCHAIN_FILE=../../cmake/32-bit-toolchain.cmake -D MSYS2_FOLDER=$(cd $MINGW_PREFIX/.. && pwd -W) ../..
make_exec="mingw32-make" make_exec="mingw32-make"
else else
echo "Unknown platform, configuring general build" echo "Unknown platform, configuring general build"
if [ "$STATIC" == true ]; then if [ "$STATIC" == true ]; then
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="$ARCH" -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
else else
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D ARCH="$ARCH" -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
fi fi
fi fi

BIN
images/busy-indicator.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 493 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

2
images/monero-vector.svg Normal file
View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" viewBox="0 0 6000 6000" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata><defs><clipPath id="a"><path d="m0 4500h4500v-4500h-4500z"/></clipPath></defs><g transform="matrix(1.3333 0 0 -1.3333 0 6e3)"><g clip-path="url(#a)"><g transform="translate(4128 2250.2)"><path d="m0 0c0-1037.2-840.79-1878.1-1878.1-1878.1-1037.2 0-1878 840.88-1878 1878.1 0 1037.3 840.8 1878.1 1878 1878.1 1037.3 0 1878.1-840.79 1878.1-1878.1" fill="#fff"/></g><g transform="translate(2250 4128.2)"><path d="m0 0c-1036.9 0-1879.1-842.06-1877.8-1878 0.262-207.26 33.308-406.63 95.342-593.12h561.88v1579.9l1220.6-1220.6 1220.6 1220.6v-1579.9h561.96c62.117 186.48 95.008 385.85 95.369 593.12 1.809 1037-840.89 1877.8-1877.9 1877.8z" fill="#f36e36"/></g><g transform="translate(1969.3 1735.8)"><path d="m0 0-532.67 532.7v-994.14h-407.26l-384.29-0.07c329.63-540.8 925.35-902.56 1604.9-902.56 679.54 0 1275.3 361.85 1605 902.65l-384.44-0.013h-407.27v994.14l-813.3-813.31-280.62 280.61z" fill="#575757"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 575 B

View File

@@ -1,8 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="18" viewBox="0 0 10 18">
<g fill="none" fill-rule="evenodd" opacity="1">
<path fill="none" d="M-13-9h36v36h-36z" opacity="1"/>
<g fill="#000" fill-rule="nonzero">
<path d="M5 0C3.75 0 2.571.468 1.643 1.296A5.057 5.057 0 0 0 0 5.04c0 .396.321.72.714.72h.715a.72.72 0 0 0 .714-.72c0-.828.357-1.584.964-2.16A2.823 2.823 0 0 1 5 2.16c.107 0 .214 0 .321.036 1.322.144 2.358 1.224 2.5 2.52.143 1.188-.464 2.304-1.5 2.88-1.5.792-2.428 2.304-2.428 3.96v2.124c0 .396.321.72.714.72h.714a.72.72 0 0 0 .715-.72v-2.124c0-.828.5-1.62 1.285-2.052A4.98 4.98 0 0 0 9.93 4.5C9.714 2.16 7.857.288 5.57.036 5.393 0 5.18 0 5 0zM5.714 18H4.286a.358.358 0 0 1-.357-.36V16.2c0-.2.16-.36.357-.36h1.428c.198 0 .357.16.357.36v1.44c0 .2-.16.36-.357.36z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 848 B

View File

@@ -1,4 +1,4 @@
Copyright (c) 2014-2019, The Monero Project Copyright (c) 2014-2020, The Monero Project
All rights reserved. All rights reserved.

View File

@@ -1,5 +1,5 @@
; Monero Carbon Chamaeleon GUI Wallet Installer for Windows ; Monero Nitrogen Nebula GUI Wallet Installer for Windows
; Copyright (c) 2017-2019, The Monero Project ; Copyright (c) 2017-2020, The Monero Project
; See LICENSE ; See LICENSE
#define GuiVersion GetFileVersion("bin\monero-wallet-gui.exe") #define GuiVersion GetFileVersion("bin\monero-wallet-gui.exe")
@@ -11,7 +11,7 @@ AppName=Monero GUI Wallet
AppVersion={#GuiVersion} AppVersion={#GuiVersion}
VersionInfoVersion={#GuiVersion} VersionInfoVersion={#GuiVersion}
DefaultDirName={pf}\Monero GUI Wallet DefaultDirName={commonpf}\Monero GUI Wallet
DefaultGroupName=Monero GUI Wallet DefaultGroupName=Monero GUI Wallet
UninstallDisplayIcon={app}\monero-wallet-gui.exe UninstallDisplayIcon={app}\monero-wallet-gui.exe
PrivilegesRequired=admin PrivilegesRequired=admin
@@ -62,7 +62,6 @@ Name: "en"; MessagesFile: "compiler:Default.isl"
; .exe/.dll file possibly with version info). ; .exe/.dll file possibly with version info).
; ;
; This is far more robust than relying on version info or on file dates (flag "comparetimestamp"). ; This is far more robust than relying on version info or on file dates (flag "comparetimestamp").
; As of version 0.15.0.0, the Monero .exe files do not carry version info anyway in their .exe headers.
; The only small drawback seems to be somewhat longer update times because each and every file is ; The only small drawback seems to be somewhat longer update times because each and every file is
; copied again, even if already present with correct file date and identical content. ; copied again, even if already present with correct file date and identical content.
; ;
@@ -71,17 +70,18 @@ Name: "en"; MessagesFile: "compiler:Default.isl"
Source: {#file AddBackslash(SourcePath) + "ReadMe.htm"}; DestDir: "{app}"; DestName: "ReadMe.htm"; Flags: ignoreversion Source: {#file AddBackslash(SourcePath) + "ReadMe.htm"}; DestDir: "{app}"; DestName: "ReadMe.htm"; Flags: ignoreversion
Source: "FinishImage.bmp"; Flags: dontcopy Source: "FinishImage.bmp"; Flags: dontcopy
Source: "LICENSE"; DestDir: "{app}"; Flags: ignoreversion
; Monero GUI wallet exe and guide ; Monero GUI wallet exe and guide
Source: "bin\monero-wallet-gui.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\monero-wallet-gui.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\monero-gui-wallet-guide.pdf"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\monero-gui-wallet-guide.pdf"; DestDir: "{app}"; Flags: ignoreversion
; Monero CLI wallet ; Monero CLI wallet
Source: "bin\monero-wallet-cli.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-wallet-cli.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\monero-gen-trusted-multisig.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-gen-trusted-multisig.exe"; DestDir: "{app}"; Flags: ignoreversion
; Monero wallet RPC interface implementation ; Monero wallet RPC interface implementation
Source: "bin\monero-wallet-rpc.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-wallet-rpc.exe"; DestDir: "{app}"; Flags: ignoreversion
; Monero daemon ; Monero daemon
Source: "bin\monerod.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\monerod.exe"; DestDir: "{app}"; Flags: ignoreversion
@@ -90,16 +90,17 @@ Source: "bin\monerod.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "monero-daemon.bat"; DestDir: "{app}"; Flags: ignoreversion; Source: "monero-daemon.bat"; DestDir: "{app}"; Flags: ignoreversion;
; Monero blockchain utilities ; Monero blockchain utilities
Source: "bin\monero-blockchain-export.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-blockchain-export.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\monero-blockchain-import.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-blockchain-import.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\monero-blockchain-mark-spent-outputs.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-blockchain-mark-spent-outputs.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\monero-blockchain-usage.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-blockchain-usage.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\monero-blockchain-import.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-blockchain-import.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\monero-blockchain-ancestry.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-blockchain-ancestry.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\monero-blockchain-depth.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-blockchain-depth.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\monero-blockchain-prune-known-spent-data.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-blockchain-prune-known-spent-data.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\monero-blockchain-prune.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-blockchain-prune.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\monero-blockchain-stats.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\extras\monero-blockchain-stats.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "bin\extras\monero-gen-ssl-cert.exe"; DestDir: "{app}"; Flags: ignoreversion
; Qt Quick 2D Renderer fallback for systems / environments with "low-level graphics" i.e. without 3D support ; Qt Quick 2D Renderer fallback for systems / environments with "low-level graphics" i.e. without 3D support
Source: "bin\start-low-graphics-mode.bat"; DestDir: "{app}"; Flags: ignoreversion Source: "bin\start-low-graphics-mode.bat"; DestDir: "{app}"; Flags: ignoreversion
@@ -166,6 +167,7 @@ Type: files; Name: "{app}\libssp-0.dll"
Type: files; Name: "{app}\libhidapi-0.dll" Type: files; Name: "{app}\libhidapi-0.dll"
Type: files; Name: "{app}\libeay32.dll" Type: files; Name: "{app}\libeay32.dll"
Type: files; Name: "{app}\ssleay32.dll" Type: files; Name: "{app}\ssleay32.dll"
Type: files; Name: "{group}\Utilities\x (Check Blockchain Folder).lnk"
[Tasks] [Tasks]
@@ -201,7 +203,7 @@ begin
// Additional wizard page for entering a special blockchain location // Additional wizard page for entering a special blockchain location
blockChainDefaultDir := ExpandConstant('{commonappdata}\bitmonero'); blockChainDefaultDir := ExpandConstant('{commonappdata}\bitmonero');
s := 'The default folder to store the Monero blockchain is ' + blockChainDefaultDir; s := 'The default folder to store the Monero blockchain is ' + blockChainDefaultDir;
s := s + '. As this will need more than 74 GB of free space, you may want to use a folder on a different drive.'; s := s + '. As this will need more than 90 GB of free space, you may want to use a folder on a different drive.';
s := s + ' If yes, specify that folder here.'; s := s + ' If yes, specify that folder here.';
BlockChainDirPage := CreateInputDirPage(wpSelectDir, BlockChainDirPage := CreateInputDirPage(wpSelectDir,
@@ -333,7 +335,7 @@ Name: "{group}\Utilities\Textual (CLI) Wallet"; Filename: "{app}\monero-wallet-c
; Icons for troubleshooting problems / testing / debugging ; Icons for troubleshooting problems / testing / debugging
; To show that they are in some way different (not for everyday use), make them visually different ; To show that they are in some way different (not for everyday use), make them visually different
; from the others by text, and make them sort at the end by the help of "x" in front ; from the others by text, and make them sort at the end by the help of "x" in front
Name: "{group}\Utilities\x (Check Blockchain Folder)"; Filename: "{win}\Explorer.exe"; Parameters: {code:BlockChainDir} Name: "{group}\Utilities\x (Check Default Blockchain Folder)"; Filename: "{win}\Explorer.exe"; Parameters: {code:BlockChainDir}
Name: "{group}\Utilities\x (Check Daemon Log)"; Filename: "Notepad"; Parameters: {code:DaemonLog} Name: "{group}\Utilities\x (Check Daemon Log)"; Filename: "Notepad"; Parameters: {code:DaemonLog}
Name: "{group}\Utilities\x (Check Default Wallet Folder)"; Filename: "{win}\Explorer.exe"; Parameters: """{userdocs}\Monero\wallets""" Name: "{group}\Utilities\x (Check Default Wallet Folder)"; Filename: "{win}\Explorer.exe"; Parameters: """{userdocs}\Monero\wallets"""
Name: "{group}\Utilities\x (Check GUI Wallet Log)"; Filename: "Notepad"; Parameters: """{userappdata}\monero-wallet-gui\monero-wallet-gui.log""" Name: "{group}\Utilities\x (Check GUI Wallet Log)"; Filename: "Notepad"; Parameters: """{userappdata}\monero-wallet-gui\monero-wallet-gui.log"""

View File

@@ -1,12 +1,12 @@
# Monero GUI Wallet Windows Installer # # Monero GUI Wallet Windows Installer #
Copyright (c) 2017-2019, The Monero Project Copyright (c) 2017-2020, The Monero Project
## Introduction ## ## Introduction ##
This is a *Inno Setup* script `Monero.iss` plus some related files This is a *Inno Setup* script `Monero.iss` plus some related files
that allows you to build a standalone Windows installer (.exe) for that allows you to build a standalone Windows installer (.exe) for
the GUI wallet that comes with the Carbon Chamaeleon release of Monero. the GUI wallet that comes with the Nitrogen Nebula release of Monero.
This turns the GUI wallet into a more or less standard Windows program, This turns the GUI wallet into a more or less standard Windows program,
by default installed into a subdirectory of `C:\Program Files`, a by default installed into a subdirectory of `C:\Program Files`, a
@@ -18,7 +18,7 @@ Monero.
As the setup script in file [Monero.iss](Monero.iss) has to list many As the setup script in file [Monero.iss](Monero.iss) has to list many
files and directories of the GUI wallet package to install by name, files and directories of the GUI wallet package to install by name,
this version of the script only works with exactly the GUI wallet this version of the script only works with exactly the GUI wallet
for Monero release *Carbon Chamaeleon* that you find on for Monero release *Nitrogen Nebula* that you find on
[the official download page](https://getmonero.org/downloads/). [the official download page](https://getmonero.org/downloads/).
It should however be easy to modify the script for future It should however be easy to modify the script for future
@@ -32,15 +32,15 @@ See [LICENSE](LICENSE).
You can only build on Windows, and the result is always a You can only build on Windows, and the result is always a
Windows .exe file that can act as a standalone installer for the Windows .exe file that can act as a standalone installer for the
Carbon Chamaeleon GUI wallet. Nitrogen Nebula GUI wallet.
Note that the installer build process is now reproducible / deterministic. For details check the file [Deterministic.md](Deterministic.md). Note that the installer build process is now reproducible / deterministic. For details check the file [Deterministic.md](Deterministic.md).
The build steps in detail: The build steps in detail:
1. Install *Inno Setup*. You can get it from [here](http://www.jrsoftware.org/isdl.php) 1. Install *Inno Setup*. You can get it from [here](http://www.jrsoftware.org/isdl.php)
2. Get the Inno Setup script plus related files by cloning the whole [monero-gui GitHub repository](https://github.com/monero-project/monero-gui); you will only need the files in the installer directory `installers\windows` however. Depending on development state, additionally instead of simply using `master` you may have to checkout a specific branch, like `release-v0.15`. 2. Get the Inno Setup script plus related files by cloning the whole [monero-gui GitHub repository](https://github.com/monero-project/monero-gui); you will only need the files in the installer directory `installers\windows` however. Depending on development state, additionally instead of simply using `master` you may have to checkout a specific branch, like `release-v0.16`.
3. The setup script is written to take the GUI wallet files from a subdirectory named `bin`; so create `installers\windows\bin`, get the zip file of the GUI wallet from [here](https://getmonero.org/downloads/), unpack it somewhere, and copy all the files and subdirectories in the single subdirectory there (currently named `monero-gui-0.15.0.0`) to this `bin` subdirectory 3. The setup script is written to take the GUI wallet files from a subdirectory named `bin`; so create `installers\windows\bin`, get the zip file of the GUI wallet from [here](https://getmonero.org/downloads/), unpack it somewhere, and copy all the files and subdirectories in the single subdirectory there (currently named `monero-gui-0.16.0.0`) to this `bin` subdirectory
4. Start Inno Setup, load `Monero.iss` and compile it 4. Start Inno Setup, load `Monero.iss` and compile it
5. The result i.e. the finished installer will be the file `mysetup.exe` in the `installers\windows\Output` subdirectory 5. The result i.e. the finished installer will be the file `mysetup.exe` in the `installers\windows\Output` subdirectory

View File

@@ -1,12 +1,12 @@
<html> <html>
<head> <head>
<title>Monero Carbon Chamaeleon GUI Wallet</title> <title>Monero Nitrogen Nebula GUI Wallet</title>
</head> </head>
<body style="font-family: Arial, Helvetica, sans-serif"> <body style="font-family: Arial, Helvetica, sans-serif">
<h1>Monero Carbon Chamaeleon GUI Wallet</h1> <h1>Monero Nitrogen Nebula GUI Wallet</h1>
<p>Copyright (c) 2014-2019, The Monero Project</p> <p>Copyright (c) 2014-2020, The Monero Project</p>
<h2>Preface</h2> <h2>Preface</h2>
@@ -22,7 +22,7 @@
<h2>Content of the Package</h2> <h2>Content of the Package</h2>
<p>You just installed the <i>Monero GUI wallet</i> for Windows, release Carbon Chamaeleon, version {#GuiVersion}. <p>You just installed the <i>Monero GUI wallet</i> for Windows, release Nitrogen Nebula, version {#GuiVersion}.
The wallet enables you to send and receive Moneroj in a secure and very private way. The wallet enables you to send and receive Moneroj in a secure and very private way.
</p> </p>
@@ -60,7 +60,7 @@
provides the most security and privacy possible for you.</p> provides the most security and privacy possible for you.</p>
<p>However if your Internet access makes it difficult to run a full node, or if you have simply no room to store <p>However if your Internet access makes it difficult to run a full node, or if you have simply no room to store
the blockchain locally (somewhat over 74 GB in November 2019, and of course growing), you can compromise and try to connect the blockchain locally (about 90 GB in May 2020, and of course growing), you can compromise and try to connect
to a remote node. One way of finding such a node is checking to a remote node. One way of finding such a node is checking
<a href="https://moneroworld.com/#nodes">this page</a>. <a href="https://moneroworld.com/#nodes">this page</a>.
</p> </p>
@@ -104,7 +104,7 @@
<p>The Monero software and especially the GUI wallet are "work in progress", and sometimes things go wrong.</p> <p>The Monero software and especially the GUI wallet are "work in progress", and sometimes things go wrong.</p>
<p>Please note that despite any technical problems that you may encounter your moneroj are almost always safe: You may <p>Please note that despite any technical problems that you may encounter your Moneroj are almost always safe: You may
not be able to move them or you even may not see how many you currently have, but you most probably won't loose any. not be able to move them or you even may not see how many you currently have, but you most probably won't loose any.
But do remember that the seed needed to re-create the wallet <b>is</b> critical, however: <b>Never loose your But do remember that the seed needed to re-create the wallet <b>is</b> critical, however: <b>Never loose your
seed!</b></p> seed!</b></p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 KiB

After

Width:  |  Height:  |  Size: 440 KiB

View File

@@ -55,36 +55,14 @@ function ago(epoch) {
var now = new Date().getTime() / 1000; var now = new Date().getTime() / 1000;
var delta = now - epoch; var delta = now - epoch;
if(delta < 60) { if(delta < 60)
if (delta <= 1) { return qsTr("%n second(s) ago", "0", Math.floor(delta))
return 1 + " " + qsTr("second ago") else if (delta >= 60 && delta <= 3600)
} else { return qsTr("%n minute(s) ago", "0", Math.floor(delta / 60))
return Math.floor(delta) + " " + qsTr("seconds ago") else if (delta >= 3600 && delta <= 86400)
} return qsTr("%n hour(s) ago", "0", Math.floor(delta / 60 / 60))
} else if (delta >= 60 && delta <= 3600) { else if (delta >= 86400)
if(delta >= 60 && delta < 120){ return qsTr("%n day(s) ago", "0", Math.floor(delta / 24 / 60 / 60))
return 1 + " " + qsTr("minute ago")
} else {
return parseInt(Math.floor(delta / 60)) + " " + qsTr("minutes ago")
}
} else if (delta >= 3600 && delta <= 86400) {
if(delta >= 3600 && delta < 7200) {
return 1 + " " + qsTr("hour ago")
} else {
return parseInt(Math.floor(delta / 60 / 60)) + " " + qsTr("hours ago")
}
} else if (delta >= 86400){
if(delta >= 86400 && delta < 172800) {
return 1 + " " + qsTr("day ago")
} else {
var _delta = parseInt(Math.floor(delta / 24 / 60 / 60));
if(_delta === 1) {
return 1 + " " + qsTr("day ago")
} else {
return _delta + " " + qsTr("days ago")
}
}
}
} }
function netTypeToString(){ function netTypeToString(){
@@ -133,3 +111,7 @@ function capitalize(s){
if (typeof s !== 'string') return '' if (typeof s !== 'string') return ''
return s.charAt(0).toUpperCase() + s.slice(1) return s.charAt(0).toUpperCase() + s.slice(1)
} }
function removeTrailingZeros(value) {
return (value + '').replace(/(\.\d*[1-9])0+$/, '$1');
}

View File

@@ -58,11 +58,6 @@ function switchPage(next) {
} }
function createWalletPath(isIOS, folder_path,account_name){ function createWalletPath(isIOS, folder_path,account_name){
// Remove trailing slash - (default on windows and mac)
if (folder_path.substring(folder_path.length -1) === "/"){
folder_path = folder_path.substring(0,folder_path.length -1)
}
// Store releative path on ios. // Store releative path on ios.
if(isIOS) if(isIOS)
folder_path = ""; folder_path = "";
@@ -102,10 +97,6 @@ function tr(text) {
return qsTr(text) + translationManager.emptyString return qsTr(text) + translationManager.emptyString
} }
function lineBreaksToSpaces(text) {
return text.trim().replace(/(\r\n|\n|\r)/gm, " ");
}
function usefulName(path) { function usefulName(path) {
// arbitrary "short enough" limit // arbitrary "short enough" limit
if (path.length < 32) if (path.length < 32)
@@ -115,7 +106,7 @@ function usefulName(path) {
function checkSeed(seed) { function checkSeed(seed) {
console.log("Checking seed") console.log("Checking seed")
var wordsArray = lineBreaksToSpaces(seed).split(" "); var wordsArray = seed.split(/\s+/);
return wordsArray.length === 25 || wordsArray.length === 24 return wordsArray.length === 25 || wordsArray.length === 24
} }

BIN
lang/flags/nb_NO.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -55,6 +55,7 @@ Lojban
<language display_name="Suomi" locale="fi_FI" wallet_language="English" flag="/lang/flags/fi.png" qs="none"/> <language display_name="Suomi" locale="fi_FI" wallet_language="English" flag="/lang/flags/fi.png" qs="none"/>
<language display_name="Pirate" locale="prt" wallet_language="English" flag="/lang/flags/pirate.png" qs="none"/> <language display_name="Pirate" locale="prt" wallet_language="English" flag="/lang/flags/pirate.png" qs="none"/>
<language display_name="Български" locale="bg_BG" wallet_language="English" flag="/lang/flags/bg.png" qs="none"/> <language display_name="Български" locale="bg_BG" wallet_language="English" flag="/lang/flags/bg.png" qs="none"/>
<language display_name="Norwegian" locale="nb_NO" wallet_language="English" flag="/lang/flags/nb_NO.png" qs="none"/>
<!-- <language display_name="اُردُو" locale="ur_UR" wallet_language="English" flag="/lang/flags/pk.png" qs="none"/> --> <!-- <language display_name="اُردُو" locale="ur_UR" wallet_language="English" flag="/lang/flags/pk.png" qs="none"/> -->
<!-- <language display_name="فارسی" locale="fa_FA" wallet_language="English" flag="/lang/flags/ir.png" qs="none"/> --> <!-- <language display_name="فارسی" locale="fa_FA" wallet_language="English" flag="/lang/flags/ir.png" qs="none"/> -->
<!-- <language display_name="Zulu" locale="zu_ZU" wallet_language="English" flag="/lang/flags/za.png" qs="none"/> --> <!-- <language display_name="Zulu" locale="zu_ZU" wallet_language="English" flag="/lang/flags/za.png" qs="none"/> -->

388
main.qml
View File

@@ -34,6 +34,7 @@ import QtQuick.Dialogs 1.2
import QtGraphicalEffects 1.0 import QtGraphicalEffects 1.0
import moneroComponents.Wallet 1.0 import moneroComponents.Wallet 1.0
import moneroComponents.WalletManager 1.0
import moneroComponents.PendingTransaction 1.0 import moneroComponents.PendingTransaction 1.0
import moneroComponents.NetworkType 1.0 import moneroComponents.NetworkType 1.0
import moneroComponents.Settings 1.0 import moneroComponents.Settings 1.0
@@ -45,16 +46,20 @@ import "pages/merchant" as MoneroMerchant
import "wizard" import "wizard"
import "js/Utils.js" as Utils import "js/Utils.js" as Utils
import "js/Windows.js" as Windows import "js/Windows.js" as Windows
import "version.js" as Version
ApplicationWindow { ApplicationWindow {
id: appWindow id: appWindow
title: "Monero" + (walletName ? " - " + walletName : "") title: "Monero" + (walletName ? " - " + walletName : "")
minimumWidth: 750
minimumHeight: 450
property var currentItem property var currentItem
property bool hideBalanceForced: false property bool hideBalanceForced: false
property bool ctrlPressed: false property bool ctrlPressed: false
property alias persistentSettings : persistentSettings property alias persistentSettings : persistentSettings
property var currentWallet; property var currentWallet;
property bool disconnected: currentWallet ? currentWallet.disconnected : false
property var transaction; property var transaction;
property var transactionDescription; property var transactionDescription;
property var walletPassword property var walletPassword
@@ -62,13 +67,15 @@ ApplicationWindow {
property bool daemonSynced: false property bool daemonSynced: false
property bool walletSynced: false property bool walletSynced: false
property int maxWindowHeight: (isAndroid || isIOS)? screenHeight : (screenHeight < 900)? 720 : 800; property int maxWindowHeight: (isAndroid || isIOS)? screenHeight : (screenHeight < 900)? 720 : 800;
property bool daemonRunning: false property bool daemonRunning: !persistentSettings.useRemoteNode && !disconnected
property bool daemonStartStopInProgress: false
property alias toolTip: toolTip property alias toolTip: toolTip
property string walletName property string walletName
property bool viewOnly: false property bool viewOnly: false
property bool foundNewBlock: false property bool foundNewBlock: false
property bool qrScannerEnabled: (typeof builtWithScanner != "undefined") && builtWithScanner property bool qrScannerEnabled: (typeof builtWithScanner != "undefined") && builtWithScanner
property int blocksToSync: 1 property int blocksToSync: 1
property int firstBlockSeen
property bool isMining: false property bool isMining: false
property int walletMode: persistentSettings.walletMode property int walletMode: persistentSettings.walletMode
property var cameraUi property var cameraUi
@@ -211,7 +218,7 @@ ApplicationWindow {
appWindow.viewState = prevState; appWindow.viewState = prevState;
} }
}; };
passwordDialog.open(usefulName(walletPath())); passwordDialog.open(usefulName(persistentSettings.wallet_path));
} }
function initialize() { function initialize() {
@@ -247,10 +254,9 @@ ApplicationWindow {
// enable timers // enable timers
userInActivityTimer.running = true; userInActivityTimer.running = true;
simpleModeConnectionTimer.running = true;
// wallet already opened with wizard, we just need to initialize it // wallet already opened with wizard, we just need to initialize it
var wallet_path = walletPath(); var wallet_path = persistentSettings.wallet_path;
if(isIOS) if(isIOS)
wallet_path = moneroAccountsDir + wallet_path; wallet_path = moneroAccountsDir + wallet_path;
// console.log("opening wallet at: ", wallet_path, "with password: ", appWindow.walletPassword); // console.log("opening wallet at: ", wallet_path, "with password: ", appWindow.walletPassword);
@@ -288,6 +294,7 @@ ApplicationWindow {
currentWallet.connectionStatusChanged.disconnect(onWalletConnectionStatusChanged) currentWallet.connectionStatusChanged.disconnect(onWalletConnectionStatusChanged)
currentWallet.deviceButtonRequest.disconnect(onDeviceButtonRequest); currentWallet.deviceButtonRequest.disconnect(onDeviceButtonRequest);
currentWallet.deviceButtonPressed.disconnect(onDeviceButtonPressed); currentWallet.deviceButtonPressed.disconnect(onDeviceButtonPressed);
currentWallet.walletPassphraseNeeded.disconnect(onWalletPassphraseNeededWallet);
currentWallet.transactionCommitted.disconnect(onTransactionCommitted); currentWallet.transactionCommitted.disconnect(onTransactionCommitted);
middlePanel.paymentClicked.disconnect(handlePayment); middlePanel.paymentClicked.disconnect(handlePayment);
middlePanel.sweepUnmixableClicked.disconnect(handleSweepUnmixable); middlePanel.sweepUnmixableClicked.disconnect(handleSweepUnmixable);
@@ -355,6 +362,7 @@ ApplicationWindow {
currentWallet.connectionStatusChanged.connect(onWalletConnectionStatusChanged) currentWallet.connectionStatusChanged.connect(onWalletConnectionStatusChanged)
currentWallet.deviceButtonRequest.connect(onDeviceButtonRequest); currentWallet.deviceButtonRequest.connect(onDeviceButtonRequest);
currentWallet.deviceButtonPressed.connect(onDeviceButtonPressed); currentWallet.deviceButtonPressed.connect(onDeviceButtonPressed);
currentWallet.walletPassphraseNeeded.connect(onWalletPassphraseNeededWallet);
currentWallet.transactionCommitted.connect(onTransactionCommitted); currentWallet.transactionCommitted.connect(onTransactionCommitted);
middlePanel.paymentClicked.connect(handlePayment); middlePanel.paymentClicked.connect(handlePayment);
middlePanel.sweepUnmixableClicked.connect(handleSweepUnmixable); middlePanel.sweepUnmixableClicked.connect(handleSweepUnmixable);
@@ -389,11 +397,6 @@ ApplicationWindow {
return !persistentSettings.useRemoteNode || persistentSettings.is_trusted_daemon; return !persistentSettings.useRemoteNode || persistentSettings.is_trusted_daemon;
} }
function walletPath() {
var wallet_path = persistentSettings.wallet_path
return wallet_path;
}
function usefulName(path) { function usefulName(path) {
// arbitrary "short enough" limit // arbitrary "short enough" limit
if (path.length < 32) if (path.length < 32)
@@ -471,20 +474,12 @@ ApplicationWindow {
console.log("Wallet connection status changed " + status) console.log("Wallet connection status changed " + status)
middlePanel.updateStatus(); middlePanel.updateStatus();
leftPanel.networkStatus.connected = status leftPanel.networkStatus.connected = status
if (status == Wallet.ConnectionStatus_Disconnected) {
// update local daemon status. firstBlockSeen = 0;
const isDisconnected = status === Wallet.ConnectionStatus_Disconnected;
if (!persistentSettings.useRemoteNode) {
daemonRunning = !isDisconnected;
} else {
daemonRunning = false;
} }
// Update fee multiplier dropdown on transfer page
middlePanel.transferView.updatePriorityDropdown();
// If wallet isnt connected, advanced wallet mode and no daemon is running - Ask // If wallet isnt connected, advanced wallet mode and no daemon is running - Ask
if (appWindow.walletMode >= 2 && !persistentSettings.useRemoteNode && !walletInitialized && isDisconnected) { if (appWindow.walletMode >= 2 && !persistentSettings.useRemoteNode && !walletInitialized && disconnected) {
daemonManager.runningAsync(persistentSettings.nettype, function(running) { daemonManager.runningAsync(persistentSettings.nettype, function(running) {
if (!running) { if (!running) {
daemonManagerDialog.open(); daemonManagerDialog.open();
@@ -563,21 +558,32 @@ ApplicationWindow {
} }
} }
function onWalletPassphraseNeeded(){ function onWalletPassphraseNeededManager(on_device){
if(rootItem.state !== "normal") return; onWalletPassphraseNeeded(walletManager, on_device)
}
function onWalletPassphraseNeededWallet(on_device){
onWalletPassphraseNeeded(currentWallet, on_device)
}
function onWalletPassphraseNeeded(handler, on_device){
hideProcessingSplash(); hideProcessingSplash();
console.log(">>> wallet passphrase needed: ") console.log(">>> wallet passphrase needed: ")
passwordDialog.onAcceptedPassphraseCallback = function() { devicePassphraseDialog.onAcceptedCallback = function(passphrase) {
walletManager.onPassphraseEntered(passwordDialog.password); handler.onPassphraseEntered(passphrase, false, false);
this.onWalletOpening(); appWindow.onWalletOpening();
} }
passwordDialog.onRejectedPassphraseCallback = function() { devicePassphraseDialog.onWalletEntryCallback = function() {
walletManager.onPassphraseEntered("", true); handler.onPassphraseEntered("", true, false);
this.onWalletOpening(); appWindow.onWalletOpening();
} }
passwordDialog.openPassphraseDialog() devicePassphraseDialog.onRejectedCallback = function() {
handler.onPassphraseEntered("", false, true);
appWindow.onWalletOpening();
}
devicePassphraseDialog.open(on_device)
} }
function onWalletUpdate() { function onWalletUpdate() {
@@ -620,18 +626,22 @@ ApplicationWindow {
currentDaemonAddress = localDaemonAddress currentDaemonAddress = localDaemonAddress
currentWallet.initAsync(currentDaemonAddress, isTrustedDaemon()); currentWallet.initAsync(currentDaemonAddress, isTrustedDaemon());
walletManager.setDaemonAddressAsync(currentDaemonAddress); walletManager.setDaemonAddressAsync(currentDaemonAddress);
firstBlockSeen = 0;
} }
function onHeightRefreshed(bcHeight, dCurrentBlock, dTargetBlock) { function onHeightRefreshed(bcHeight, dCurrentBlock, dTargetBlock) {
// Daemon fully synced // Daemon fully synced
// TODO: implement onDaemonSynced or similar in wallet API and don't start refresh thread before daemon is synced // TODO: implement onDaemonSynced or similar in wallet API and don't start refresh thread before daemon is synced
// targetBlock = currentBlock = 1 before network connection is established. // targetBlock = currentBlock = 1 before network connection is established.
if (firstBlockSeen == 0 && dTargetBlock != 1) {
firstBlockSeen = dCurrentBlock;
}
daemonSynced = dCurrentBlock >= dTargetBlock && dTargetBlock != 1 daemonSynced = dCurrentBlock >= dTargetBlock && dTargetBlock != 1
walletSynced = bcHeight >= dTargetBlock walletSynced = bcHeight >= dTargetBlock
// Update progress bars // Update progress bars
if(!daemonSynced) { if(!daemonSynced) {
leftPanel.daemonProgressBar.updateProgress(dCurrentBlock,dTargetBlock, dTargetBlock-dCurrentBlock); leftPanel.daemonProgressBar.updateProgress(dCurrentBlock,dTargetBlock, dTargetBlock-firstBlockSeen);
leftPanel.progressBar.updateProgress(0,dTargetBlock, dTargetBlock, qsTr("Waiting for daemon to sync")); leftPanel.progressBar.updateProgress(0,dTargetBlock, dTargetBlock, qsTr("Waiting for daemon to sync"));
} else { } else {
leftPanel.daemonProgressBar.updateProgress(dCurrentBlock,dTargetBlock, 0, qsTr("Daemon is synchronized (%1)").arg(dCurrentBlock.toFixed(0))); leftPanel.daemonProgressBar.updateProgress(dCurrentBlock,dTargetBlock, 0, qsTr("Daemon is synchronized (%1)").arg(dCurrentBlock.toFixed(0)));
@@ -640,7 +650,7 @@ ApplicationWindow {
} }
// Update wallet sync progress // Update wallet sync progress
leftPanel.isSyncing = (currentWallet.connected() !== Wallet.ConnectionStatus_Disconnected) && !daemonSynced leftPanel.isSyncing = !disconnected && !daemonSynced;
// Update transfer page status // Update transfer page status
middlePanel.updateStatus(); middlePanel.updateStatus();
@@ -666,54 +676,55 @@ ApplicationWindow {
console.log(">>> wallet refreshed") console.log(">>> wallet refreshed")
// Daemon connected // Daemon connected
leftPanel.networkStatus.connected = currentWallet.connected() leftPanel.networkStatus.connected = currentWallet ? currentWallet.connected() : Wallet.ConnectionStatus_Disconnected
currentWallet.refreshHeightAsync(); currentWallet.refreshHeightAsync();
} }
function startDaemon(flags){ function startDaemon(flags){
daemonStartStopInProgress = true;
// Pause refresh while starting daemon // Pause refresh while starting daemon
currentWallet.pauseRefresh(); currentWallet.pauseRefresh();
// Pause simplemode connection timer
simpleModeConnectionTimer.stop();
appWindow.showProcessingSplash(qsTr("Waiting for daemon to start...")) appWindow.showProcessingSplash(qsTr("Waiting for daemon to start..."))
const noSync = appWindow.walletMode === 0; const noSync = appWindow.walletMode === 0;
daemonManager.start(flags, persistentSettings.nettype, persistentSettings.blockchainDataDir, persistentSettings.bootstrapNodeAddress, noSync); const bootstrapNodeAddress = persistentSettings.walletMode < 2 ? "auto" : persistentSettings.bootstrapNodeAddress
daemonManager.start(flags, persistentSettings.nettype, persistentSettings.blockchainDataDir, bootstrapNodeAddress, noSync);
} }
function stopDaemon(){ function stopDaemon(callback){
daemonStartStopInProgress = true;
appWindow.showProcessingSplash(qsTr("Waiting for daemon to stop...")) appWindow.showProcessingSplash(qsTr("Waiting for daemon to stop..."))
daemonManager.stop(persistentSettings.nettype); daemonManager.stopAsync(persistentSettings.nettype, function(result) {
daemonStartStopInProgress = false;
hideProcessingSplash();
callback(result);
});
} }
function onDaemonStarted(){ function onDaemonStarted(){
console.log("daemon started"); console.log("daemon started");
daemonRunning = true; daemonStartStopInProgress = false;
hideProcessingSplash(); hideProcessingSplash();
currentWallet.connected(true); currentWallet.connected(true);
// resume refresh // resume refresh
currentWallet.startRefresh(); currentWallet.startRefresh();
// resume simplemode connection timer // resume simplemode connection timer
appWindow.disconnectedEpoch = Utils.epoch(); appWindow.disconnectedEpoch = Utils.epoch();
simpleModeConnectionTimer.start();
} }
function onDaemonStopped(){ function onDaemonStopped(){
console.log("daemon stopped");
hideProcessingSplash();
daemonRunning = false;
currentWallet.connected(true); currentWallet.connected(true);
} }
function onDaemonStartFailure(){ function onDaemonStartFailure(error) {
console.log("daemon start failed"); console.log("daemon start failed");
daemonStartStopInProgress = false;
hideProcessingSplash(); hideProcessingSplash();
// resume refresh // resume refresh
currentWallet.startRefresh(); currentWallet.startRefresh();
daemonRunning = false;
informationPopup.title = qsTr("Daemon failed to start") + translationManager.emptyString; 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.text = error + ".\n\n" + 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.icon = StandardIcon.Critical
informationPopup.onCloseCallback = null informationPopup.onCloseCallback = null
informationPopup.open(); informationPopup.open();
@@ -984,7 +995,11 @@ ApplicationWindow {
informationPopup.open() informationPopup.open()
currentWallet.refresh() currentWallet.refresh()
currentWallet.disposeTransaction(transaction) currentWallet.disposeTransaction(transaction)
currentWallet.store(); currentWallet.storeAsync(function(success) {
if (!success) {
appWindow.showStatusMessage(qsTr("Failed to store the wallet"), 3);
}
});
} }
// called on "getProof" // called on "getProof"
@@ -1084,7 +1099,6 @@ ApplicationWindow {
console.log("Displaying processing splash") console.log("Displaying processing splash")
if (typeof message != 'undefined') { if (typeof message != 'undefined') {
splash.messageText = message splash.messageText = message
splash.heightProgressText = ""
} }
leftPanel.enabled = false; leftPanel.enabled = false;
@@ -1111,14 +1125,15 @@ ApplicationWindow {
wizard.restart(); wizard.restart();
wizard.wizardState = "wizardHome"; wizard.wizardState = "wizardHome";
rootItem.state = "wizard" rootItem.state = "wizard"
// reset balance // reset balance, clear spendable funds message
clearMoneroCardLabelText(); clearMoneroCardLabelText();
leftPanel.minutesToUnlock = "";
// reset fields
middlePanel.addressBookView.clearFields(); middlePanel.addressBookView.clearFields();
middlePanel.transferView.clearFields(); middlePanel.transferView.clearFields();
middlePanel.receiveView.clearFields(); middlePanel.receiveView.clearFields();
// disable timers // disable timers
userInActivityTimer.running = false; userInActivityTimer.running = false;
simpleModeConnectionTimer.running = false;
}); });
} }
@@ -1143,9 +1158,9 @@ ApplicationWindow {
triggeredOnStart: false triggeredOnStart: false
} }
function fiatApiParseTicker(resp, currency){ function fiatApiParseTicker(url, resp, currency){
// parse & validate incoming JSON // parse & validate incoming JSON
if(resp._url.startsWith("https://api.kraken.com/0/")){ if(url.startsWith("https://api.kraken.com/0/")){
if(resp.hasOwnProperty("error") && resp.error.length > 0 || !resp.hasOwnProperty("result")){ if(resp.hasOwnProperty("error") && resp.error.length > 0 || !resp.hasOwnProperty("result")){
appWindow.fiatApiError("Kraken API has error(s)"); appWindow.fiatApiError("Kraken API has error(s)");
return; return;
@@ -1154,14 +1169,14 @@ ApplicationWindow {
var key = currency === "xmreur" ? "XXMRZEUR" : "XXMRZUSD"; var key = currency === "xmreur" ? "XXMRZEUR" : "XXMRZUSD";
var ticker = resp.result[key]["o"]; var ticker = resp.result[key]["o"];
return ticker; return ticker;
} else if(resp._url.startsWith("https://api.coingecko.com/api/v3/")){ } else if(url.startsWith("https://api.coingecko.com/api/v3/")){
var key = currency === "xmreur" ? "eur" : "usd"; var key = currency === "xmreur" ? "eur" : "usd";
if(!resp.hasOwnProperty("monero") || !resp["monero"].hasOwnProperty(key)){ if(!resp.hasOwnProperty("monero") || !resp["monero"].hasOwnProperty(key)){
appWindow.fiatApiError("Coingecko API has error(s)"); appWindow.fiatApiError("Coingecko API has error(s)");
return; return;
} }
return resp["monero"][key]; return resp["monero"][key];
} else if(resp._url.startsWith("https://min-api.cryptocompare.com/data/")){ } else if(url.startsWith("https://min-api.cryptocompare.com/data/")){
var key = currency === "xmreur" ? "EUR" : "USD"; var key = currency === "xmreur" ? "EUR" : "USD";
if(!resp.hasOwnProperty(key)){ if(!resp.hasOwnProperty(key)){
appWindow.fiatApiError("cryptocompare API has error(s)"); appWindow.fiatApiError("cryptocompare API has error(s)");
@@ -1171,13 +1186,7 @@ ApplicationWindow {
} }
} }
function fiatApiGetCurrency(resp){ function fiatApiGetCurrency(url) {
// map response to `appWindow.fiatPriceAPIs` object
if (!resp.hasOwnProperty('_url')){
appWindow.fiatApiError("invalid JSON");
return;
}
var apis = appWindow.fiatPriceAPIs; var apis = appWindow.fiatPriceAPIs;
for (var api in apis){ for (var api in apis){
if (!apis.hasOwnProperty(api)) if (!apis.hasOwnProperty(api))
@@ -1187,23 +1196,34 @@ ApplicationWindow {
if(!apis[api].hasOwnProperty(cur)) if(!apis[api].hasOwnProperty(cur))
continue; continue;
var url = apis[api][cur]; if (apis[api][cur] === url) {
if(url === resp._url){
return cur; return cur;
} }
} }
} }
} }
function fiatApiJsonReceived(resp){ function fiatApiJsonReceived(url, resp, error) {
if (error) {
appWindow.fiatApiError(error);
return;
}
try {
resp = JSON.parse(resp);
} catch (e) {
appWindow.fiatApiError("bad JSON: " + e);
return;
}
// handle incoming JSON, set ticker // handle incoming JSON, set ticker
var currency = appWindow.fiatApiGetCurrency(resp); var currency = appWindow.fiatApiGetCurrency(url);
if(typeof currency == "undefined"){ if(typeof currency == "undefined"){
appWindow.fiatApiError("could not get currency"); appWindow.fiatApiError("could not get currency");
return; return;
} }
var ticker = appWindow.fiatApiParseTicker(resp, currency); var ticker = appWindow.fiatApiParseTicker(url, resp, currency);
if(ticker <= 0){ if(ticker <= 0){
appWindow.fiatApiError("could not get ticker"); appWindow.fiatApiError("could not get ticker");
return; return;
@@ -1235,7 +1255,7 @@ ApplicationWindow {
} }
var url = provider[userCurrency]; var url = provider[userCurrency];
Prices.getJSON(url); Network.getJSON(url, fiatApiJsonReceived);
} }
function fiatApiCurrencySymbol() { function fiatApiCurrencySymbol() {
@@ -1291,9 +1311,8 @@ ApplicationWindow {
walletManager.deviceButtonRequest.connect(onDeviceButtonRequest); walletManager.deviceButtonRequest.connect(onDeviceButtonRequest);
walletManager.deviceButtonPressed.connect(onDeviceButtonPressed); walletManager.deviceButtonPressed.connect(onDeviceButtonPressed);
walletManager.checkUpdatesComplete.connect(onWalletCheckUpdatesComplete); walletManager.checkUpdatesComplete.connect(onWalletCheckUpdatesComplete);
walletManager.walletPassphraseNeeded.connect(onWalletPassphraseNeeded); walletManager.walletPassphraseNeeded.connect(onWalletPassphraseNeededManager);
IPC.uriHandler.connect(onUriHandler); IPC.uriHandler.connect(onUriHandler);
Prices.priceJsonReceived.connect(appWindow.fiatApiJsonReceived);
if(typeof daemonManager != "undefined") { if(typeof daemonManager != "undefined") {
daemonManager.daemonStarted.connect(onDaemonStarted); daemonManager.daemonStarted.connect(onDaemonStarted);
@@ -1325,8 +1344,6 @@ ApplicationWindow {
openWallet("wizard"); openWallet("wizard");
} }
checkUpdates();
if(persistentSettings.fiatPriceEnabled){ if(persistentSettings.fiatPriceEnabled){
appWindow.fiatApiRefresh(); appWindow.fiatApiRefresh();
appWindow.fiatTimerStart(); appWindow.fiatTimerStart();
@@ -1371,10 +1388,14 @@ ApplicationWindow {
property int segregationHeight: 0 property int segregationHeight: 0
property int kdfRounds: 1 property int kdfRounds: 1
property bool hideBalance: false property bool hideBalance: false
property bool askPasswordBeforeSending: true
property bool lockOnUserInActivity: true property bool lockOnUserInActivity: true
property int walletMode: 2 property int walletMode: 2
property int lockOnUserInActivityInterval: 10 // minutes property int lockOnUserInActivityInterval: 10 // minutes
property bool blackTheme: true property bool blackTheme: true
property bool checkForUpdates: true
property bool autosave: true
property int autosaveMinutes: 10
property bool fiatPriceEnabled: false property bool fiatPriceEnabled: false
property bool fiatPriceToggle: false property bool fiatPriceToggle: false
@@ -1406,21 +1427,28 @@ ApplicationWindow {
z: parent.z + 1 z: parent.z + 1
id: transactionConfirmationPopup id: transactionConfirmationPopup
onAccepted: { onAccepted: {
var handleAccepted = function() {
// Save transaction to file if view only wallet
if (viewOnly) {
saveTxDialog.open();
} else {
handleTransactionConfirmed()
}
}
close(); close();
passwordDialog.onAcceptedCallback = function() { passwordDialog.onAcceptedCallback = function() {
if(walletPassword === passwordDialog.password){ if(walletPassword === passwordDialog.password){
// Save transaction to file if view only wallet handleAccepted()
if(viewOnly) {
saveTxDialog.open();
} else {
handleTransactionConfirmed()
}
} else { } else {
passwordDialog.showError(qsTr("Wrong password") + translationManager.emptyString); passwordDialog.showError(qsTr("Wrong password") + translationManager.emptyString);
} }
} }
passwordDialog.onRejectedCallback = null; passwordDialog.onRejectedCallback = null;
passwordDialog.open() if(!persistentSettings.askPasswordBeforeSending) {
handleAccepted()
} else {
passwordDialog.open()
}
} }
} }
@@ -1440,6 +1468,14 @@ ApplicationWindow {
} }
} }
MoneroComponents.UpdateDialog {
id: updateDialog
allowed: !passwordDialog.visible && !inputDialog.visible && !splash.visible
x: (parent.width - width) / 2
y: (parent.height - height) / 2
}
// Choose blockchain folder // Choose blockchain folder
FileDialog { FileDialog {
id: blockchainFileDialog id: blockchainFileDialog
@@ -1469,7 +1505,6 @@ ApplicationWindow {
confirmationDialog.text += qsTr("Note: lmdb folder not found. A new folder will be created.") + "\n\n" confirmationDialog.text += qsTr("Note: lmdb folder not found. A new folder will be created.") + "\n\n"
confirmationDialog.icon = StandardIcon.Question confirmationDialog.icon = StandardIcon.Question
confirmationDialog.cancelText = qsTr("Cancel")
// Continue // Continue
confirmationDialog.onAcceptedCallback = function() { confirmationDialog.onAcceptedCallback = function() {
@@ -1489,12 +1524,10 @@ ApplicationWindow {
PasswordDialog { PasswordDialog {
id: passwordDialog id: passwordDialog
visible: false visible: false
z: parent.z + 1 z: parent.z + 2
anchors.fill: parent anchors.fill: parent
property var onAcceptedCallback property var onAcceptedCallback
property var onRejectedCallback property var onRejectedCallback
property var onAcceptedPassphraseCallback
property var onRejectedPassphraseCallback
onAccepted: { onAccepted: {
if (onAcceptedCallback) if (onAcceptedCallback)
onAcceptedCallback(); onAcceptedCallback();
@@ -1518,14 +1551,13 @@ ApplicationWindow {
informationPopup.open(); informationPopup.open();
} }
onRejectedNewPassword: {} onRejectedNewPassword: {}
onAcceptedPassphrase: { }
if (onAcceptedPassphraseCallback)
onAcceptedPassphraseCallback(); DevicePassphraseDialog {
} id: devicePassphraseDialog
onRejectedPassphrase: { visible: false
if (onRejectedPassphraseCallback) z: parent.z + 1
onRejectedPassphraseCallback(); anchors.fill: parent
}
} }
InputDialog { InputDialog {
@@ -1556,8 +1588,8 @@ ApplicationWindow {
ProcessingSplash { ProcessingSplash {
id: splash id: splash
width: appWindow.width / 1.5 width: appWindow.width / 2
height: appWindow.height / 2 height: appWindow.height / 2.66
x: (appWindow.width - width) / 2 x: (appWindow.width - width) / 2
y: (appWindow.height - height) / 2 y: (appWindow.height - height) / 2
messageText: qsTr("Please wait...") + translationManager.emptyString messageText: qsTr("Please wait...") + translationManager.emptyString
@@ -1615,12 +1647,6 @@ ApplicationWindow {
updateBalance(); updateBalance();
} }
onMerchantClicked: {
middlePanel.state = "Merchant";
middlePanel.flickable.contentY = 0;
updateBalance();
}
onTxkeyClicked: { onTxkeyClicked: {
middlePanel.state = "TxKey"; middlePanel.state = "TxKey";
middlePanel.flickable.contentY = 0; middlePanel.flickable.contentY = 0;
@@ -1679,6 +1705,15 @@ ApplicationWindow {
anchors.right: parent.right anchors.right: parent.right
state: "Transfer" state: "Transfer"
} }
WizardController {
id: wizard
anchors.fill: parent
onUseMoneroClicked: {
rootItem.state = "normal";
appWindow.openWallet("wizard");
}
}
} }
FastBlur { FastBlur {
@@ -1686,23 +1721,9 @@ ApplicationWindow {
anchors.fill: blurredArea anchors.fill: blurredArea
source: blurredArea source: blurredArea
radius: 64 radius: 64
visible: passwordDialog.visible || inputDialog.visible || splash.visible visible: passwordDialog.visible || inputDialog.visible || splash.visible || updateDialog.visible || devicePassphraseDialog.visible
} }
WizardController {
id: wizard
anchors.fill: parent
onUseMoneroClicked: {
rootItem.state = "normal";
appWindow.openWallet("wizard");
}
}
WizardLang {
id: languageView
visible: false
anchors.fill: parent
}
property int minWidth: 326 property int minWidth: 326
property int minHeight: 400 property int minHeight: 400
@@ -1801,16 +1822,10 @@ ApplicationWindow {
color: "#FFFFFF" color: "#FFFFFF"
} }
} }
Notifier {
visible:false
id: notifier
}
} }
function toggleLanguageView(){ function toggleLanguageView(){
middlePanel.visible = !middlePanel.visible; languageSidebar.isOpened ? languageSidebar.close() : languageSidebar.open();
languageView.visible = !languageView.visible
resetLanguageFields() resetLanguageFields()
// update after changing language from settings page // update after changing language from settings page
if (persistentSettings.language != wizard.language_language) { if (persistentSettings.language != wizard.language_language) {
@@ -1819,6 +1834,24 @@ ApplicationWindow {
} }
} }
Timer {
id: autosaveTimer
interval: persistentSettings.autosaveMinutes * 60 * 1000
repeat: true
running: persistentSettings.autosave
onTriggered: {
if (currentWallet) {
currentWallet.storeAsync(function(success) {
if (success) {
appWindow.showStatusMessage(qsTr("Autosaved the wallet"), 3);
} else {
appWindow.showStatusMessage(qsTr("Failed to autosave the wallet"), 3);
}
});
}
}
}
// TODO: Make the callback dynamic // TODO: Make the callback dynamic
Timer { Timer {
id: statusMessageTimer id: statusMessageTimer
@@ -1858,17 +1891,13 @@ ApplicationWindow {
} }
function checkSimpleModeConnection(){ function checkSimpleModeConnection(){
// auto-connection mechanism for simple mode
if(appWindow.walletMode >= 2) return;
const disconnectedTimeoutSec = 30; const disconnectedTimeoutSec = 30;
const firstCheckDelaySec = 2; const firstCheckDelaySec = 2;
const connected = leftPanel.networkStatus.connected !== Wallet.ConnectionStatus_Disconnected;
const firstRun = appWindow.disconnectedEpoch == 0; const firstRun = appWindow.disconnectedEpoch == 0;
if (firstRun) { if (firstRun) {
appWindow.disconnectedEpoch = Utils.epoch() + firstCheckDelaySec - disconnectedTimeoutSec; appWindow.disconnectedEpoch = Utils.epoch() + firstCheckDelaySec - disconnectedTimeoutSec;
} else if (connected) { } else if (!disconnected) {
appWindow.disconnectedEpoch = Utils.epoch(); appWindow.disconnectedEpoch = Utils.epoch();
} }
@@ -1878,15 +1907,20 @@ ApplicationWindow {
} }
if (appWindow.daemonRunning) { if (appWindow.daemonRunning) {
appWindow.stopDaemon(); appWindow.stopDaemon(function() {
appWindow.startDaemon("")
});
} else {
appWindow.startDaemon("");
} }
appWindow.startDaemon("");
} }
Timer { Timer {
// Simple mode connection check timer // Simple mode connection check timer
id: simpleModeConnectionTimer id: simpleModeConnectionTimer
interval: 2000; running: false; repeat: true interval: 2000
running: appWindow.walletMode < 2 && currentWallet != undefined && !daemonStartStopInProgress
repeat: true
onTriggered: appWindow.checkSimpleModeConnection() onTriggered: appWindow.checkSimpleModeConnection()
} }
@@ -1935,8 +1969,7 @@ ApplicationWindow {
onClose(); onClose();
} }
confirmationDialog.onRejectedCallback = function() { confirmationDialog.onRejectedCallback = function() {
daemonManager.stop(persistentSettings.nettype); stopDaemon(onClose);
onClose();
}; };
confirmationDialog.open(); confirmationDialog.open();
} }
@@ -1961,15 +1994,26 @@ ApplicationWindow {
} }
// If daemon is running - prompt user before exiting // If daemon is running - prompt user before exiting
if(typeof daemonManager != "undefined" && daemonRunning) { if(daemonManager == undefined || persistentSettings.useRemoteNode) {
if (appWindow.walletMode == 0) {
stopDaemon();
closeAccepted();
} else {
showDaemonIsRunningDialog(closeAccepted);
}
} else {
closeAccepted(); closeAccepted();
} else if (appWindow.walletMode == 0) {
stopDaemon(closeAccepted);
} else {
showProcessingSplash(qsTr("Checking local node status..."));
const handler = function(running) {
hideProcessingSplash();
if (running) {
showDaemonIsRunningDialog(closeAccepted);
} else {
closeAccepted();
}
};
if (currentWallet) {
handler(!currentWallet.disconnected);
} else {
daemonManager.runningAsync(persistentSettings.nettype, handler);
}
} }
} }
@@ -1981,34 +2025,42 @@ ApplicationWindow {
closeWallet(Qt.quit); closeWallet(Qt.quit);
} }
function onWalletCheckUpdatesComplete(update) { function onWalletCheckUpdatesComplete(version, downloadUrl, hash, firstSigner, secondSigner) {
if (update === "") const alreadyAsked = updateDialog.url == downloadUrl && updateDialog.hash == hash;
return if (!alreadyAsked)
print("Update found: " + update) {
var parts = update.split("|") updateDialog.show(version, isMac || isWindows || isLinux ? downloadUrl : "", hash);
if (parts.length == 4) {
var version = parts[0]
var hash = parts[1]
var user_url = parts[2]
var msg = ""
if (isMac || isWindows || isLinux) {
msg = qsTr("New version of Monero v%1 is available.<br><br>Download:<br>%2<br><br>SHA256 Hash:<br>%3").arg(version).arg(user_url).arg(hash) + translationManager.emptyString
} else {
msg = qsTr("New version of Monero v%1 is available. Check out getmonero.org").arg(version) + translationManager.emptyString
}
notifier.show(msg)
} else {
print("Failed to parse update spec")
} }
} }
function getBuildTag() {
if (isMac) {
return "mac-x64";
}
if (isWindows) {
return oshelper.installed ? "install-win-x64" : "win-x64";
}
if (isLinux) {
return "linux-x64";
}
return "source";
}
function checkUpdates() { function checkUpdates() {
walletManager.checkUpdatesAsync("monero-gui", "gui") const version = Version.GUI_VERSION.match(/\d+\.\d+\.\d+\.\d+/);
if (version) {
walletManager.checkUpdatesAsync("monero-gui", "gui", getBuildTag(), version[0]);
} else {
console.error("failed to parse version number", Version.GUI_VERSION);
}
} }
Timer { Timer {
id: updatesTimer id: updatesTimer
interval: 3600*1000; running: true; repeat: true interval: 3600 * 1000
repeat: true
running: !disableCheckUpdatesFlag && persistentSettings.checkForUpdates
triggeredOnStart: true
onTriggered: checkUpdates() onTriggered: checkUpdates()
} }
@@ -2087,9 +2139,8 @@ ApplicationWindow {
function applyWalletMode(mode){ function applyWalletMode(mode){
if (mode < 2) { if (mode < 2) {
persistentSettings.useRemoteNode = false; persistentSettings.useRemoteNode = false;
persistentSettings.bootstrapNodeAddress = "auto";
if (middlePanel.settingsView.settingsStateViewState === "Node" || middlePanel.settingsView.settingsStateViewState === "Log") { if (middlePanel.settingsView.settingsStateViewState === "Node") {
middlePanel.settingsView.settingsStateViewState = "Wallet" middlePanel.settingsView.settingsStateViewState = "Wallet"
} }
} }
@@ -2109,6 +2160,11 @@ ApplicationWindow {
blackColor: "black" blackColor: "black"
whiteColor: "white" whiteColor: "white"
} }
MouseArea {
anchors.fill: parent
hoverEnabled: true
}
} }
// borders on white theme + linux // borders on white theme + linux
@@ -2176,8 +2232,12 @@ ApplicationWindow {
} }
} }
// @TODO: QML type 'Drawer' has issues with buildbot; debug after Qt 5.9 migration MoneroComponents.LanguageSidebar {
// MoneroComponents.LanguageSidebar { id: languageSidebar
// id: languageSidebar dragMargin: 0
// } }
WalletManager {
id: walletManager
}
} }

2
monero

Submodule monero updated: 581994b61c...7bd1ed03dd

View File

@@ -43,7 +43,9 @@ INCLUDEPATH += $$WALLET_ROOT/include \
$$PWD/src/libwalletqt \ $$PWD/src/libwalletqt \
$$PWD/src/QR-Code-generator \ $$PWD/src/QR-Code-generator \
$$PWD/src \ $$PWD/src \
$$WALLET_ROOT/src $$WALLET_ROOT/src \
$$WALLET_ROOT/external/easylogging++ \
$$WALLET_ROOT/contrib/epee/include
HEADERS += \ HEADERS += \
src/main/filter.h \ src/main/filter.h \
@@ -51,6 +53,7 @@ HEADERS += \
src/main/oscursor.h \ src/main/oscursor.h \
src/libwalletqt/WalletManager.h \ src/libwalletqt/WalletManager.h \
src/libwalletqt/Wallet.h \ src/libwalletqt/Wallet.h \
src/libwalletqt/PassphraseHelper.h \
src/libwalletqt/PendingTransaction.h \ src/libwalletqt/PendingTransaction.h \
src/libwalletqt/TransactionHistory.h \ src/libwalletqt/TransactionHistory.h \
src/libwalletqt/TransactionInfo.h \ src/libwalletqt/TransactionInfo.h \
@@ -74,11 +77,12 @@ HEADERS += \
src/libwalletqt/UnsignedTransaction.h \ src/libwalletqt/UnsignedTransaction.h \
src/main/Logger.h \ src/main/Logger.h \
src/main/MainApp.h \ src/main/MainApp.h \
src/qt/downloader.h \
src/qt/FutureScheduler.h \ src/qt/FutureScheduler.h \
src/qt/ipc.h \ src/qt/ipc.h \
src/qt/KeysFiles.h \ src/qt/KeysFiles.h \
src/qt/network.h \
src/qt/utils.h \ src/qt/utils.h \
src/qt/prices.h \
src/qt/macoshelper.h \ src/qt/macoshelper.h \
src/qt/MoneroSettings.h \ src/qt/MoneroSettings.h \
src/qt/TailsOS.h src/qt/TailsOS.h
@@ -88,12 +92,15 @@ SOURCES += src/main/main.cpp \
src/main/clipboardAdapter.cpp \ src/main/clipboardAdapter.cpp \
src/main/oscursor.cpp \ src/main/oscursor.cpp \
src/libwalletqt/WalletManager.cpp \ src/libwalletqt/WalletManager.cpp \
src/libwalletqt/WalletListenerImpl.cpp \
src/libwalletqt/Wallet.cpp \ src/libwalletqt/Wallet.cpp \
src/libwalletqt/PassphraseHelper.cpp \
src/libwalletqt/PendingTransaction.cpp \ src/libwalletqt/PendingTransaction.cpp \
src/libwalletqt/TransactionHistory.cpp \ src/libwalletqt/TransactionHistory.cpp \
src/libwalletqt/TransactionInfo.cpp \ src/libwalletqt/TransactionInfo.cpp \
src/libwalletqt/QRCodeImageProvider.cpp \ src/libwalletqt/QRCodeImageProvider.cpp \
src/main/oshelper.cpp \ src/main/oshelper.cpp \
src/openpgp/openpgp.cpp \
src/TranslationManager.cpp \ src/TranslationManager.cpp \
src/model/TransactionHistoryModel.cpp \ src/model/TransactionHistoryModel.cpp \
src/model/TransactionHistorySortFilterModel.cpp \ src/model/TransactionHistorySortFilterModel.cpp \
@@ -110,11 +117,13 @@ SOURCES += src/main/main.cpp \
src/libwalletqt/UnsignedTransaction.cpp \ src/libwalletqt/UnsignedTransaction.cpp \
src/main/Logger.cpp \ src/main/Logger.cpp \
src/main/MainApp.cpp \ src/main/MainApp.cpp \
src/qt/downloader.cpp \
src/qt/FutureScheduler.cpp \ src/qt/FutureScheduler.cpp \
src/qt/ipc.cpp \ src/qt/ipc.cpp \
src/qt/KeysFiles.cpp \ src/qt/KeysFiles.cpp \
src/qt/network.cpp \
src/qt/updater.cpp \
src/qt/utils.cpp \ src/qt/utils.cpp \
src/qt/prices.cpp \
src/qt/MoneroSettings.cpp \ src/qt/MoneroSettings.cpp \
src/qt/TailsOS.cpp src/qt/TailsOS.cpp
@@ -155,6 +164,8 @@ ios:arm64 {
} }
LIBS_COMMON = \ LIBS_COMMON = \
-lgcrypt \
-lgpg-error \
-lwallet_merged \ -lwallet_merged \
-llmdb \ -llmdb \
-lepee \ -lepee \
@@ -176,8 +187,10 @@ android {
QMAKE_CXXFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -Wformat -Wformat-security QMAKE_CXXFLAGS += -Werror -Wformat -Wformat-security
QMAKE_CFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -Wformat -Wformat-security QMAKE_CFLAGS += -Werror -Wformat -Wformat-security
QMAKE_CXXFLAGS_RELEASE += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -O2
QMAKE_CFLAGS_RELEASE += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -O2
ios { ios {
message("Host is IOS") message("Host is IOS")
@@ -221,6 +234,14 @@ CONFIG(WITH_SCANNER) {
LIBS += -lzbarjni -liconv LIBS += -lzbarjni -liconv
} else { } else {
LIBS += -lzbar LIBS += -lzbar
macx {
ZBAR_DIR = $$system(brew --prefix zbar, lines, EXIT_CODE)
equals(EXIT_CODE, 0) {
INCLUDEPATH += $$ZBAR_DIR/include
} else {
INCLUDEPATH += /usr/local/include
}
}
} }
} else { } else {
message("Skipping camera scanner because of Incompatible Qt Version !") message("Skipping camera scanner because of Incompatible Qt Version !")
@@ -299,7 +320,8 @@ win32 {
-lssl \ -lssl \
-lsodium \ -lsodium \
-lcrypto \ -lcrypto \
-lws2_32 -lws2_32 \
-lole32
!contains(QMAKE_TARGET.arch, x86_64) { !contains(QMAKE_TARGET.arch, x86_64) {
message("Target is 32bit") message("Target is 32bit")
@@ -371,18 +393,49 @@ macx {
# LIBS+= -Wl,-Bstatic # LIBS+= -Wl,-Bstatic
# } # }
OPENSSL_LIBRARY_DIRS = $$system(brew --prefix openssl, lines, EXIT_CODE) OPENSSL_DIR = $$system(brew --prefix openssl, lines, EXIT_CODE)
!equals(EXIT_CODE, 0) {
OPENSSL_DIR = /usr/local/ssl
}
OPENSSL_LIBRARY_DIR = $$OPENSSL_DIR/lib
INCLUDEPATH += $$OPENSSL_DIR/include
BOOST_DIR = $$system(brew --prefix boost, lines, EXIT_CODE)
equals(EXIT_CODE, 0) { equals(EXIT_CODE, 0) {
OPENSSL_LIBRARY_DIRS = $$OPENSSL_LIBRARY_DIRS/lib INCLUDEPATH += $$BOOST_DIR/include
} else { } else {
OPENSSL_LIBRARY_DIRS = /usr/local/ssl/lib INCLUDEPATH += /usr/local/include
}
GCRYPT_DIR = $$system(brew --prefix libgcrypt, lines, EXIT_CODE)
equals(EXIT_CODE, 0) {
INCLUDEPATH += $$GCRYPT_DIR/include
} else {
INCLUDEPATH += /usr/local/include
}
GPGP_ERROR_DIR = $$system(brew --prefix libgpg-error, lines, EXIT_CODE)
equals(EXIT_CODE, 0) {
INCLUDEPATH += $$GPGP_ERROR_DIR/include
} else {
INCLUDEPATH += /usr/local/include
}
SODIUM_DIR = $$system(brew --prefix libsodium, lines, EXIT_CODE)
equals(EXIT_CODE, 0) {
INCLUDEPATH += $$SODIUM_DIR/include
} else {
INCLUDEPATH += /usr/local/include
} }
QT += macextras QT += macextras
OBJECTIVE_SOURCES += src/qt/macoshelper.mm OBJECTIVE_SOURCES += src/qt/macoshelper.mm
LIBS+= -Wl,-dead_strip
LIBS+= -Wl,-dead_strip_dylibs
LIBS+= -Wl,-bind_at_load
LIBS+= \ LIBS+= \
-L/usr/local/lib \ -L/usr/local/lib \
-L$$OPENSSL_LIBRARY_DIRS \ -L$$OPENSSL_LIBRARY_DIR \
-L/usr/local/opt/boost/lib \ -L/usr/local/opt/boost/lib \
-lboost_serialization \ -lboost_serialization \
-lboost_thread-mt \ -lboost_thread-mt \
@@ -514,6 +567,7 @@ DISTFILES += \
VERSION = $$cat('version.js', lines) VERSION = $$cat('version.js', lines)
VERSION = $$find(VERSION, 'GUI_VERSION') VERSION = $$find(VERSION, 'GUI_VERSION')
VERSION_LONG = $$replace(VERSION, '.*\"(.*)\"', '\1')
VERSION = $$replace(VERSION, '.*(\d+\.\d+\.\d+\.\d+).*', '\1') VERSION = $$replace(VERSION, '.*(\d+\.\d+\.\d+\.\d+).*', '\1')
# windows application icon # windows application icon
@@ -521,4 +575,7 @@ RC_ICONS = images/appicon.ico
# mac Info.plist & application icon # mac Info.plist & application icon
QMAKE_INFO_PLIST = $$PWD/share/Info.plist QMAKE_INFO_PLIST = $$PWD/share/Info.plist
macx {
QMAKE_POST_LINK += sed -i "''" -e "s/@VERSION@/$$VERSION/g" -e "s/@VERSION_LONG@/$$VERSION_LONG/g" "$$sprintf("%1/%2/%3.app", $$OUT_PWD, $$DESTDIR, $$TARGET)/Contents/Info.plist";
}
ICON = $$PWD/images/appicon.icns ICON = $$PWD/images/appicon.icns

View File

@@ -55,6 +55,7 @@ Rectangle {
inputDialog.labelText = qsTr("Set the label of the selected account:") + translationManager.emptyString; inputDialog.labelText = qsTr("Set the label of the selected account:") + translationManager.emptyString;
inputDialog.onAcceptedCallback = function() { inputDialog.onAcceptedCallback = function() {
appWindow.currentWallet.setSubaddressLabel(_index, 0, inputDialog.inputText) appWindow.currentWallet.setSubaddressLabel(_index, 0, inputDialog.inputText)
appWindow.currentWallet.subaddressAccount.refresh()
} }
inputDialog.onRejectedCallback = null; inputDialog.onRejectedCallback = null;
inputDialog.open(appWindow.currentWallet.getSubaddressLabel(_index, 0)) inputDialog.open(appWindow.currentWallet.getSubaddressLabel(_index, 0))
@@ -185,7 +186,7 @@ Rectangle {
delegate: Rectangle { delegate: Rectangle {
id: tableItem2 id: tableItem2
height: subaddressAccountListRow.subaddressAccountListItemHeight height: subaddressAccountListRow.subaddressAccountListItemHeight
width: parent.width width: parent ? parent.width : undefined
Layout.fillWidth: true Layout.fillWidth: true
color: "transparent" color: "transparent"

View File

@@ -79,13 +79,6 @@ Rectangle {
topPadding: 0 topPadding: 0
text: qsTr("Save your most used addresses here") + translationManager.emptyString text: qsTr("Save your most used addresses here") + translationManager.emptyString
width: parent.width width: parent.width
// @TODO: Legacy. Remove after Qt 5.8.
// https://stackoverflow.com/questions/41990013
MouseArea {
anchors.fill: parent
enabled: false
}
} }
Text { Text {
@@ -99,13 +92,6 @@ Rectangle {
topPadding: 0 topPadding: 0
text: qsTr("This makes it easier to send or receive Monero and reduces errors when typing in addresses manually.") + translationManager.emptyString text: qsTr("This makes it easier to send or receive Monero and reduces errors when typing in addresses manually.") + translationManager.emptyString
width: parent.width width: parent.width
// @TODO: Legacy. Remove after Qt 5.8.
// https://stackoverflow.com/questions/41990013
MouseArea {
anchors.fill: parent
enabled: false
}
} }
MoneroComponents.StandardButton { MoneroComponents.StandardButton {
@@ -306,8 +292,8 @@ Rectangle {
MoneroComponents.LineEditMulti { MoneroComponents.LineEditMulti {
id: addressLine id: addressLine
Layout.topMargin: 20 Layout.topMargin: 20
labelText: qsTr("<style type='text/css'>a {text-decoration: none; color: #858585; font-size: 14px;}</style>\ labelText: "<style type='text/css'>a {text-decoration: none; color: #858585; font-size: 14px;}</style> %1"
Address") + translationManager.emptyString .arg(qsTr("Address")) + translationManager.emptyString
placeholderText: { placeholderText: {
if(persistentSettings.nettype == NetworkType.MAINNET){ if(persistentSettings.nettype == NetworkType.MAINNET){
return "4.. / 8.. / OpenAlias"; return "4.. / 8.. / OpenAlias";
@@ -325,8 +311,6 @@ Rectangle {
if (!parsed.error) { if (!parsed.error) {
addressLine.text = parsed.address; addressLine.text = parsed.address;
descriptionLine.text = parsed.tx_description; descriptionLine.text = parsed.tx_description;
} else {
addressLine.text = clipboardText;
} }
} }
@@ -384,8 +368,8 @@ Rectangle {
MoneroComponents.LineEditMulti { MoneroComponents.LineEditMulti {
id: descriptionLine id: descriptionLine
Layout.topMargin: 20 Layout.topMargin: 20
labelText: qsTr("<style type='text/css'>a {text-decoration: none; color: #858585; font-size: 14px;}</style>\ labelText: "<style type='text/css'>a {text-decoration: none; color: #858585; font-size: 14px;}</style> %1"
Description") + translationManager.emptyString .arg(qsTr("Description")) + translationManager.emptyString
placeholderText: qsTr("Add a name...") + translationManager.emptyString placeholderText: qsTr("Add a name...") + translationManager.emptyString
} }
RowLayout { RowLayout {

View File

@@ -156,7 +156,7 @@ Rectangle {
input.bottomPadding: 6 input.bottomPadding: 6
fontSize: 16 fontSize: 16
labelFontSize: 14 labelFontSize: 14
placeholderText: qsTr("Search...") + translationManager.emptyString placeholderText: qsTr("Search by Transaction ID, Address, Description, Amount or Blockheight") + translationManager.emptyString
placeholderFontSize: 16 placeholderFontSize: 16
inputHeight: 34 inputHeight: 34
onTextUpdated: { onTextUpdated: {
@@ -569,8 +569,8 @@ Rectangle {
delegate: Rectangle { delegate: Rectangle {
id: delegate id: delegate
property bool collapsed: root.txDataCollapsed.indexOf(hash) >= 0 ? true : false property bool collapsed: root.txDataCollapsed.indexOf(hash) >= 0 ? true : false
anchors.left: parent.left anchors.left: parent ? parent.left : undefined
anchors.right: parent.right anchors.right: parent ? parent.right : undefined
height: { height: {
if(!collapsed) return 60; if(!collapsed) return 60;
if(isout && delegate.address !== "") return 320; if(isout && delegate.address !== "") return 320;
@@ -633,7 +633,17 @@ Rectangle {
MoneroComponents.TextPlain { MoneroComponents.TextPlain {
font.family: MoneroComponents.Style.fontRegular.name font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 15 font.pixelSize: 15
text: isout ? qsTr("Sent") : qsTr("Received") + translationManager.emptyString text: {
if (!isout) {
return qsTr("Received") + translationManager.emptyString;
}
const addressBookName = currentWallet ? currentWallet.addressBook.getDescription(address) : null;
if (!addressBookName)
{
return qsTr("Sent") + translationManager.emptyString;
}
return addressBookName;
}
color: MoneroComponents.Style.historyHeaderTextColor color: MoneroComponents.Style.historyHeaderTextColor
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
themeTransitionBlackColor: MoneroComponents.Style._b_historyHeaderTextColor themeTransitionBlackColor: MoneroComponents.Style._b_historyHeaderTextColor
@@ -1382,9 +1392,9 @@ Rectangle {
if(root.sortSearchString.length >= 1){ if(root.sortSearchString.length >= 1){
if(item.amount && item.amount.toString().startsWith(root.sortSearchString)){ if(item.amount && item.amount.toString().startsWith(root.sortSearchString)){
txs.push(item); txs.push(item);
} else if(item.address !== "" && item.address.startsWith(root.sortSearchString)){ } else if(item.address !== "" && item.address.toLowerCase().startsWith(root.sortSearchString.toLowerCase())){
txs.push(item); txs.push(item);
} else if(item.blockheight.toString().startsWith(root.sortSearchString)) { } else if(typeof item.blockheight !== "undefined" && item.blockheight.toString().startsWith(root.sortSearchString)) {
txs.push(item); txs.push(item);
} else if(item.tx_note.toLowerCase().indexOf(root.sortSearchString.toLowerCase()) !== -1) { } else if(item.tx_note.toLowerCase().indexOf(root.sortSearchString.toLowerCase()) !== -1) {
txs.push(item); txs.push(item);
@@ -1501,7 +1511,7 @@ Rectangle {
"i": i, "i": i,
"isout": isout, "isout": isout,
"amount": Number(amount), "amount": Number(amount),
"displayAmount": displayAmount + " XMR", "displayAmount": Utils.removeTrailingZeros(displayAmount.toFixed(12)) + " XMR",
"hash": hash, "hash": hash,
"paymentId": paymentId, "paymentId": paymentId,
"address": address, "address": address,

View File

@@ -131,7 +131,7 @@ Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
fontSize: 22 fontSize: 22
Layout.topMargin: 10 Layout.topMargin: 10
text: qsTr("Keys") + translationManager.emptyString text: qsTr("Primary address & Keys") + translationManager.emptyString
} }
Rectangle { Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
@@ -140,8 +140,18 @@ Rectangle {
opacity: MoneroComponents.Style.dividerOpacity opacity: MoneroComponents.Style.dividerOpacity
Layout.bottomMargin: 10 Layout.bottomMargin: 10
} }
MoneroComponents.LineEditMulti {
Layout.fillWidth: true
id: primaryAddress
readOnly: true
copyButton: true
wrapMode: Text.Wrap
labelText: qsTr("Primary address") + translationManager.emptyString
fontSize: 16
}
MoneroComponents.LineEdit { MoneroComponents.LineEdit {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 25
id: secretViewKey id: secretViewKey
readOnly: true readOnly: true
copyButton: true copyButton: true
@@ -261,6 +271,7 @@ Rectangle {
function onPageCompleted() { function onPageCompleted() {
console.log("keys page loaded"); console.log("keys page loaded");
primaryAddress.text = currentWallet.address(0, 0)
walletCreationHeight.text = currentWallet.walletCreationHeight walletCreationHeight.text = currentWallet.walletCreationHeight
secretViewKey.text = currentWallet.secretViewKey secretViewKey.text = currentWallet.secretViewKey
publicViewKey.text = currentWallet.publicViewKey publicViewKey.text = currentWallet.publicViewKey
@@ -281,7 +292,7 @@ Rectangle {
secretSpendKey.text = qsTr("(View Only Wallet - No secret spend key available)") + translationManager.emptyString secretSpendKey.text = qsTr("(View Only Wallet - No secret spend key available)") + translationManager.emptyString
} }
// hardware device wallet // hardware device wallet
if(currentWallet.seed === "") { if(appWindow.currentWallet.isHwBacked() === true) {
showFullQr.visible = false showFullQr.visible = false
viewOnlyQRCode.visible = true viewOnlyQRCode.visible = true
showViewOnlyQr.visible = false showViewOnlyQr.visible = false

View File

@@ -251,7 +251,19 @@ Rectangle {
function updateStatusText() { function updateStatusText() {
if (appWindow.isMining) { if (appWindow.isMining) {
statusText.text = qsTr("Mining at %1 H/s").arg(walletManager.miningHashRate()) + translationManager.emptyString; var userHashRate = walletManager.miningHashRate();
if (userHashRate === 0) {
statusText.text = qsTr("Mining temporarily suspended.") + translationManager.emptyString;
}
else {
var blockTime = 120;
var blocksPerDay = 86400 / blockTime;
var globalHashRate = walletManager.networkDifficulty() / blockTime;
var probabilityFindNextBlock = userHashRate / globalHashRate;
var probabilityFindBlockDay = 1 - Math.pow(1 - probabilityFindNextBlock, blocksPerDay);
var chanceFindBlockDay = Math.round(1 / probabilityFindBlockDay);
statusText.text = qsTr("Mining at %1 H/s. It gives you a 1 in %2 daily chance of finding a block.").arg(userHashRate).arg(chanceFindBlockDay) + translationManager.emptyString;
}
} }
else { else {
statusText.text = qsTr("Not mining") + translationManager.emptyString; statusText.text = qsTr("Not mining") + translationManager.emptyString;

View File

@@ -105,7 +105,7 @@ Rectangle {
delegate: Rectangle { delegate: Rectangle {
id: tableItem2 id: tableItem2
height: subaddressListRow.subaddressListItemHeight height: subaddressListRow.subaddressListItemHeight
width: parent.width width: parent ? parent.width : undefined
Layout.fillWidth: true Layout.fillWidth: true
color: "transparent" color: "transparent"
@@ -290,34 +290,39 @@ Rectangle {
} }
} }
RowLayout { MoneroComponents.StandardButton {
spacing: parent.spacing Layout.preferredWidth: 220
small: true
text: FontAwesome.save + " %1".arg(qsTr("Save as image")) + translationManager.emptyString
label.font.family: FontAwesome.fontFamily
fontSize: 13
onClicked: qrFileDialog.open()
}
MoneroComponents.StandardButton { MoneroComponents.StandardButton {
rightIcon: "qrc:///images/download-white.png" Layout.preferredWidth: 220
onClicked: qrFileDialog.open() small: true
text: FontAwesome.clipboard + " %1".arg(qsTr("Copy to clipboard")) + translationManager.emptyString
label.font.family: FontAwesome.fontFamily
fontSize: 13
onClicked: {
clipboard.setText(TxUtils.makeQRCodeString(appWindow.current_address));
appWindow.showStatusMessage(qsTr("Copied to clipboard") + translationManager.emptyString, 3);
} }
}
MoneroComponents.StandardButton { MoneroComponents.StandardButton {
rightIcon: "qrc:///images/external-link-white.png" Layout.preferredWidth: 220
onClicked: { small: true
clipboard.setText(TxUtils.makeQRCodeString(appWindow.current_address)); text: FontAwesome.eye + " %1".arg(qsTr("Show on device")) + translationManager.emptyString
appWindow.showStatusMessage(qsTr("Copied to clipboard") + translationManager.emptyString, 3); label.font.family: FontAwesome.fontFamily
} fontSize: 13
} visible: appWindow.currentWallet ? appWindow.currentWallet.isHwBacked() : false
onClicked: {
MoneroComponents.StandardButton { appWindow.currentWallet.deviceShowAddressAsync(
text: FontAwesome.eye appWindow.currentWallet.currentSubaddressAccount,
label.font.family: FontAwesome.fontFamily appWindow.current_subaddress_table_index,
fontSize: 24 '');
width: 36
visible: appWindow.currentWallet ? appWindow.currentWallet.isHwBacked() : false
onClicked: {
appWindow.currentWallet.deviceShowAddressAsync(
appWindow.currentWallet.currentSubaddressAccount,
appWindow.current_subaddress_table_index,
'');
}
} }
} }
} }

View File

@@ -187,7 +187,6 @@ Rectangle {
readOnly: false readOnly: false
onTextChanged: signSignatureLine.text = '' onTextChanged: signSignatureLine.text = ''
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere
pasteButton: true
} }
} }
@@ -302,7 +301,6 @@ Rectangle {
readOnly: false readOnly: false
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere
text: '' text: ''
pasteButton: true
} }
RowLayout { RowLayout {
@@ -344,7 +342,6 @@ Rectangle {
placeholderText: qsTr("Enter the Monero Address (example: 44AFFq5kSiGBoZ...)") + translationManager.emptyString placeholderText: qsTr("Enter the Monero Address (example: 44AFFq5kSiGBoZ...)") + translationManager.emptyString
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere
text: '' text: ''
pasteButton: true
} }
MoneroComponents.LineEditMulti { MoneroComponents.LineEditMulti {
@@ -354,7 +351,6 @@ Rectangle {
placeholderFontSize: 16 placeholderFontSize: 16
placeholderText: qsTr("Enter the signature to verify") + translationManager.emptyString placeholderText: qsTr("Enter the signature to verify") + translationManager.emptyString
Layout.fillWidth: true Layout.fillWidth: true
pasteButton: true
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere
text: '' text: ''
} }

View File

@@ -27,6 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.9 import QtQuick 2.9
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import moneroComponents.Clipboard 1.0 import moneroComponents.Clipboard 1.0
@@ -38,6 +39,7 @@ import "../components"
import "../components" as MoneroComponents import "../components" as MoneroComponents
import "." 1.0 import "." 1.0
import "../js/TxUtils.js" as TxUtils import "../js/TxUtils.js" as TxUtils
import "../js/Utils.js" as Utils
Rectangle { Rectangle {
@@ -51,8 +53,34 @@ Rectangle {
property alias transferHeight2: advancedLayout.height property alias transferHeight2: advancedLayout.height
property int mixin: 10 // (ring size 11) property int mixin: 10 // (ring size 11)
property string warningContent: "" property string warningContent: ""
property string sendButtonWarning: "" property string sendButtonWarning: {
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 // Currently opened wallet is not view-only
if (appWindow.viewOnly) {
return qsTr("Wallet is view-only and sends are only possible by using offline transaction signing. " +
"Unless key images are imported, the balance reflects only incoming but not outgoing transactions.") + translationManager.emptyString;
}
// There are sufficient unlocked funds available
if (walletManager.amountFromString(amountLine.text) > appWindow.getUnlockedBalance()) {
return qsTr("Amount is more than unlocked balance.") + translationManager.emptyString;
}
if (addressLine.text)
{
// Address is valid
if (!TxUtils.checkAddress(addressLine.text, appWindow.persistentSettings.nettype)) {
return qsTr("Address is invalid.") + translationManager.emptyString;
}
// Amount is nonzero
if (!amountLine.text || parseFloat(amountLine.text) <= 0) {
return qsTr("Enter an amount.") + translationManager.emptyString;
}
}
return "";
}
property string startLinkText: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 14px;}</style><a href='#'>(%1)</a>".arg(qsTr("Start daemon")) + translationManager.emptyString
property bool warningLongPidDescription: descriptionLine.text.match(/^[0-9a-f]{64}$/i) property bool warningLongPidDescription: descriptionLine.text.match(/^[0-9a-f]{64}$/i)
Clipboard { id: clipboard } Clipboard { id: clipboard }
@@ -88,10 +116,8 @@ Rectangle {
addressLine.text = "" addressLine.text = ""
setPaymentId(""); setPaymentId("");
amountLine.text = "" amountLine.text = ""
root.sendButtonWarning = ""
setDescription(""); setDescription("");
priorityDropdown.currentIndex = 0 priorityDropdown.currentIndex = 0
updatePriorityDropdown()
} }
// Information dialog // Information dialog
@@ -137,96 +163,6 @@ Rectangle {
} }
} }
GridLayout {
columns: appWindow.walletMode < 2 ? 1 : 2
Layout.fillWidth: true
columnSpacing: 32
ColumnLayout {
Layout.fillWidth: true
Layout.minimumWidth: 200
// Amount input
LineEdit {
id: amountLine
Layout.fillWidth: true
inlineIcon: true
labelText: qsTr("<style type='text/css'>a {text-decoration: none; color: #858585; font-size: 14px;}</style>\
Amount <font size='2'> ( </font> <a href='#'>Change account</a><font size='2'> )</font>")
+ translationManager.emptyString
copyButton: !isNaN(amountLine.text) && persistentSettings.fiatPriceEnabled
copyButtonText: fiatApiCurrencySymbol() + " ~" + fiatApiConvertToFiat(amountLine.text)
copyButtonEnabled: false
onLabelLinkActivated: {
middlePanel.accountView.selectAndSend = true;
appWindow.showPageRequest("Account")
}
placeholderText: "0.00"
width: 100
fontBold: true
inlineButtonText: qsTr("All") + translationManager.emptyString
inlineButton.onClicked: amountLine.text = "(all)"
onTextChanged: {
const match = amountLine.text.match(/^0+(\d.*)/);
if (match) {
const cursorPosition = amountLine.cursorPosition;
amountLine.text = match[1];
amountLine.cursorPosition = Math.max(cursorPosition, 1) - 1;
} else if(amountLine.text.indexOf('.') === 0){
amountLine.text = '0' + amountLine.text;
if (amountLine.text.length > 2) {
amountLine.cursorPosition = 1;
}
}
amountLine.error = walletManager.amountFromString(amountLine.text) > appWindow.getUnlockedBalance()
}
validator: RegExpValidator {
regExp: /^(\d{1,8})?([\.]\d{1,12})?$/
}
}
}
ColumnLayout {
visible: appWindow.walletMode >= 2
Layout.fillWidth: true
Label {
id: transactionPriority
Layout.topMargin: 12
text: qsTr("Transaction priority") + translationManager.emptyString
fontBold: false
fontSize: 16
}
// Note: workaround for translations in listElements
// ListElement: cannot use script for property value, so
// code like this wont work:
// ListElement { column1: qsTr("LOW") + translationManager.emptyString ; column2: ""; priority: PendingTransaction.Priority_Low }
// For translations to work, the strings need to be listed in
// the file components/StandardDropdown.qml too.
// Priorites after v5
ListModel {
id: priorityModelV5
ListElement { column1: qsTr("Automatic") ; column2: ""; priority: 0}
ListElement { column1: qsTr("Slow (x0.2 fee)") ; column2: ""; priority: 1}
ListElement { column1: qsTr("Normal (x1 fee)") ; column2: ""; priority: 2 }
ListElement { column1: qsTr("Fast (x5 fee)") ; column2: ""; priority: 3 }
ListElement { column1: qsTr("Fastest (x200 fee)") ; column2: ""; priority: 4 }
}
StandardDropdown {
Layout.fillWidth: true
id: priorityDropdown
Layout.topMargin: 5
currentIndex: 0
}
}
// Make sure dropdown is on top
z: parent.z + 1
}
// recipient address input // recipient address input
RowLayout { RowLayout {
id: addressLineRow id: addressLineRow
@@ -235,10 +171,9 @@ Rectangle {
LineEditMulti { LineEditMulti {
id: addressLine id: addressLine
spacing: 0 spacing: 0
inputPaddingRight: inlineButtonVisible && inlineButton2Visible ? 100 : 60
fontBold: true fontBold: true
labelText: qsTr("<style type='text/css'>a {text-decoration: none; color: #858585; font-size: 14px;}</style>\ labelText: qsTr("Address") + translationManager.emptyString
Address <font size='2'> ( </font> <a href='#'>Address book</a><font size='2'> )</font>")
+ translationManager.emptyString
labelButtonText: qsTr("Resolve") + translationManager.emptyString labelButtonText: qsTr("Resolve") + translationManager.emptyString
placeholderText: { placeholderText: {
if(persistentSettings.nettype == NetworkType.MAINNET){ if(persistentSettings.nettype == NetworkType.MAINNET){
@@ -251,11 +186,6 @@ Rectangle {
} }
wrapMode: Text.WrapAnywhere wrapMode: Text.WrapAnywhere
addressValidation: true addressValidation: true
onInputLabelLinkActivated: {
middlePanel.addressBookView.selectAndSend = true;
appWindow.showPageRequest("AddressBook");
}
pasteButton: true
onTextChanged: { onTextChanged: {
const parsed = walletManager.parse_uri_to_object(text); const parsed = walletManager.parse_uri_to_object(text);
if (!parsed.error) { if (!parsed.error) {
@@ -265,16 +195,27 @@ Rectangle {
setDescription(parsed.tx_description); setDescription(parsed.tx_description);
} }
} }
inlineButton.text: FontAwesome.qrcode inlineButton.text: FontAwesome.addressBook
inlineButton.buttonHeight: 30
inlineButton.fontPixelSize: 22 inlineButton.fontPixelSize: 22
inlineButton.fontFamily: FontAwesome.fontFamily inlineButton.fontFamily: FontAwesome.fontFamily
inlineButton.textColor: MoneroComponents.Style.defaultFontColor inlineButton.textColor: MoneroComponents.Style.defaultFontColor
inlineButton.buttonColor: MoneroComponents.Style.orange
inlineButton.onClicked: { inlineButton.onClicked: {
cameraUi.state = "Capture" middlePanel.addressBookView.selectAndSend = true;
cameraUi.qrcode_decoded.connect(updateFromQrCode) appWindow.showPageRequest("AddressBook");
} }
inlineButtonVisible : appWindow.qrScannerEnabled && !addressLine.text inlineButtonVisible: true
inlineButton2.text: FontAwesome.qrcode
inlineButton2.buttonHeight: 30
inlineButton2.fontPixelSize: 22
inlineButton2.fontFamily: FontAwesome.fontFamily
inlineButton2.textColor: MoneroComponents.Style.defaultFontColor
inlineButton2.onClicked: {
cameraUi.state = "Capture"
cameraUi.qrcode_decoded.connect(updateFromQrCode)
}
inlineButton2Visible: appWindow.qrScannerEnabled
} }
} }
@@ -324,6 +265,143 @@ Rectangle {
} }
} }
GridLayout {
columns: appWindow.walletMode < 2 ? 1 : 2
Layout.fillWidth: true
columnSpacing: 32
ColumnLayout {
Layout.fillWidth: true
Layout.minimumWidth: 200
// Amount input
LineEdit {
id: amountLine
Layout.fillWidth: true
inlineIcon: true
labelText: "<style type='text/css'>a {text-decoration: none; color: #858585; font-size: 14px;}</style>\
%1 <a href='#'>(%2)</a>".arg(qsTr("Amount")).arg(qsTr("Change account"))
+ translationManager.emptyString
copyButton: !isNaN(amountLine.text) && persistentSettings.fiatPriceEnabled
copyButtonText: "~%1 %2".arg(fiatApiConvertToFiat(amountLine.text)).arg(fiatApiCurrencySymbol())
copyButtonEnabled: false
onLabelLinkActivated: {
middlePanel.accountView.selectAndSend = true;
appWindow.showPageRequest("Account")
}
placeholderText: "0.00"
width: 100
fontBold: true
inlineButtonText: qsTr("All") + translationManager.emptyString
inlineButton.onClicked: amountLine.text = "(all)"
onTextChanged: {
amountLine.text = amountLine.text.replace(",", ".");
const match = amountLine.text.match(/^0+(\d.*)/);
if (match) {
const cursorPosition = amountLine.cursorPosition;
amountLine.text = match[1];
amountLine.cursorPosition = Math.max(cursorPosition, 1) - 1;
} else if(amountLine.text.indexOf('.') === 0){
amountLine.text = '0' + amountLine.text;
if (amountLine.text.length > 2) {
amountLine.cursorPosition = 1;
}
}
amountLine.error = walletManager.amountFromString(amountLine.text) > appWindow.getUnlockedBalance()
}
validator: RegExpValidator {
regExp: /^(\d{1,8})?([\.,]\d{1,12})?$/
}
}
MoneroComponents.TextPlain {
id: feeLabel
Layout.alignment: Qt.AlignRight
Layout.topMargin: 12
font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 14
color: MoneroComponents.Style.defaultFontColor
property bool estimating: false
property var estimatedFee: null
property string estimatedFeeFiat: {
if (!persistentSettings.fiatPriceEnabled || estimatedFee == null) {
return "";
}
const fiatFee = fiatApiConvertToFiat(estimatedFee);
return " (%1 %3)".arg(fiatFee < 0.01 ? "<0.01" : "~" + fiatFee).arg(fiatApiCurrencySymbol());
}
property var fee: {
estimatedFee = null;
estimating = sendButton.enabled;
if (!sendButton.enabled || !currentWallet) {
return;
}
currentWallet.estimateTransactionFeeAsync(
addressLine.text,
walletManager.amountFromString(amountLine.text),
priorityModelV5.get(priorityDropdown.currentIndex).priority,
function (amount) {
estimatedFee = Utils.removeTrailingZeros(amount);
estimating = false;
});
}
text: {
if (!sendButton.enabled || estimatedFee == null) {
return ""
}
return "%1: ~%2 XMR".arg(qsTr("Fee")).arg(estimatedFee) +
estimatedFeeFiat +
translationManager.emptyString;
}
BusyIndicator {
anchors.right: parent.right
running: feeLabel.estimating
height: parent.height
}
}
}
ColumnLayout {
visible: appWindow.walletMode >= 2
Layout.alignment: Qt.AlignTop
Label {
id: transactionPriority
Layout.topMargin: 0
text: qsTr("Transaction priority") + translationManager.emptyString
fontBold: false
fontSize: 16
}
// Note: workaround for translations in listElements
// ListElement: cannot use script for property value, so
// code like this wont work:
// ListElement { column1: qsTr("LOW") + translationManager.emptyString ; column2: ""; priority: PendingTransaction.Priority_Low }
// For translations to work, the strings need to be listed in
// the file components/StandardDropdown.qml too.
// Priorites after v5
ListModel {
id: priorityModelV5
ListElement { column1: qsTr("Automatic") ; column2: ""; priority: 0}
ListElement { column1: qsTr("Slow (x0.2 fee)") ; column2: ""; priority: 1}
ListElement { column1: qsTr("Normal (x1 fee)") ; column2: ""; priority: 2 }
ListElement { column1: qsTr("Fast (x5 fee)") ; column2: ""; priority: 3 }
ListElement { column1: qsTr("Fastest (x200 fee)") ; column2: ""; priority: 4 }
}
StandardDropdown {
Layout.preferredWidth: 200
id: priorityDropdown
Layout.topMargin: 5
currentIndex: 0
dataModel: priorityModelV5
}
}
}
MoneroComponents.WarningBox { MoneroComponents.WarningBox {
text: qsTr("Description field contents match long payment ID format. \ text: qsTr("Description field contents match long payment ID format. \
Please don't paste long payment ID into description field, your funds might be lost.") + translationManager.emptyString; Please don't paste long payment ID into description field, your funds might be lost.") + translationManager.emptyString;
@@ -414,9 +492,7 @@ Rectangle {
rightIconInactive: "qrc:///images/rightArrowInactive.png" rightIconInactive: "qrc:///images/rightArrowInactive.png"
Layout.topMargin: 4 Layout.topMargin: 4
text: qsTr("Send") + translationManager.emptyString text: qsTr("Send") + translationManager.emptyString
enabled: { enabled: !sendButtonWarningBox.visible && !warningContent && addressLine.text && !paymentIdWarningBox.visible
updateSendButton()
}
onClicked: { onClicked: {
console.log("Transfer: paymentClicked") console.log("Transfer: paymentClicked")
var priority = priorityModelV5.get(priorityDropdown.currentIndex).priority var priority = priorityModelV5.get(priorityDropdown.currentIndex).priority
@@ -439,10 +515,9 @@ Rectangle {
id: advancedLayout id: advancedLayout
anchors.top: pageRoot.bottom anchors.top: pageRoot.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 20 anchors.margins: 20
anchors.topMargin: 32 anchors.topMargin: 32
spacing: 26 spacing: 10
enabled: !viewOnly || pageRoot.enabled enabled: !viewOnly || pageRoot.enabled
RowLayout { RowLayout {
@@ -457,85 +532,88 @@ Rectangle {
} }
} }
GridLayout { AdvancedOptionsItem {
visible: persistentSettings.transferShowAdvanced && appWindow.walletMode >= 2 visible: persistentSettings.transferShowAdvanced && appWindow.walletMode >= 2
columns: 6 title: qsTr("Key images") + translationManager.emptyString
button1.text: qsTr("Export") + translationManager.emptyString
StandardButton { button1.enabled: !appWindow.viewOnly
id: sweepUnmixableButton button1.onClicked: {
text: qsTr("Sweep Unmixable") + translationManager.emptyString console.log("Transfer: export key images clicked")
enabled : pageRoot.enabled exportKeyImagesDialog.open();
small: true
onClicked: {
console.log("Transfer: sweepUnmixableClicked")
root.sweepUnmixableClicked()
}
} }
button2.text: qsTr("Import") + translationManager.emptyString
StandardButton { button2.enabled: appWindow.viewOnly && appWindow.isTrustedDaemon()
id: saveTxButton button2.onClicked: {
text: qsTr("Create tx file") + translationManager.emptyString console.log("Transfer: import key images clicked")
visible: appWindow.viewOnly importKeyImagesDialog.open();
enabled: pageRoot.checkInformation(amountLine.text, addressLine.text, appWindow.persistentSettings.nettype)
small: true
onClicked: {
console.log("Transfer: saveTx Clicked")
var priority = priorityModelV5.get(priorityDropdown.currentIndex).priority
console.log("priority: " + priority)
console.log("amount: " + amountLine.text)
addressLine.text = addressLine.text.trim()
setPaymentId(paymentIdLine.text.trim());
root.paymentClicked(addressLine.text, paymentIdLine.text, amountLine.text, root.mixin, priority, descriptionLine.text)
}
} }
helpTextLarge.text: qsTr("Required for view-only wallets to display the real balance") + translationManager.emptyString
helpTextSmall.text: {
var errorMessage = "";
if (appWindow.viewOnly && !appWindow.isTrustedDaemon()){
errorMessage = "<p class='orange'>" + qsTr("* To import, you must connect to a local node or a trusted remote node") + "</p>";
}
return "<style type='text/css'>p{line-height:20px; margin-top:0px; margin-bottom:0px; color:#ffffff;} p.orange{color:#ff9323;}</style>" +
"<p>" + qsTr("1. Using cold wallet, export the key images into a file") + "</p>" +
"<p>" + qsTr("2. Using view-only wallet, import the key images file") + "</p>" +
errorMessage + translationManager.emptyString
}
helpTextSmall.themeTransition: false
}
AdvancedOptionsItem {
visible: persistentSettings.transferShowAdvanced && appWindow.walletMode >= 2
title: qsTr("Offline transaction signing") + translationManager.emptyString
button1.text: qsTr("Create") + translationManager.emptyString
button1.enabled: appWindow.viewOnly && pageRoot.checkInformation(amountLine.text, addressLine.text, appWindow.persistentSettings.nettype)
button1.onClicked: {
console.log("Transfer: saveTx Clicked")
var priority = priorityModelV5.get(priorityDropdown.currentIndex).priority
console.log("priority: " + priority)
console.log("amount: " + amountLine.text)
addressLine.text = addressLine.text.trim()
setPaymentId(paymentIdLine.text.trim());
root.paymentClicked(addressLine.text, paymentIdLine.text, amountLine.text, root.mixin, priority, descriptionLine.text)
}
button2.text: qsTr("Sign (offline)") + translationManager.emptyString
button2.enabled: !appWindow.viewOnly
button2.onClicked: {
console.log("Transfer: sign tx clicked")
signTxDialog.open();
}
button3.text: qsTr("Submit") + translationManager.emptyString
button3.enabled: appWindow.viewOnly
button3.onClicked: {
console.log("Transfer: submit tx clicked")
submitTxDialog.open();
}
helpTextLarge.text: qsTr("Spend XMR from a cold (offline) wallet") + translationManager.emptyString
helpTextSmall.text: {
var errorMessage = "";
if (appWindow.viewOnly && !pageRoot.checkInformation(amountLine.text, addressLine.text, appWindow.persistentSettings.nettype)){
errorMessage = "<p class='orange'>" + qsTr("* To create a transaction file, please enter address and amount above") + "</p>";
}
return "<style type='text/css'>p{line-height:20px; margin-top:0px; margin-bottom:0px; color:#ffffff;} p.orange{color:#ff9323;}</style>" +
"<p>" + qsTr("1. Using view-only wallet, export the outputs into a file") + "</p>" +
"<p>" + qsTr("2. Using cold wallet, import the outputs file and export the key images") + "</p>" +
"<p>" + qsTr("3. Using view-only wallet, import the key images file and create a transaction file") + "</p>" +
errorMessage +
"<p>" + qsTr("4. Using cold wallet, sign your transaction file") + "</p>" +
"<p>" + qsTr("5. Using view-only wallet, submit your signed transaction") + "</p>" + translationManager.emptyString
}
helpTextSmall.themeTransition: false
}
StandardButton { AdvancedOptionsItem {
id: signTxButton visible: persistentSettings.transferShowAdvanced && appWindow.walletMode >= 2
text: qsTr("Sign tx file") + translationManager.emptyString title: qsTr("Unmixable outputs") + translationManager.emptyString
small: true button1.text: qsTr("Sweep") + translationManager.emptyString
visible: !appWindow.viewOnly button1.enabled : pageRoot.enabled
onClicked: { button1.onClicked: {
console.log("Transfer: sign tx clicked") console.log("Transfer: sweepUnmixableClicked")
signTxDialog.open(); root.sweepUnmixableClicked()
}
}
StandardButton {
id: submitTxButton
text: qsTr("Submit tx file") + translationManager.emptyString
small: true
visible: appWindow.viewOnly
enabled: pageRoot.enabled
onClicked: {
console.log("Transfer: submit tx clicked")
submitTxDialog.open();
}
}
StandardButton {
id: exportKeyImagesButton
text: qsTr("Export key images") + translationManager.emptyString
small: true
visible: !appWindow.viewOnly
enabled: pageRoot.enabled
onClicked: {
console.log("Transfer: export key images clicked")
exportKeyImagesDialog.open();
}
}
StandardButton {
id: importKeyImagesButton
text: qsTr("Import key images") + translationManager.emptyString
small: true
visible: appWindow.viewOnly && !persistentSettings.useRemoteNode
enabled: pageRoot.enabled
onClicked: {
console.log("Transfer: import key images clicked")
importKeyImagesDialog.open();
}
} }
helpTextLarge.text: qsTr("Create a transaction that spends old unmovable outputs") + translationManager.emptyString
} }
} }
@@ -668,12 +746,6 @@ Rectangle {
function onPageCompleted() { function onPageCompleted() {
console.log("transfer page loaded") console.log("transfer page loaded")
updateStatus(); updateStatus();
updatePriorityDropdown()
}
function updatePriorityDropdown() {
priorityDropdown.dataModel = priorityModelV5;
priorityDropdown.update()
} }
//TODO: Add daemon sync status //TODO: Add daemon sync status
@@ -695,6 +767,9 @@ Rectangle {
//pageRoot.enabled = false; //pageRoot.enabled = false;
switch (currentWallet.connected()) { switch (currentWallet.connected()) {
case Wallet.ConnectionStatus_Connecting:
root.warningContent = qsTr("Wallet is connecting to daemon.")
break
case Wallet.ConnectionStatus_Disconnected: case Wallet.ConnectionStatus_Disconnected:
root.warningContent = messageNotConnected; root.warningContent = messageNotConnected;
break break
@@ -730,49 +805,4 @@ Rectangle {
if(typeof amount !== 'undefined') if(typeof amount !== 'undefined')
amountLine.text = amount; amountLine.text = amount;
} }
function updateSendButton(){
// reset message
root.sendButtonWarning = "";
// Currently opened wallet is not view-only
if(appWindow.viewOnly){
root.sendButtonWarning = qsTr("Wallet is view-only and sends are not possible. Unless key images are imported, " +
"the balance reflects only incoming but not outgoing transactions.") + translationManager.emptyString;
return false;
}
// There are sufficient unlocked funds available
if(walletManager.amountFromString(amountLine.text) > appWindow.getUnlockedBalance()){
root.sendButtonWarning = qsTr("Amount is more than unlocked balance.") + translationManager.emptyString;
return false;
}
// There is no warning box displayed
if(root.warningContent !== ""){
return false;
}
if (addressLine.text == "") {
return false;
}
// Address is valid
if(!TxUtils.checkAddress(addressLine.text, appWindow.persistentSettings.nettype)){
root.sendButtonWarning = qsTr("Address is invalid.") + translationManager.emptyString;
return false;
}
// Amount is nonzero
if (!amountLine.text || parseFloat(amountLine.text) <= 0) {
root.sendButtonWarning = qsTr("Enter an amount.") + translationManager.emptyString;
return false;
}
if (paymentIdWarningBox.visible) {
return false;
}
return true;
}
} }

View File

@@ -25,6 +25,7 @@ Item {
anchors.margins: 0 anchors.margins: 0
property int minWidth: 900 property int minWidth: 900
property int minHeight: 600
property int qrCodeSize: 220 property int qrCodeSize: 220
property bool enableTracking: false property bool enableTracking: false
property string trackingError: "" // setting this will show a message @ tracking table property string trackingError: "" // setting this will show a message @ tracking table
@@ -33,6 +34,9 @@ Item {
property var hiddenAmounts: [] property var hiddenAmounts: []
function onPageCompleted() { function onPageCompleted() {
if (appWindow.currentWallet) {
appWindow.current_address = appWindow.currentWallet.address(appWindow.currentWallet.currentSubaddressAccount, 0)
}
// prepare tracking // prepare tracking
trackingCheckbox.checked = root.enableTracking trackingCheckbox.checked = root.enableTracking
root.update(); root.update();
@@ -67,7 +71,7 @@ Item {
ColumnLayout { ColumnLayout {
id: mainLayout id: mainLayout
visible: parent.width >= root.minWidth visible: parent.width >= root.minWidth && appWindow.height >= root.minHeight
spacing: 0 spacing: 0
// emulates max-width + center for container // emulates max-width + center for container
@@ -151,14 +155,10 @@ Item {
model: trackingModel model: trackingModel
message: { message: {
if(!root.enableTracking){ if(!root.enableTracking){
return qsTr( return "<style>p{font-size:14px;}</style> <p>%1</p> <p>%2</p>"
"<style>p{font-size:14px;}</style>" + .arg(qsTr("This page will automatically scan the blockchain and the tx pool for incoming transactions using the QR code."))
"<p>This page will automatically scan the blockchain and the tx pool " + .arg(qsTr("It's up to you whether to accept unconfirmed transactions or not. It is likely they'll be confirmed in short order, but there is still a possibility they might not, so for larger values you may want to wait for one or more confirmation(s)"))
"for incoming transactions using the QR code.</p>" + + translationManager.emptyString;
"<p>It's up to you whether to accept unconfirmed transactions or not. It is likely they'll be " +
"confirmed in short order, but there is still a possibility they might not, so for larger " +
"values you may want to wait for one or more confirmation(s).</p>"
) + translationManager.emptyString;
} else if(root.trackingError !== ""){ } else if(root.trackingError !== ""){
return root.trackingError; return root.trackingError;
} else if(trackingModel.count < 1){ } else if(trackingModel.count < 1){
@@ -265,7 +265,10 @@ Item {
font.pixelSize: 12 font.pixelSize: 12
font.bold: false font.bold: false
color: "white" color: "white"
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 12px;}</style>Currently selected address: ") + addressLabel + qsTr(" <a href='#'>(Change)</a>") + translationManager.emptyString text: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 12px;}</style>%1: %2 <a href='#'>(%3)</a>"
.arg(qsTr("Currently selected address"))
.arg(addressLabel)
.arg(qsTr("Change")) + translationManager.emptyString
textFormat: Text.RichText textFormat: Text.RichText
themeTransition: false themeTransition: false
@@ -545,7 +548,7 @@ Item {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: appWindow.showPageRequest("Receive") onClicked: appWindow.showPageRequest("Settings")
} }
} }
} }
@@ -554,7 +557,7 @@ Item {
Rectangle { Rectangle {
// Shows when the window is too small // Shows when the window is too small
visible: parent.width < root.minWidth visible: parent.width < root.minWidth || appWindow.height < root.minHeight
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 100; anchors.topMargin: 100;
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
@@ -571,6 +574,13 @@ Item {
text: qsTr("The merchant page requires a larger window") + translationManager.emptyString text: qsTr("The merchant page requires a larger window") + translationManager.emptyString
themeTransition: false themeTransition: false
} }
MouseArea {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: appWindow.showPageRequest("Settings")
}
} }
function update() { function update() {
@@ -582,7 +592,7 @@ Item {
return return
} }
if (appWindow.currentWallet.connected() == Wallet.ConnectionStatus_Disconnected) { if (appWindow.disconnected) {
root.trackingError = qsTr("WARNING: no connection to daemon"); root.trackingError = qsTr("WARNING: no connection to daemon");
trackingModel.clear(); trackingModel.clear();
return return
@@ -590,9 +600,7 @@ Item {
var model = appWindow.currentWallet.historyModel var model = appWindow.currentWallet.historyModel
var count = model.rowCount() var count = model.rowCount()
var totalAmount = 0
var nTransactions = 0 var nTransactions = 0
var blockchainHeight = null
var txs = [] var txs = []
// Currently selected subaddress as per Receive page // Currently selected subaddress as per Receive page
@@ -608,8 +616,6 @@ Item {
var subaddrIndex = model.data(idx, TransactionHistoryModel.TransactionSubaddrIndexRole); var subaddrIndex = model.data(idx, TransactionHistoryModel.TransactionSubaddrIndexRole);
if (!isout && subaddrAccount == appWindow.currentWallet.currentSubaddressAccount && subaddrIndex == current_subaddress_table_index) { if (!isout && subaddrAccount == appWindow.currentWallet.currentSubaddressAccount && subaddrIndex == current_subaddress_table_index) {
var amount = model.data(idx, TransactionHistoryModel.TransactionAtomicAmountRole);
totalAmount = walletManager.addi(totalAmount, amount)
nTransactions += 1 nTransactions += 1
var txid = model.data(idx, TransactionHistoryModel.TransactionHashRole); var txid = model.data(idx, TransactionHistoryModel.TransactionHashRole);
@@ -617,21 +623,17 @@ Item {
var in_txpool = false; var in_txpool = false;
var confirmations = 0; var confirmations = 0;
var displayAmount = 0; var displayAmount = model.data(idx, TransactionHistoryModel.TransactionDisplayAmountRole);
if (blockHeight == 0) { if (blockHeight === undefined) {
in_txpool = true; in_txpool = true;
} else { } else {
if (blockchainHeight == null) confirmations = model.data(idx, TransactionHistoryModel.TransactionConfirmationsRole);
blockchainHeight = walletManager.blockchainHeight()
confirmations = blockchainHeight - blockHeight - 1
displayAmount = model.data(idx, TransactionHistoryModel.TransactionDisplayAmountRole);
} }
txs.push({ txs.push({
"amount": displayAmount, "amount": displayAmount,
"confirmations": confirmations, "confirmations": confirmations,
"blockheight": blockHeight,
"in_txpool": in_txpool, "in_txpool": in_txpool,
"txid": txid, "txid": txid,
"time_epoch": timeEpoch, "time_epoch": timeEpoch,
@@ -651,9 +653,7 @@ Item {
txs.forEach(function(tx){ txs.forEach(function(tx){
trackingModel.append({ trackingModel.append({
"amount": tx.amount, "amount": tx.amount,
"blockheight": tx.blockheight,
"confirmations": tx.confirmations, "confirmations": tx.confirmations,
"blockheight": tx.blockHeight,
"in_txpool": tx.in_txpool, "in_txpool": tx.in_txpool,
"txid": tx.txid, "txid": tx.txid,
"time_epoch": tx.time_epoch, "time_epoch": tx.time_epoch,

View File

@@ -125,7 +125,7 @@ ListView {
font.pixelSize: 14 font.pixelSize: 14
font.bold: true font.bold: true
color: hide_amount ? "#707070" : "#009F1E" color: hide_amount ? "#707070" : "#009F1E"
text: hide_amount ? '-' : '+' + amount text: hide_amount ? '-' : '+' + amount + (in_txpool ? ' (%1)'.arg(qsTr('unconfirmed')) : '')
selectionColor: MoneroComponents.Style.textSelectionColor selectionColor: MoneroComponents.Style.textSelectionColor
selectByMouse: true selectByMouse: true
readOnly: true readOnly: true

View File

@@ -273,7 +273,6 @@ Rectangle {
// LOG // LOG
id: navLog id: navLog
property bool isActive: settingsStateView.state === "Log" property bool isActive: settingsStateView.state === "Log"
visible: appWindow.walletMode >= 2
Layout.preferredWidth: navLogText.width + grid.textMargin Layout.preferredWidth: navLogText.width + grid.textMargin
Layout.preferredHeight: 32 Layout.preferredHeight: 32
Layout.minimumWidth: 72 Layout.minimumWidth: 72

View File

@@ -103,7 +103,7 @@ Rectangle {
MoneroComponents.TextBlock { MoneroComponents.TextBlock {
font.pixelSize: 14 font.pixelSize: 14
color: MoneroComponents.Style.dimmedFontColor color: MoneroComponents.Style.dimmedFontColor
text: Version.GUI_MONERO_VERSION + translationManager.emptyString text: moneroVersion
} }
Rectangle { Rectangle {
@@ -131,10 +131,11 @@ Rectangle {
} }
MoneroComponents.TextBlock { MoneroComponents.TextBlock {
id: walletLocation
Layout.fillWidth: true Layout.fillWidth: true
color: MoneroComponents.Style.dimmedFontColor color: MoneroComponents.Style.dimmedFontColor
font.pixelSize: 14 font.pixelSize: 14
property string walletPath: (isIOS ? moneroAccountsDir : "") + appWindow.walletPath() property string walletPath: (isIOS ? moneroAccountsDir : "") + persistentSettings.wallet_path
text: "\ text: "\
<style type='text/css'>\ <style type='text/css'>\
a {cursor:pointer;text-decoration: none; color: #FF6C3C}\ a {cursor:pointer;text-decoration: none; color: #FF6C3C}\
@@ -182,7 +183,7 @@ Rectangle {
color: MoneroComponents.Style.dimmedFontColor color: MoneroComponents.Style.dimmedFontColor
font.pixelSize: 14 font.pixelSize: 14
property var style: "<style type='text/css'>a {cursor:pointer;text-decoration: none; color: #FF6C3C}</style>" property var style: "<style type='text/css'>a {cursor:pointer;text-decoration: none; color: #FF6C3C}</style>"
text: (currentWallet ? currentWallet.walletCreationHeight : "") + style + qsTr(" <a href='#'> (Click to change)</a>") + translationManager.emptyString text: (currentWallet ? currentWallet.walletCreationHeight : "") + style + " <a href='#'> (%1)</a>".arg(qsTr("Change")) + translationManager.emptyString
onLinkActivated: { onLinkActivated: {
inputDialog.labelText = qsTr("Set a new restore height.\nYou can enter a block height or a date (YYYY-MM-DD):") + translationManager.emptyString; inputDialog.labelText = qsTr("Set a new restore height.\nYou can enter a block height or a date (YYYY-MM-DD):") + translationManager.emptyString;
inputDialog.onAcceptedCallback = function() { inputDialog.onAcceptedCallback = function() {
@@ -212,7 +213,6 @@ Rectangle {
+ "The old wallet cache file will be renamed and can be restored later.\n" + "The old wallet cache file will be renamed and can be restored later.\n"
); );
confirmationDialog.icon = StandardIcon.Question confirmationDialog.icon = StandardIcon.Question
confirmationDialog.cancelText = qsTr("Cancel")
confirmationDialog.onAcceptedCallback = function() { confirmationDialog.onAcceptedCallback = function() {
appWindow.closeWallet(function() { appWindow.closeWallet(function() {
walletManager.clearWalletCache(persistentSettings.wallet_path); walletManager.clearWalletCache(persistentSettings.wallet_path);
@@ -230,7 +230,7 @@ Rectangle {
appWindow.showStatusMessage(qsTr("Invalid restore height specified. Must be a number or a date formatted YYYY-MM-DD"),3); appWindow.showStatusMessage(qsTr("Invalid restore height specified. Must be a number or a date formatted YYYY-MM-DD"),3);
} }
inputDialog.onRejectedCallback = null; inputDialog.onRejectedCallback = null;
inputDialog.open(currentWallet ? currentWallet.walletCreationHeight : "0") inputDialog.open(currentWallet ? currentWallet.walletCreationHeight.toFixed(0) : "0")
} }
MouseArea { MouseArea {
@@ -381,32 +381,38 @@ Rectangle {
} }
} }
// Copy info to clipboard RowLayout {
MoneroComponents.StandardButton { spacing: 20;
small: true
text: qsTr("Copy to clipboard") + translationManager.emptyString
onClicked: {
var data = "";
data += "GUI version: " + Version.GUI_VERSION + " (Qt " + qtRuntimeVersion + ")";
data += "\nEmbedded Monero version: " + Version.GUI_MONERO_VERSION;
data += "\nWallet path: ";
var wallet_path = walletPath(); MoneroComponents.StandardButton {
if(isIOS) small: true
wallet_path = moneroAccountsDir + wallet_path; text: qsTr("Copy to clipboard") + translationManager.emptyString
data += wallet_path; onClicked: {
var data = "";
data += "GUI version: " + Version.GUI_VERSION + " (Qt " + qtRuntimeVersion + ")";
data += "\nEmbedded Monero version: " + moneroVersion;
data += "\nWallet path: " + walletLocation.walletPath;
data += "\nWallet creation height: "; data += "\nWallet creation height: ";
if(currentWallet) if(currentWallet)
data += currentWallet.walletCreationHeight; data += currentWallet.walletCreationHeight;
data += "\nWallet log path: " + walletLogPath; data += "\nWallet log path: " + walletLogPath;
data += "\nWallet mode: " + walletModeString; data += "\nWallet mode: " + walletModeString;
data += "\nGraphics: " + isOpenGL ? "OpenGL" : "Low graphics mode"; data += "\nGraphics: " + isOpenGL ? "OpenGL" : "Low graphics mode";
console.log("Copied to clipboard"); console.log("Copied to clipboard");
clipboard.setText(data); clipboard.setText(data);
appWindow.showStatusMessage(qsTr("Copied to clipboard"), 3); appWindow.showStatusMessage(qsTr("Copied to clipboard"), 3);
}
}
MoneroComponents.StandardButton {
small: true
text: qsTr("Donate to Monero") + translationManager.emptyString
onClicked: {
middlePanel.sendTo("888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H", "", "Donation to Monero Core Team");
}
} }
} }
} }

View File

@@ -58,6 +58,14 @@ Rectangle {
text: qsTr("Custom decorations") + translationManager.emptyString text: qsTr("Custom decorations") + translationManager.emptyString
} }
MoneroComponents.CheckBox {
id: checkForUpdatesCheckBox
enabled: !disableCheckUpdatesFlag
checked: persistentSettings.checkForUpdates && !disableCheckUpdatesFlag
onClicked: persistentSettings.checkForUpdates = !persistentSettings.checkForUpdates
text: qsTr("Check for updates periodically") + translationManager.emptyString
}
MoneroComponents.CheckBox { MoneroComponents.CheckBox {
id: hideBalanceCheckBox id: hideBalanceCheckBox
checked: persistentSettings.hideBalance checked: persistentSettings.hideBalance
@@ -78,6 +86,46 @@ Rectangle {
persistentSettings.blackTheme = MoneroComponents.Style.blackTheme; persistentSettings.blackTheme = MoneroComponents.Style.blackTheme;
} }
} }
MoneroComponents.CheckBox {
checked: persistentSettings.askPasswordBeforeSending
text: qsTr("Ask for password before sending a transaction") + translationManager.emptyString
toggleOnClick: false
onClicked: {
if (persistentSettings.askPasswordBeforeSending) {
passwordDialog.onAcceptedCallback = function() {
if (appWindow.walletPassword === passwordDialog.password){
persistentSettings.askPasswordBeforeSending = false;
} else {
passwordDialog.showError(qsTr("Wrong password"));
}
}
passwordDialog.onRejectedCallback = null;
passwordDialog.open()
} else {
persistentSettings.askPasswordBeforeSending = true;
}
}
}
MoneroComponents.CheckBox {
checked: persistentSettings.autosave
onClicked: persistentSettings.autosave = !persistentSettings.autosave
text: qsTr("Autosave") + translationManager.emptyString
}
MoneroComponents.Slider {
Layout.fillWidth: true
Layout.leftMargin: 35
Layout.topMargin: 6
visible: persistentSettings.autosave
from: 1
stepSize: 1
to: 60
value: persistentSettings.autosaveMinutes
text: "%1 %2 %3".arg(qsTr("Every")).arg(value).arg(qsTr("minute(s)")) + translationManager.emptyString
onMoved: persistentSettings.autosaveMinutes = value
}
MoneroComponents.CheckBox { MoneroComponents.CheckBox {
id: userInActivityCheckbox id: userInActivityCheckbox
@@ -86,70 +134,20 @@ Rectangle {
text: qsTr("Lock wallet on inactivity") + translationManager.emptyString text: qsTr("Lock wallet on inactivity") + translationManager.emptyString
} }
ColumnLayout { MoneroComponents.Slider {
visible: userInActivityCheckbox.checked visible: userInActivityCheckbox.checked
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 6 Layout.topMargin: 6
Layout.leftMargin: 42 Layout.leftMargin: 35
spacing: 0 from: 1
stepSize: 1
Text { to: 60
color: MoneroComponents.Style.defaultFontColor value: persistentSettings.lockOnUserInActivityInterval
font.pixelSize: 14 text: {
Layout.fillWidth: true var minutes = value > 1 ? qsTr("minutes") : qsTr("minute");
text: { return qsTr("After ") + value + " " + minutes + translationManager.emptyString;
var val = userInactivitySlider.value;
var minutes = val > 1 ? qsTr("minutes") : qsTr("minute");
qsTr("After ") + val + " " + minutes + translationManager.emptyString;
}
}
Slider {
id: userInactivitySlider
from: 1
value: persistentSettings.lockOnUserInActivityInterval
to: 60
leftPadding: 0
stepSize: 1
snapMode: Slider.SnapAlways
background: Rectangle {
x: parent.leftPadding
y: parent.topPadding + parent.availableHeight / 2 - height / 2
implicitWidth: 200
implicitHeight: 4
width: parent.availableWidth
height: implicitHeight
radius: 2
color: MoneroComponents.Style.progressBarBackgroundColor
Rectangle {
width: parent.visualPosition * parent.width
height: parent.height
color: MoneroComponents.Style.green
radius: 2
}
}
handle: Rectangle {
x: parent.leftPadding + parent.visualPosition * (parent.availableWidth - width)
y: parent.topPadding + parent.availableHeight / 2 - height / 2
implicitWidth: 18
implicitHeight: 18
radius: 8
color: parent.pressed ? "#f0f0f0" : "#f6f6f6"
border.color: MoneroComponents.Style.grey
}
onMoved: persistentSettings.lockOnUserInActivityInterval = userInactivitySlider.value;
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
}
} }
onMoved: persistentSettings.lockOnUserInActivityInterval = value
} }
//! Manage pricing //! Manage pricing
@@ -212,6 +210,7 @@ Rectangle {
MoneroComponents.StandardDropdown { MoneroComponents.StandardDropdown {
id: fiatPriceCurrencyDropdown id: fiatPriceCurrencyDropdown
Layout.fillWidth: true Layout.fillWidth: true
currentIndex: persistentSettings.fiatPriceCurrency === "xmrusd" ? 0 : 1
dataModel: fiatPriceCurrencyModel dataModel: fiatPriceCurrencyModel
onChanged: { onChanged: {
var obj = dataModel.get(currentIndex); var obj = dataModel.get(currentIndex);
@@ -297,10 +296,6 @@ Rectangle {
i += 1; i += 1;
} }
fiatPriceProviderDropDown.update();
fiatPriceCurrencyDropdown.currentIndex = persistentSettings.fiatPriceCurrency === "xmrusd" ? 0 : 1;
fiatPriceCurrencyDropdown.update();
console.log('SettingsLayout loaded'); console.log('SettingsLayout loaded');
} }
} }

View File

@@ -159,7 +159,7 @@ Rectangle {
textFormat: TextEdit.RichText textFormat: TextEdit.RichText
selectByMouse: true selectByMouse: true
selectByKeyboard: true selectByKeyboard: true
font.family: MoneroComponents.Style.defaultFontColor font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 14 font.pixelSize: 14
wrapMode: TextEdit.Wrap wrapMode: TextEdit.Wrap
readOnly: true readOnly: true
@@ -213,9 +213,27 @@ Rectangle {
MoneroComponents.LineEdit { MoneroComponents.LineEdit {
id: sendCommandText id: sendCommandText
Layout.fillWidth: true Layout.fillWidth: true
property var lastCommands: []
property int currentCommandIndex
fontBold: false fontBold: false
placeholderText: qsTr("command + enter (e.g 'help' or 'status')") + translationManager.emptyString placeholderText: qsTr("command + enter (e.g 'help' or 'status')") + translationManager.emptyString
placeholderFontSize: 16 placeholderFontSize: 16
Keys.onUpPressed: {
if (currentCommandIndex != 0) {
sendCommandText.text = lastCommands[currentCommandIndex - 1]
currentCommandIndex = currentCommandIndex - 1
}
}
Keys.onDownPressed: {
if (currentCommandIndex == lastCommands.length - 1) {
currentCommandIndex = lastCommands.length;
return text = "";
}
if (currentCommandIndex != lastCommands.length) {
sendCommandText.text = lastCommands[currentCommandIndex + 1]
currentCommandIndex = currentCommandIndex + 1
}
}
onAccepted: { onAccepted: {
if(text.length > 0) { if(text.length > 0) {
consoleArea.logCommand(">>> " + text) consoleArea.logCommand(">>> " + text)
@@ -225,15 +243,14 @@ Rectangle {
} }
}); });
} }
lastCommands.push(text);
currentCommandIndex = lastCommands.length;
text = "" text = ""
} }
} }
} }
Component.onCompleted: { Component.onCompleted: {
logLevelDropdown.currentIndex = appWindow.persistentSettings.logLevel;
logLevelDropdown.update();
if(typeof daemonManager != "undefined") if(typeof daemonManager != "undefined")
daemonManager.daemonConsoleUpdated.connect(onDaemonConsoleUpdated) daemonManager.daemonConsoleUpdated.connect(onDaemonConsoleUpdated)
} }

View File

@@ -130,13 +130,6 @@ Rectangle{
topPadding: 0 topPadding: 0
text: qsTr("The blockchain is downloaded to your computer. Provides higher security and requires more local storage.") + translationManager.emptyString text: qsTr("The blockchain is downloaded to your computer. Provides higher security and requires more local storage.") + translationManager.emptyString
width: parent.width - (localNodeIcon.width + localNodeIcon.anchors.leftMargin + anchors.leftMargin) width: parent.width - (localNodeIcon.width + localNodeIcon.anchors.leftMargin + anchors.leftMargin)
// @TODO: Legacy. Remove after Qt 5.8.
// https://stackoverflow.com/questions/41990013
MouseArea {
anchors.fill: parent
enabled: false
}
} }
} }
@@ -229,13 +222,6 @@ Rectangle{
topPadding: 0 topPadding: 0
text: qsTr("Uses a third-party server to connect to the Monero network. Less secure, but easier on your computer.") + translationManager.emptyString text: qsTr("Uses a third-party server to connect to the Monero network. Less secure, but easier on your computer.") + translationManager.emptyString
width: parent.width - (remoteNodeIcon.width + remoteNodeIcon.anchors.leftMargin + anchors.leftMargin) width: parent.width - (remoteNodeIcon.width + remoteNodeIcon.anchors.leftMargin + anchors.leftMargin)
// @TODO: Legacy. Remove after Qt 5.8.
// https://stackoverflow.com/questions/41990013
MouseArea {
anchors.fill: parent
enabled: false
}
} }
MouseArea { MouseArea {
@@ -279,12 +265,10 @@ Rectangle{
Layout.minimumWidth: 100 Layout.minimumWidth: 100
placeholderFontSize: 15 placeholderFontSize: 15
daemonAddrLabelText: qsTr("Address") daemonAddrLabelText: qsTr("Address") + translationManager.emptyString
daemonPortLabelText: qsTr("Port") daemonPortLabelText: qsTr("Port") + translationManager.emptyString
property var rna: persistentSettings.remoteNodeAddress initialAddress: persistentSettings.remoteNodeAddress
daemonAddrText: rna.search(":") != -1 ? rna.split(":")[0].trim() : ""
daemonPortText: rna.search(":") != -1 ? (rna.split(":")[1].trim() == "") ? appWindow.getDefaultDaemonRpcPort(persistentSettings.nettype) : rna.split(":")[1] : ""
onEditingFinished: { onEditingFinished: {
persistentSettings.remoteNodeAddress = remoteNodeEdit.getAddress(); persistentSettings.remoteNodeAddress = remoteNodeEdit.getAddress();
console.log("setting remote node to " + persistentSettings.remoteNodeAddress); console.log("setting remote node to " + persistentSettings.remoteNodeAddress);
@@ -318,7 +302,7 @@ Rectangle{
labelText: qsTr("Daemon password") + translationManager.emptyString labelText: qsTr("Daemon password") + translationManager.emptyString
text: persistentSettings.daemonPassword text: persistentSettings.daemonPassword
placeholderText: qsTr("Password") + translationManager.emptyString placeholderText: qsTr("Password") + translationManager.emptyString
echoMode: TextInput.Password password: true
placeholderFontSize: 15 placeholderFontSize: 15
labelFontSize: 14 labelFontSize: 14
fontSize: 15 fontSize: 15
@@ -381,15 +365,13 @@ Rectangle{
fontSize: 15 fontSize: 15
labelFontSize: 14 labelFontSize: 14
property string style: "<style type='text/css'>a {cursor:pointer;text-decoration: none; color: #FF6C3C}</style>" property string style: "<style type='text/css'>a {cursor:pointer;text-decoration: none; color: #FF6C3C}</style>"
labelText: qsTr("Blockchain location") + style + qsTr(" <a href='#'> (change)</a>") + translationManager.emptyString labelText: qsTr("Blockchain location") + style + " <a href='#'> (%1)</a>".arg(qsTr("Change")) + translationManager.emptyString
labelButtonText: qsTr("Reset") + translationManager.emptyString
labelButtonVisible: text
placeholderText: qsTr("(default)") + translationManager.emptyString placeholderText: qsTr("(default)") + translationManager.emptyString
placeholderFontSize: 15 placeholderFontSize: 15
readOnly: true readOnly: true
text: { text: persistentSettings.blockchainDataDir
if(persistentSettings.blockchainDataDir.length > 0){
return persistentSettings.blockchainDataDir;
} else { return "" }
}
addressValidation: false addressValidation: false
onInputLabelLinkActivated: { onInputLabelLinkActivated: {
//mouse.accepted = false //mouse.accepted = false
@@ -399,6 +381,7 @@ Rectangle{
blockchainFileDialog.open(); blockchainFileDialog.open();
blockchainFolder.focus = true; blockchainFolder.focus = true;
} }
onLabelButtonClicked: persistentSettings.blockchainDataDir = ""
} }
} }
@@ -413,7 +396,12 @@ Rectangle{
placeholderFontSize: 15 placeholderFontSize: 15
text: persistentSettings.daemonFlags text: persistentSettings.daemonFlags
addressValidation: false addressValidation: false
onEditingFinished: persistentSettings.daemonFlags = daemonFlags.text; error: text.match(/(^|\s)--(data-dir|bootstrap-daemon-address)/)
onEditingFinished: {
if (!daemonFlags.error) {
persistentSettings.daemonFlags = daemonFlags.text;
}
}
} }
RowLayout { RowLayout {
@@ -427,17 +415,9 @@ Rectangle{
Layout.minimumWidth: 100 Layout.minimumWidth: 100
Layout.bottomMargin: 20 Layout.bottomMargin: 20
daemonAddrLabelText: qsTr("Bootstrap Address") daemonAddrLabelText: qsTr("Bootstrap Address") + translationManager.emptyString
daemonPortLabelText: qsTr("Bootstrap Port") daemonPortLabelText: qsTr("Bootstrap Port") + translationManager.emptyString
daemonAddrText: persistentSettings.bootstrapNodeAddress.split(":")[0].trim() initialAddress: persistentSettings.bootstrapNodeAddress
daemonPortText: {
var node_split = persistentSettings.bootstrapNodeAddress.split(":");
if(node_split.length == 2){
(node_split[1].trim() == "") ? appWindow.getDefaultDaemonRpcPort(persistentSettings.nettype) : node_split[1];
} else {
return ""
}
}
onEditingFinished: { onEditingFinished: {
if (daemonAddrText == "auto") { if (daemonAddrText == "auto") {
persistentSettings.bootstrapNodeAddress = daemonAddrText; persistentSettings.bootstrapNodeAddress = daemonAddrText;

View File

@@ -30,6 +30,7 @@ import QtQuick 2.9
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Controls 2.0 import QtQuick.Controls 2.0
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import FontAwesome 1.0
import "../../js/Utils.js" as Utils import "../../js/Utils.js" as Utils
import "../../components" as MoneroComponents import "../../components" as MoneroComponents
@@ -47,10 +48,10 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
anchors.margins: 20 anchors.margins: 20
anchors.topMargin: 0 anchors.topMargin: 0
spacing: 8 spacing: 0
MoneroComponents.SettingsListItem { MoneroComponents.SettingsListItem {
buttonText: qsTr("Close wallet") + translationManager.emptyString iconText: FontAwesome.signOutAlt
description: qsTr("Logs out of this wallet.") + translationManager.emptyString description: qsTr("Logs out of this wallet.") + translationManager.emptyString
title: qsTr("Close this wallet") + translationManager.emptyString title: qsTr("Close this wallet") + translationManager.emptyString
@@ -58,7 +59,7 @@ Rectangle {
} }
MoneroComponents.SettingsListItem { MoneroComponents.SettingsListItem {
buttonText: qsTr("Create wallet") + translationManager.emptyString iconText: FontAwesome.eye
description: qsTr("Creates a new wallet that can only view and initiate transactions, but requires a spendable wallet to sign transactions before sending.") + translationManager.emptyString description: qsTr("Creates a new wallet that can only view and initiate transactions, but requires a spendable wallet to sign transactions before sending.") + translationManager.emptyString
title: qsTr("Create a view-only wallet") + translationManager.emptyString title: qsTr("Create a view-only wallet") + translationManager.emptyString
visible: !appWindow.viewOnly visible: !appWindow.viewOnly
@@ -80,7 +81,7 @@ Rectangle {
} }
MoneroComponents.SettingsListItem { MoneroComponents.SettingsListItem {
buttonText: qsTr("Show seed") + translationManager.emptyString iconText: FontAwesome.key
description: qsTr("Store this information safely to recover your wallet in the future.") + translationManager.emptyString description: qsTr("Store this information safely to recover your wallet in the future.") + translationManager.emptyString
title: qsTr("Show seed & keys") + translationManager.emptyString title: qsTr("Show seed & keys") + translationManager.emptyString
@@ -90,7 +91,7 @@ Rectangle {
} }
MoneroComponents.SettingsListItem { MoneroComponents.SettingsListItem {
buttonText: qsTr("Rescan") + translationManager.emptyString iconText: FontAwesome.repeat
description: qsTr("Use this feature if you think the shown balance is not accurate.") + translationManager.emptyString description: qsTr("Use this feature if you think the shown balance is not accurate.") + translationManager.emptyString
title: qsTr("Rescan wallet balance") + translationManager.emptyString title: qsTr("Rescan wallet balance") + translationManager.emptyString
visible: appWindow.walletMode >= 2 visible: appWindow.walletMode >= 2
@@ -114,7 +115,7 @@ Rectangle {
} }
MoneroComponents.SettingsListItem { MoneroComponents.SettingsListItem {
buttonText: qsTr("Change password") + translationManager.emptyString iconText: FontAwesome.ellipsisH
description: qsTr("Change the password of your wallet.") + translationManager.emptyString description: qsTr("Change the password of your wallet.") + translationManager.emptyString
title: qsTr("Change wallet password") + translationManager.emptyString title: qsTr("Change wallet password") + translationManager.emptyString
@@ -135,6 +136,19 @@ Rectangle {
passwordDialog.open() passwordDialog.open()
} }
} }
MoneroComponents.SettingsListItem {
iconText: FontAwesome.cashRegister
isLast: true
description: qsTr("Receive Monero for your business, easily.") + translationManager.emptyString
title: qsTr("Enter merchant mode") + translationManager.emptyString
onClicked: {
middlePanel.state = "Merchant";
middlePanel.flickable.contentY = 0;
updateBalance();
}
}
} }
Component.onCompleted: { Component.onCompleted: {

27
qml.qrc
View File

@@ -3,16 +3,16 @@
<file>main.qml</file> <file>main.qml</file>
<file>LeftPanel.qml</file> <file>LeftPanel.qml</file>
<file>MiddlePanel.qml</file> <file>MiddlePanel.qml</file>
<file>images/download-white.png</file>
<file>images/download-white@2x.png</file>
<file>images/external-link-white.png</file>
<file>images/external-link-white@2x.png</file>
<file>components/Label.qml</file> <file>components/Label.qml</file>
<file>components/SettingsListItem.qml</file> <file>components/SettingsListItem.qml</file>
<file>components/Slider.qml</file>
<file>components/UpdateDialog.qml</file>
<file>images/whatIsIcon.png</file> <file>images/whatIsIcon.png</file>
<file>images/whatIsIcon@2x.png</file> <file>images/whatIsIcon@2x.png</file>
<file>images/lockIcon.png</file>
<file>components/MenuButton.qml</file> <file>components/MenuButton.qml</file>
<file>monero/utils/gpg_keys/binaryfate.asc</file>
<file>monero/utils/gpg_keys/fluffypony.asc</file>
<file>monero/utils/gpg_keys/luigi1111.asc</file>
<file>pages/Account.qml</file> <file>pages/Account.qml</file>
<file>pages/Transfer.qml</file> <file>pages/Transfer.qml</file>
<file>pages/History.qml</file> <file>pages/History.qml</file>
@@ -27,7 +27,7 @@
<file>components/TipItem.qml</file> <file>components/TipItem.qml</file>
<file>images/tip.png</file> <file>images/tip.png</file>
<file>components/MenuButtonDivider.qml</file> <file>components/MenuButtonDivider.qml</file>
<file>images/moneroIcon.png</file> <file>images/monero-vector.svg</file>
<file>components/StandardDropdown.qml</file> <file>components/StandardDropdown.qml</file>
<file>images/whiteDropIndicator.png</file> <file>images/whiteDropIndicator.png</file>
<file>images/whiteDropIndicator@2x.png</file> <file>images/whiteDropIndicator@2x.png</file>
@@ -38,7 +38,6 @@
<file>images/prevMonth.png</file> <file>images/prevMonth.png</file>
<file>images/prevMonth@2x.png</file> <file>images/prevMonth@2x.png</file>
<file>components/TitleBar.qml</file> <file>components/TitleBar.qml</file>
<file>images/moneroLogo2.png</file>
<file>images/resize.png</file> <file>images/resize.png</file>
<file>images/resize@2x.png</file> <file>images/resize@2x.png</file>
<file>images/resizeHovered.png</file> <file>images/resizeHovered.png</file>
@@ -89,6 +88,7 @@
<file>lang/flags/gb.png</file> <file>lang/flags/gb.png</file>
<file>lang/flags/us.png</file> <file>lang/flags/us.png</file>
<file>lang/flags/pirate.png</file> <file>lang/flags/pirate.png</file>
<file>lang/flags/nb_NO.png</file>
<file>pages/Receive.qml</file> <file>pages/Receive.qml</file>
<file>pages/TxKey.qml</file> <file>pages/TxKey.qml</file>
<file>pages/SharedRingDB.qml</file> <file>pages/SharedRingDB.qml</file>
@@ -99,11 +99,11 @@
<file>components/ProcessingSplash.qml</file> <file>components/ProcessingSplash.qml</file>
<file>components/ProgressBar.qml</file> <file>components/ProgressBar.qml</file>
<file>components/StandardDialog.qml</file> <file>components/StandardDialog.qml</file>
<file>components/DevicePassphraseDialog.qml</file>
<file>pages/Sign.qml</file> <file>pages/Sign.qml</file>
<file>components/DaemonManagerDialog.qml</file> <file>components/DaemonManagerDialog.qml</file>
<file>version.js</file> <file>version.js</file>
<file>components/QRCodeScanner.qml</file> <file>components/QRCodeScanner.qml</file>
<file>components/Notifier.qml</file>
<file>components/TextBlock.qml</file> <file>components/TextBlock.qml</file>
<file>components/RemoteNodeEdit.qml</file> <file>components/RemoteNodeEdit.qml</file>
<file>pages/Keys.qml</file> <file>pages/Keys.qml</file>
@@ -113,8 +113,6 @@
<file>images/card-background-white.png</file> <file>images/card-background-white.png</file>
<file>images/card-background-white@2x.png</file> <file>images/card-background-white@2x.png</file>
<file>images/moneroLogo_white.png</file> <file>images/moneroLogo_white.png</file>
<file>images/question.png</file>
<file>images/question@2x.png</file>
<file>images/titlebarLogo.png</file> <file>images/titlebarLogo.png</file>
<file>images/titlebarLogo@2x.png</file> <file>images/titlebarLogo@2x.png</file>
<file>pages/merchant/MerchantTitlebar.qml</file> <file>pages/merchant/MerchantTitlebar.qml</file>
@@ -191,7 +189,6 @@
<file>wizard/WizardHeader.qml</file> <file>wizard/WizardHeader.qml</file>
<file>wizard/WizardHome.qml</file> <file>wizard/WizardHome.qml</file>
<file>wizard/WizardLanguage.qml</file> <file>wizard/WizardLanguage.qml</file>
<file>wizard/WizardLang.qml</file>
<file>wizard/WizardNav.qml</file> <file>wizard/WizardNav.qml</file>
<file>wizard/WizardWalletInput.qml</file> <file>wizard/WizardWalletInput.qml</file>
<file>wizard/WizardRestoreWallet1.qml</file> <file>wizard/WizardRestoreWallet1.qml</file>
@@ -207,7 +204,6 @@
<file>js/Wizard.js</file> <file>js/Wizard.js</file>
<file>components/LanguageSidebar.qml</file> <file>components/LanguageSidebar.qml</file>
<file>images/world-flags-globe.png</file> <file>images/world-flags-globe.png</file>
<file>images/langFlagGrey.png</file>
<file>images/restore-wallet-from-hardware@2x.png</file> <file>images/restore-wallet-from-hardware@2x.png</file>
<file>images/restore-wallet-from-hardware.png</file> <file>images/restore-wallet-from-hardware.png</file>
<file>images/open-wallet-from-file@2x.png</file> <file>images/open-wallet-from-file@2x.png</file>
@@ -222,12 +218,9 @@
<file>images/local-node@2x.png</file> <file>images/local-node@2x.png</file>
<file>images/local-node-full.png</file> <file>images/local-node-full.png</file>
<file>images/local-node-full@2x.png</file> <file>images/local-node-full@2x.png</file>
<file>wizard/WizardNavProgressDot.qml</file>
<file>wizard/WizardOpenWallet1.qml</file> <file>wizard/WizardOpenWallet1.qml</file>
<file>images/arrow-right-in-circle.png</file> <file>images/arrow-right-in-circle.png</file>
<file>images/arrow-right-in-circle@2x.png</file> <file>images/arrow-right-in-circle@2x.png</file>
<file>images/themes/white/leftPanelBg.jpg</file>
<file>images/themes/white/middlePanelBg.jpg</file>
<file>images/right.svg</file> <file>images/right.svg</file>
<file>images/middlePanelShadow.png</file> <file>images/middlePanelShadow.png</file>
<file>images/themes/white/titlebarLogo@2x.png</file> <file>images/themes/white/titlebarLogo@2x.png</file>
@@ -238,7 +231,6 @@
<file>images/themes/white/close.svg</file> <file>images/themes/white/close.svg</file>
<file>images/themes/white/fullscreen.svg</file> <file>images/themes/white/fullscreen.svg</file>
<file>images/themes/white/minimize.svg</file> <file>images/themes/white/minimize.svg</file>
<file>images/themes/white/question.svg</file>
<file>components/effects/ColorTransition.qml</file> <file>components/effects/ColorTransition.qml</file>
<file>components/effects/GradientBackground.qml</file> <file>components/effects/GradientBackground.qml</file>
<file>images/check-white.svg</file> <file>images/check-white.svg</file>
@@ -246,5 +238,8 @@
<file>images/edit.svg</file> <file>images/edit.svg</file>
<file>images/arrow-right-in-circle-outline-medium-white.svg</file> <file>images/arrow-right-in-circle-outline-medium-white.svg</file>
<file>images/tails-grey.png</file> <file>images/tails-grey.png</file>
<file>components/AdvancedOptionsItem.qml</file>
<file>images/busy-indicator.png</file>
<file>images/busy-indicator@2x.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -23,9 +23,18 @@
<key>CFBundleName</key> <key>CFBundleName</key>
<string>Monero GUI</string> <string>Monero GUI</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2014-2020 The Monero Project</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>org.monero-project.monero-wallet-gui</string> <string>org.monero-project.monero-wallet-gui</string>
<key>CFBundleVersion</key>
<string>@VERSION_LONG@</string>
<key>CFBundleShortVersionString</key>
<string>@VERSION@</string>
<key>NSSupportsAutomaticGraphicsSwitching</key> <key>NSSupportsAutomaticGraphicsSwitching</key>
<true/> <true/>

View File

@@ -3,6 +3,7 @@ add_subdirectory(QR-Code-scanner)
add_subdirectory(daemon) add_subdirectory(daemon)
add_subdirectory(libwalletqt) add_subdirectory(libwalletqt)
add_subdirectory(model) add_subdirectory(model)
add_subdirectory(openpgp)
add_subdirectory(zxcvbn-c) add_subdirectory(zxcvbn-c)
qt5_add_resources(RESOURCES ../qml.qrc) qt5_add_resources(RESOURCES ../qml.qrc)
@@ -14,7 +15,9 @@ file(GLOB SOURCE_FILES
"main/*.h" "main/*.h"
"main/*.cpp" "main/*.cpp"
"libwalletqt/WalletManager.cpp" "libwalletqt/WalletManager.cpp"
"libwalletqt/WalletListenerImpl.cpp"
"libwalletqt/Wallet.cpp" "libwalletqt/Wallet.cpp"
"libwalletqt/PassphraseHelper.cpp"
"libwalletqt/PendingTransaction.cpp" "libwalletqt/PendingTransaction.cpp"
"libwalletqt/TransactionHistory.cpp" "libwalletqt/TransactionHistory.cpp"
"libwalletqt/TransactionInfo.cpp" "libwalletqt/TransactionInfo.cpp"
@@ -28,6 +31,7 @@ file(GLOB SOURCE_FILES
"libwalletqt/UnsignedTransaction.cpp" "libwalletqt/UnsignedTransaction.cpp"
"libwalletqt/WalletManager.h" "libwalletqt/WalletManager.h"
"libwalletqt/Wallet.h" "libwalletqt/Wallet.h"
"libwalletqt/PassphraseHelper.h"
"libwalletqt/PendingTransaction.h" "libwalletqt/PendingTransaction.h"
"libwalletqt/TransactionHistory.h" "libwalletqt/TransactionHistory.h"
"libwalletqt/TransactionInfo.h" "libwalletqt/TransactionInfo.h"
@@ -40,13 +44,16 @@ file(GLOB SOURCE_FILES
"libwalletqt/Subaddress.h" "libwalletqt/Subaddress.h"
"libwalletqt/SubaddressAccount.h" "libwalletqt/SubaddressAccount.h"
"libwalletqt/UnsignedTransaction.h" "libwalletqt/UnsignedTransaction.h"
"daemon/*.h" "daemon/*.h"
"daemon/*.cpp" "daemon/*.cpp"
"model/*.h" "model/*.h"
"model/*.cpp" "model/*.cpp"
"qt/*.h" "qt/*.h"
"qt/*.cpp" "qt/*.cpp"
) )
if(APPLE)
list(APPEND SOURCE_FILES "qt/macoshelper.mm")
endif()
if(ENABLE_PASS_STRENGTH_METER) if(ENABLE_PASS_STRENGTH_METER)
file(GLOB PASS_STRENGTH_FILES file(GLOB PASS_STRENGTH_FILES
@@ -76,27 +83,40 @@ if(MINGW)
list(APPEND RESOURCES ${ICON_RES}) list(APPEND RESOURCES ${ICON_RES})
endif() endif()
add_executable(monero-gui ${EXECUTABLE_FLAG} main/main.cpp if(APPLE)
set(ICON ${PROJECT_SOURCE_DIR}/images/appicon.icns)
set_source_files_properties(${ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
list(APPEND RESOURCES ${ICON})
endif()
add_executable(monero-wallet-gui ${EXECUTABLE_FLAG} main/main.cpp
${SOURCE_FILES} ${SOURCE_FILES}
${PASS_STRENGTH_FILES} ${PASS_STRENGTH_FILES}
${QR_CODE_FILES} ${QR_CODE_FILES}
${RESOURCES} ${RESOURCES}
) )
set_property(TARGET monero-gui PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set_target_properties(monero-wallet-gui PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/share/Info.plist"
)
# OpenGL # OpenGL
target_include_directories(monero-gui PUBLIC ${OPENGL_INCLUDE_DIR}) target_include_directories(monero-wallet-gui PUBLIC ${OPENGL_INCLUDE_DIR})
message(STATUS "OpenGL: include dir at ${OPENGL_INCLUDE_DIR}") message(STATUS "OpenGL: include dir at ${OPENGL_INCLUDE_DIR}")
message(STATUS "OpenGL: libraries at ${OPENGL_LIBRARIES}") message(STATUS "OpenGL: libraries at ${OPENGL_LIBRARIES}")
target_include_directories(monero-gui PUBLIC ${Qt5Gui_PRIVATE_INCLUDE_DIRS}) target_include_directories(monero-wallet-gui PUBLIC ${Qt5Gui_PRIVATE_INCLUDE_DIRS})
file(GLOB_RECURSE SRC_SOURCES *.cpp) file(GLOB_RECURSE SRC_SOURCES *.cpp)
file(GLOB_RECURSE SRC_HEADERS *.h) file(GLOB_RECURSE SRC_HEADERS *.h)
target_include_directories(monero-gui PUBLIC target_include_directories(monero-wallet-gui PUBLIC
${CMAKE_SOURCE_DIR}/monero/include ${CMAKE_SOURCE_DIR}/monero/include
${CMAKE_SOURCE_DIR}/monero/src ${CMAKE_SOURCE_DIR}/monero/src
${CMAKE_SOURCE_DIR}/monero/external/easylogging++
${CMAKE_SOURCE_DIR}/monero/contrib/epee/include
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/daemon ${CMAKE_CURRENT_SOURCE_DIR}/daemon
${CMAKE_CURRENT_SOURCE_DIR}/libwalletqt ${CMAKE_CURRENT_SOURCE_DIR}/libwalletqt
@@ -112,33 +132,24 @@ target_include_directories(monero-gui PUBLIC
${ZBAR_INCLUDE_DIR} ${ZBAR_INCLUDE_DIR}
) )
target_compile_definitions(monero-gui target_compile_definitions(monero-wallet-gui
PUBLIC PUBLIC
${Qt5Widgets_DEFINITIONS} ${Qt5Widgets_DEFINITIONS}
${Qt5Qml_DEFINITIONS} ${Qt5Qml_DEFINITIONS}
) )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
if(X11_FOUND) target_link_libraries(monero-wallet-gui
target_link_libraries(monero-gui ${X11_LIBRARIES} pthread dl Xt xcb X11) wallet_merged
endif()
if(DEVICE_TREZOR_READY)
target_link_libraries(monero-gui ${TREZOR_DEP_LIBS})
endif()
target_link_libraries(monero-gui
${CMAKE_BINARY_DIR}/lib/libwallet_merged.a
${LMDB_LIBRARY} ${LMDB_LIBRARY}
${CMAKE_BINARY_DIR}/monero/contrib/epee/src/libepee.a epee
${CMAKE_BINARY_DIR}/monero/external/unbound/libunbound.a ${UNBOUND_LIBRARY}
${SODIUM_LIBRARY} ${SODIUM_LIBRARY}
${CMAKE_BINARY_DIR}/monero/external/easylogging++/libeasylogging.a easylogging
${CMAKE_BINARY_DIR}/monero/src/blockchain_db/libblockchain_db.a blockchain_db
${CMAKE_BINARY_DIR}/monero/external/randomx/librandomx.a randomx
${CMAKE_BINARY_DIR}/monero/src/hardforks/libhardforks.a hardforks
${Boost_LIBRARIES} ${Boost_LIBRARIES}
${OPENSSL_LIBRARIES} ${OPENSSL_LIBRARIES}
${CMAKE_DL_LIBS} ${CMAKE_DL_LIBS}
@@ -147,10 +158,20 @@ target_link_libraries(monero-gui
${QT5_LIBRARIES} ${QT5_LIBRARIES}
${EXTRA_LIBRARIES} ${EXTRA_LIBRARIES}
${ICU_LIBRARIES} ${ICU_LIBRARIES}
openpgp
translations
) )
if(DEVICE_TREZOR_READY)
target_link_libraries(monero-wallet-gui ${TREZOR_DEP_LIBS})
endif()
if(X11_FOUND)
target_link_libraries(monero-wallet-gui ${X11_LIBRARIES})
endif()
if(WITH_SCANNER) if(WITH_SCANNER)
target_link_libraries(monero-gui target_link_libraries(monero-wallet-gui
${ZBAR_LIBRARIES} ${ZBAR_LIBRARIES}
jpeg jpeg
v4l2 v4l2
@@ -159,6 +180,6 @@ if(WITH_SCANNER)
) )
endif() endif()
install(TARGETS monero-gui install(TARGETS monero-wallet-gui
DESTINATION ${CMAKE_INSTALL_PREFIX} DESTINATION ${CMAKE_INSTALL_PREFIX}
) )

View File

@@ -40,7 +40,7 @@ QrCodeScanner::QrCodeScanner(QObject *parent)
m_probe = new QVideoProbe(this); m_probe = new QVideoProbe(this);
m_thread = new QrScanThread(this); m_thread = new QrScanThread(this);
m_thread->start(); m_thread->start();
QObject::connect(m_thread, SIGNAL(decoded(int,QString)), this, SLOT(processCode(int,QString))); QObject::connect(m_thread, SIGNAL(decoded(int, QString)), this, SIGNAL(decoded(int, QString)));
QObject::connect(m_thread, SIGNAL(notifyError(const QString &, bool)), this, SIGNAL(notifyError(const QString &, bool))); 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))); connect(m_probe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame)));
} }
@@ -48,37 +48,6 @@ void QrCodeScanner::setSource(QCamera *camera)
{ {
m_probe->setSource(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;
}
QVariantMap parsed_unknown_parameters;
if(unknown_parameters.size() > 0)
{
qDebug() << "unknown parameters " << unknown_parameters;
foreach(const QString &item, unknown_parameters )
{
QStringList parsed_item = item.split("=");
if(parsed_item.size() == 2) {
parsed_unknown_parameters.insert(parsed_item[0], parsed_item[1]);
}
}
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, parsed_unknown_parameters);
}
void QrCodeScanner::processFrame(QVideoFrame frame) void QrCodeScanner::processFrame(QVideoFrame frame)
{ {
if(frame.isValid()){ if(frame.isValid()){

View File

@@ -51,13 +51,12 @@ public:
void setEnabled(bool enabled); void setEnabled(bool enabled);
public Q_SLOTS: public Q_SLOTS:
void processCode(int type, const QString &data);
void processFrame(QVideoFrame); void processFrame(QVideoFrame);
Q_SIGNALS: Q_SIGNALS:
void enabledChanged(); void enabledChanged();
void decoded(const QString &address, const QString &payment_id, const QString &amount, const QString &tx_description, const QString &recipient_name, const QVariantMap &extra_parameters); void decoded(int type, const QString &data);
void decode(int type, const QString &data); void decode(int type, const QString &data);
void notifyError(const QString &error, bool warning = false); void notifyError(const QString &error, bool warning = false);

View File

@@ -30,13 +30,8 @@
#include <QtGlobal> #include <QtGlobal>
#include <QDebug> #include <QDebug>
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
extern QImage qt_imageFromVideoFrame(const QVideoFrame &f); 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 #endif
QrScanThread::QrScanThread(QObject *parent) QrScanThread::QrScanThread(QObject *parent)
@@ -80,7 +75,11 @@ bool QrScanThread::zimageFromQImage(const QImage &qimg, zbar::Image &dst)
unsigned int bpl( qimg.bytesPerLine() ), width( bpl / 4), height( qimg.height()); unsigned int bpl( qimg.bytesPerLine() ), width( bpl / 4), height( qimg.height());
dst.set_size(width, height); dst.set_size(width, height);
dst.set_format("BGR4"); dst.set_format("BGR4");
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
unsigned long datalen = qimg.sizeInBytes();
#else
unsigned long datalen = qimg.byteCount(); unsigned long datalen = qimg.byteCount();
#endif
dst.set_data(qimg.bits(), datalen); dst.set_data(qimg.bits(), datalen);
if((width * 4 != bpl) || (width * height * 4 > datalen)){ if((width * 4 != bpl) || (width * height * 4 > datalen)){
emit notifyError(QString("QImage to Zbar::Image failed !")); emit notifyError(QString("QImage to Zbar::Image failed !"));
@@ -104,7 +103,11 @@ void QrScanThread::processQImage(const QImage &qimg)
void QrScanThread::processVideoFrame(const QVideoFrame &frame) void QrScanThread::processVideoFrame(const QVideoFrame &frame)
{ {
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
processQImage( qt_imageFromVideoFrame(frame) ); processQImage( qt_imageFromVideoFrame(frame) );
#else
processQImage(frame.image());
#endif
} }
void QrScanThread::stop() void QrScanThread::stop()

View File

@@ -27,7 +27,9 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "DaemonManager.h" #include "DaemonManager.h"
#include <QElapsedTimer>
#include <QFile> #include <QFile>
#include <QMutexLocker>
#include <QThread> #include <QThread>
#include <QFileInfo> #include <QFileInfo>
#include <QDir> #include <QDir>
@@ -36,7 +38,6 @@
#include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrent>
#include <QApplication> #include <QApplication>
#include <QProcess> #include <QProcess>
#include <QTime>
#include <QStorageInfo> #include <QStorageInfo>
#include <QVariantMap> #include <QVariantMap>
#include <QVariant> #include <QVariant>
@@ -49,13 +50,15 @@ namespace {
DaemonManager * DaemonManager::m_instance = nullptr; DaemonManager * DaemonManager::m_instance = nullptr;
QStringList DaemonManager::m_clArgs; QStringList DaemonManager::m_clArgs;
DaemonManager *DaemonManager::instance(const QStringList *args) DaemonManager *DaemonManager::instance(const QStringList *args/* = nullptr*/)
{ {
if (!m_instance) { if (!m_instance) {
m_instance = new DaemonManager; m_instance = new DaemonManager;
// store command line arguments for later use // store command line arguments for later use
m_clArgs = *args; if (args != nullptr)
m_clArgs.removeFirst(); {
m_clArgs = *args;
}
} }
return m_instance; return m_instance;
@@ -63,6 +66,12 @@ DaemonManager *DaemonManager::instance(const QStringList *args)
bool DaemonManager::start(const QString &flags, NetworkType::Type nettype, const QString &dataDir, const QString &bootstrapNodeAddress, bool noSync /* = false*/) bool DaemonManager::start(const QString &flags, NetworkType::Type nettype, const QString &dataDir, const QString &bootstrapNodeAddress, bool noSync /* = false*/)
{ {
if (!QFileInfo(m_monerod).isFile())
{
emit daemonStartFailure("\"" + QDir::toNativeSeparators(m_monerod) + "\" " + tr("executable is missing"));
return false;
}
// prepare command line arguments and pass to monerod // prepare command line arguments and pass to monerod
QStringList arguments; QStringList arguments;
@@ -105,8 +114,8 @@ bool DaemonManager::start(const QString &flags, NetworkType::Type nettype, const
arguments << "--check-updates" << "disabled"; arguments << "--check-updates" << "disabled";
// --max-concurrency based on threads available. max: 6 // --max-concurrency based on threads available.
int32_t concurrency = qBound(1, QThread::idealThreadCount() / 2, 6); int32_t concurrency = qMax(1, QThread::idealThreadCount() / 2);
if(!flags.contains("--max-concurrency", Qt::CaseSensitive)){ if(!flags.contains("--max-concurrency", Qt::CaseSensitive)){
arguments << "--max-concurrency" << QString::number(concurrency); arguments << "--max-concurrency" << QString::number(concurrency);
@@ -115,22 +124,23 @@ bool DaemonManager::start(const QString &flags, NetworkType::Type nettype, const
qDebug() << "starting monerod " + m_monerod; qDebug() << "starting monerod " + m_monerod;
qDebug() << "With command line arguments " << arguments; qDebug() << "With command line arguments " << arguments;
m_daemon = new QProcess(); QMutexLocker locker(&m_daemonMutex);
initialized = true;
m_daemon.reset(new QProcess());
// Connect output slots // Connect output slots
connect (m_daemon, SIGNAL(readyReadStandardOutput()), this, SLOT(printOutput())); connect(m_daemon.get(), SIGNAL(readyReadStandardOutput()), this, SLOT(printOutput()));
connect (m_daemon, SIGNAL(readyReadStandardError()), this, SLOT(printError())); connect(m_daemon.get(), SIGNAL(readyReadStandardError()), this, SLOT(printError()));
// Start monerod // Start monerod
bool started = m_daemon->startDetached(m_monerod, arguments); bool started = m_daemon->startDetached(m_monerod, arguments);
// add state changed listener // add state changed listener
connect(m_daemon,SIGNAL(stateChanged(QProcess::ProcessState)),this,SLOT(stateChanged(QProcess::ProcessState))); connect(m_daemon.get(), SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(stateChanged(QProcess::ProcessState)));
if (!started) { if (!started) {
qDebug() << "Daemon start error: " + m_daemon->errorString(); qDebug() << "Daemon start error: " + m_daemon->errorString();
emit daemonStartFailure(); emit daemonStartFailure(m_daemon->errorString());
return false; return false;
} }
@@ -140,35 +150,33 @@ bool DaemonManager::start(const QString &flags, NetworkType::Type nettype, const
emit daemonStarted(); emit daemonStarted();
m_noSync = noSync; m_noSync = noSync;
} else { } else {
emit daemonStartFailure(); emit daemonStartFailure(tr("Timed out, local node is not responding after %1 seconds").arg(DAEMON_START_TIMEOUT_SECONDS));
} }
}); });
return true; return true;
} }
bool DaemonManager::stop(NetworkType::Type nettype) void DaemonManager::stopAsync(NetworkType::Type nettype, const QJSValue& callback)
{ {
QString message; const auto feature = m_scheduler.run([this, nettype] {
sendCommand({"exit"}, nettype, message); QString message;
qDebug() << message; sendCommand({"exit"}, nettype, message);
// Start stop watcher - Will kill if not shutting down return QJSValueList({stopWatcher(nettype)});
m_scheduler.run([this, nettype] { }, callback);
if (stopWatcher(nettype))
{
emit daemonStopped();
}
});
return true; if (!feature.first)
{
QJSValue(callback).call(QJSValueList({false}));
}
} }
bool DaemonManager::startWatcher(NetworkType::Type nettype) const bool DaemonManager::startWatcher(NetworkType::Type nettype) const
{ {
// Check if daemon is started every 2 seconds // Check if daemon is started every 2 seconds
QTime timer; QElapsedTimer timer;
timer.restart(); timer.start();
while(true && !m_app_exit && timer.elapsed() / 1000 < DAEMON_START_TIMEOUT_SECONDS ) { while(true && !m_app_exit && timer.elapsed() / 1000 < DAEMON_START_TIMEOUT_SECONDS ) {
QThread::sleep(2); QThread::sleep(2);
if(!running(nettype)) { if(!running(nettype)) {
@@ -194,9 +202,9 @@ bool DaemonManager::stopWatcher(NetworkType::Type nettype) const
if(counter >= 5) { if(counter >= 5) {
qDebug() << "Killing it! "; qDebug() << "Killing it! ";
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
QProcess::execute("taskkill /F /IM monerod.exe"); QProcess::execute("taskkill", {"/F", "/IM", "monerod.exe"});
#else #else
QProcess::execute("pkill monerod"); QProcess::execute("pkill", {"monerod"});
#endif #endif
} }
@@ -217,7 +225,10 @@ void DaemonManager::stateChanged(QProcess::ProcessState state)
void DaemonManager::printOutput() void DaemonManager::printOutput()
{ {
QByteArray byteArray = m_daemon->readAllStandardOutput(); QByteArray byteArray = [this]() {
QMutexLocker locker(&m_daemonMutex);
return m_daemon->readAllStandardOutput();
}();
QStringList strLines = QString(byteArray).split("\n"); QStringList strLines = QString(byteArray).split("\n");
foreach (QString line, strLines) { foreach (QString line, strLines) {
@@ -228,7 +239,10 @@ void DaemonManager::printOutput()
void DaemonManager::printError() void DaemonManager::printError()
{ {
QByteArray byteArray = m_daemon->readAllStandardError(); QByteArray byteArray = [this]() {
QMutexLocker locker(&m_daemonMutex);
return m_daemon->readAllStandardError();
}();
QStringList strLines = QString(byteArray).split("\n"); QStringList strLines = QString(byteArray).split("\n");
foreach (QString line, strLines) { foreach (QString line, strLines) {
@@ -345,7 +359,6 @@ DaemonManager::DaemonManager(QObject *parent)
if (m_monerod.length() == 0) { if (m_monerod.length() == 0) {
qCritical() << "no daemon binary defined for current platform"; qCritical() << "no daemon binary defined for current platform";
m_has_daemon = false;
} }
} }

View File

@@ -29,6 +29,9 @@
#ifndef DAEMONMANAGER_H #ifndef DAEMONMANAGER_H
#define DAEMONMANAGER_H #define DAEMONMANAGER_H
#include <memory>
#include <QMutex>
#include <QObject> #include <QObject>
#include <QUrl> #include <QUrl>
#include <QProcess> #include <QProcess>
@@ -42,10 +45,10 @@ class DaemonManager : public QObject
public: public:
static DaemonManager * instance(const QStringList *args); static DaemonManager * instance(const QStringList *args = nullptr);
Q_INVOKABLE bool start(const QString &flags, NetworkType::Type nettype, const QString &dataDir = "", const QString &bootstrapNodeAddress = "", bool noSync = false); Q_INVOKABLE bool start(const QString &flags, NetworkType::Type nettype, const QString &dataDir = "", const QString &bootstrapNodeAddress = "", bool noSync = false);
Q_INVOKABLE bool stop(NetworkType::Type nettype); Q_INVOKABLE void stopAsync(NetworkType::Type nettype, const QJSValue& callback);
Q_INVOKABLE bool noSync() const noexcept; Q_INVOKABLE bool noSync() const noexcept;
// return true if daemon process is started // return true if daemon process is started
@@ -64,7 +67,7 @@ private:
signals: signals:
void daemonStarted() const; void daemonStarted() const;
void daemonStopped() const; void daemonStopped() const;
void daemonStartFailure() const; void daemonStartFailure(const QString &error) const;
void daemonConsoleUpdated(QString message) const; void daemonConsoleUpdated(QString message) const;
public slots: public slots:
@@ -78,10 +81,9 @@ private:
static DaemonManager * m_instance; static DaemonManager * m_instance;
static QStringList m_clArgs; static QStringList m_clArgs;
QProcess *m_daemon; std::unique_ptr<QProcess> m_daemon;
bool initialized = false; QMutex m_daemonMutex;
QString m_monerod; QString m_monerod;
bool m_has_daemon = true;
bool m_app_exit = false; bool m_app_exit = false;
bool m_noSync = false; bool m_noSync = false;

View File

@@ -32,7 +32,6 @@
AddressBook::AddressBook(Monero::AddressBook *abImpl,QObject *parent) AddressBook::AddressBook(Monero::AddressBook *abImpl,QObject *parent)
: QObject(parent), m_addressBookImpl(abImpl) : QObject(parent), m_addressBookImpl(abImpl)
{ {
qDebug(__FUNCTION__);
getAll(); getAll();
} }
@@ -46,58 +45,97 @@ int AddressBook::errorCode() const
return m_addressBookImpl->errorCode(); return m_addressBookImpl->errorCode();
} }
QList<Monero::AddressBookRow*> AddressBook::getAll(bool update) const void AddressBook::getAll()
{ {
qDebug(__FUNCTION__);
emit refreshStarted(); emit refreshStarted();
if(update) {
m_rows.clear(); QWriteLocker locker(&m_lock);
if (m_rows.empty()){ m_addresses.clear();
m_rows.clear();
for (auto &abr: m_addressBookImpl->getAll()) { for (auto &abr: m_addressBookImpl->getAll()) {
m_addresses.insert(QString::fromStdString(abr->getAddress()), m_rows.size());
m_rows.append(abr); m_rows.append(abr);
} }
} }
emit refreshFinished(); emit refreshFinished();
return m_rows;
} }
Monero::AddressBookRow * AddressBook::getRow(int index) const bool AddressBook::getRow(int index, std::function<void (Monero::AddressBookRow &)> callback) const
{ {
return m_rows.at(index); QReadLocker locker(&m_lock);
if (index < 0 || index >= m_rows.size())
{
return false;
}
callback(*m_rows.value(index));
return true;
} }
bool AddressBook::addRow(const QString &address, const QString &payment_id, const QString &description) const bool AddressBook::addRow(const QString &address, const QString &payment_id, const QString &description)
{ {
// virtual bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) = 0; // virtual bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) = 0;
bool r = m_addressBookImpl->addRow(address.toStdString(), payment_id.toStdString(), description.toStdString()); bool result;
if(r) {
getAll(true); QWriteLocker locker(&m_lock);
return r; result = m_addressBookImpl->addRow(address.toStdString(), payment_id.toStdString(), description.toStdString());
}
if (result)
{
getAll();
}
return result;
} }
bool AddressBook::deleteRow(int rowId) const bool AddressBook::deleteRow(int rowId)
{ {
bool r = m_addressBookImpl->deleteRow(rowId); bool result;
{
QWriteLocker locker(&m_lock);
result = m_addressBookImpl->deleteRow(rowId);
}
// Fetch new data from wallet2. // Fetch new data from wallet2.
getAll(true); if (result)
{
getAll();
}
return r; return result;
} }
quint64 AddressBook::count() const quint64 AddressBook::count() const
{ {
QReadLocker locker(&m_lock);
return m_rows.size(); return m_rows.size();
} }
int AddressBook::lookupPaymentID(const QString &payment_id) const int AddressBook::lookupPaymentID(const QString &payment_id) const
{ {
QReadLocker locker(&m_lock);
return m_addressBookImpl->lookupPaymentID(payment_id.toStdString()); return m_addressBookImpl->lookupPaymentID(payment_id.toStdString());
} }
QString AddressBook::getDescription(const QString &address) const
{
QReadLocker locker(&m_lock);
const QMap<QString, size_t>::const_iterator it = m_addresses.find(address);
if (it == m_addresses.end())
{
return {};
}
return QString::fromStdString(m_rows.value(*it)->getDescription());
}

View File

@@ -30,12 +30,14 @@
#define ADDRESSBOOK_H #define ADDRESSBOOK_H
#include <wallet/api/wallet2_api.h> #include <wallet/api/wallet2_api.h>
#include <QMap>
#include <QObject> #include <QObject>
#include <QReadWriteLock>
#include <QList> #include <QList>
#include <QDateTime> #include <QDateTime>
namespace Monero { namespace Monero {
class AddressBook; struct AddressBook;
} }
class AddressBookRow; class AddressBookRow;
@@ -43,14 +45,14 @@ class AddressBook : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
Q_INVOKABLE QList<Monero::AddressBookRow*> getAll(bool update = false) const; Q_INVOKABLE bool getRow(int index, std::function<void (Monero::AddressBookRow &)> callback) const;
Q_INVOKABLE Monero::AddressBookRow * getRow(int index) const; Q_INVOKABLE bool addRow(const QString &address, const QString &payment_id, const QString &description);
Q_INVOKABLE bool addRow(const QString &address, const QString &payment_id, const QString &description) const; Q_INVOKABLE bool deleteRow(int rowId);
Q_INVOKABLE bool deleteRow(int rowId) const;
quint64 count() const; quint64 count() const;
Q_INVOKABLE QString errorString() const; Q_INVOKABLE QString errorString() const;
Q_INVOKABLE int errorCode() const; Q_INVOKABLE int errorCode() const;
Q_INVOKABLE int lookupPaymentID(const QString &payment_id) const; Q_INVOKABLE int lookupPaymentID(const QString &payment_id) const;
Q_INVOKABLE QString getDescription(const QString &address) const;
enum ErrorCode { enum ErrorCode {
Status_Ok, Status_Ok,
@@ -61,6 +63,8 @@ public:
Q_ENUM(ErrorCode); Q_ENUM(ErrorCode);
private:
void getAll();
signals: signals:
void refreshStarted() const; void refreshStarted() const;
@@ -73,7 +77,9 @@ private:
explicit AddressBook(Monero::AddressBook * abImpl, QObject *parent); explicit AddressBook(Monero::AddressBook * abImpl, QObject *parent);
friend class Wallet; friend class Wallet;
Monero::AddressBook * m_addressBookImpl; Monero::AddressBook * m_addressBookImpl;
mutable QList<Monero::AddressBookRow*> m_rows; mutable QReadWriteLock m_lock;
QList<Monero::AddressBookRow*> m_rows;
QMap<QString, size_t> m_addresses;
}; };
#endif // ADDRESSBOOK_H #endif // ADDRESSBOOK_H

View File

@@ -0,0 +1,70 @@
// Copyright (c) 2014-2020, 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 "PassphraseHelper.h"
#include <QMutexLocker>
#include <QDebug>
Monero::optional<std::string> PassphraseHelper::onDevicePassphraseRequest(bool & on_device)
{
qDebug() << __FUNCTION__;
QMutexLocker locker(&m_mutex_pass);
m_passphrase_on_device = true;
m_passphrase_abort = false;
if (m_prompter != nullptr){
m_prompter->onWalletPassphraseNeeded(on_device);
}
m_cond_pass.wait(&m_mutex_pass);
if (m_passphrase_abort)
{
throw std::runtime_error("Passphrase entry abort");
}
on_device = m_passphrase_on_device;
if (!on_device) {
auto tmpPass = m_passphrase.toStdString();
m_passphrase = QString();
return Monero::optional<std::string>(tmpPass);
} else {
return Monero::optional<std::string>();
}
}
void PassphraseHelper::onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort)
{
qDebug() << __FUNCTION__;
QMutexLocker locker(&m_mutex_pass);
m_passphrase = passphrase;
m_passphrase_abort = entry_abort;
m_passphrase_on_device = enter_on_device;
m_cond_pass.wakeAll();
}

View File

@@ -0,0 +1,74 @@
// Copyright (c) 2014-2020, 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 MONERO_GUI_PASSPHRASEHELPER_H
#define MONERO_GUI_PASSPHRASEHELPER_H
#include <QtGlobal>
#include <wallet/api/wallet2_api.h>
#include <QMutex>
#include <QPointer>
#include <QWaitCondition>
#include <QMutex>
/**
* Implements component responsible for showing entry prompt to the user,
* typically Wallet / Wallet manager.
*/
class PassprasePrompter {
public:
virtual void onWalletPassphraseNeeded(bool onDevice) = 0;
};
/**
* Implements receiver of the passphrase responsible for passing it back to the wallet,
* typically wallet listener.
*/
class PassphraseReceiver {
public:
virtual void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort) = 0;
};
class PassphraseHelper {
public:
PassphraseHelper(PassprasePrompter * prompter=nullptr): m_prompter(prompter) {};
PassphraseHelper(const PassphraseHelper & h): PassphraseHelper(h.m_prompter) {};
Monero::optional<std::string> onDevicePassphraseRequest(bool & on_device);
void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort);
private:
PassprasePrompter * m_prompter;
QWaitCondition m_cond_pass;
QMutex m_mutex_pass;
QString m_passphrase;
bool m_passphrase_abort;
bool m_passphrase_on_device;
};
#endif //MONERO_GUI_PASSPHRASEHELPER_H

View File

@@ -32,14 +32,11 @@
Subaddress::Subaddress(Monero::Subaddress *subaddressImpl, QObject *parent) Subaddress::Subaddress(Monero::Subaddress *subaddressImpl, QObject *parent)
: QObject(parent), m_subaddressImpl(subaddressImpl) : QObject(parent), m_subaddressImpl(subaddressImpl)
{ {
qDebug(__FUNCTION__);
getAll(); getAll();
} }
void Subaddress::getAll() const void Subaddress::getAll() const
{ {
qDebug(__FUNCTION__);
emit refreshStarted(); emit refreshStarted();
{ {

View File

@@ -32,14 +32,11 @@
SubaddressAccount::SubaddressAccount(Monero::SubaddressAccount *subaddressAccountImpl, QObject *parent) SubaddressAccount::SubaddressAccount(Monero::SubaddressAccount *subaddressAccountImpl, QObject *parent)
: QObject(parent), m_subaddressAccountImpl(subaddressAccountImpl) : QObject(parent), m_subaddressAccountImpl(subaddressAccountImpl)
{ {
qDebug(__FUNCTION__);
getAll(); getAll();
} }
void SubaddressAccount::getAll() const void SubaddressAccount::getAll() const
{ {
qDebug(__FUNCTION__);
emit refreshStarted(); emit refreshStarted();
{ {

View File

@@ -34,6 +34,7 @@
#include <QDebug> #include <QDebug>
#include <QReadLocker> #include <QReadLocker>
#include <QWriteLocker> #include <QWriteLocker>
#include <QtGlobal>
bool TransactionHistory::transaction(int index, std::function<void (TransactionInfo &)> callback) bool TransactionHistory::transaction(int index, std::function<void (TransactionInfo &)> callback)
@@ -58,7 +59,11 @@ bool TransactionHistory::transaction(int index, std::function<void (TransactionI
void TransactionHistory::refresh(quint32 accountIndex) void TransactionHistory::refresh(quint32 accountIndex)
{ {
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
QDateTime firstDateTime = QDate(2014, 4, 18).startOfDay();
#else
QDateTime firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block QDateTime firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block
#endif
QDateTime lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones) QDateTime lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
emit refreshStarted(); emit refreshStarted();
@@ -143,7 +148,11 @@ bool TransactionHistory::TransactionHistory::locked() const
TransactionHistory::TransactionHistory(Monero::TransactionHistory *pimpl, QObject *parent) TransactionHistory::TransactionHistory(Monero::TransactionHistory *pimpl, QObject *parent)
: QObject(parent), m_pimpl(pimpl), m_minutesToUnlock(0), m_locked(false) : QObject(parent), m_pimpl(pimpl), m_minutesToUnlock(0), m_locked(false)
{ {
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
m_firstDateTime = QDate(2014, 4, 18).startOfDay();
#else
m_firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block m_firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block
#endif
m_lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones) m_lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
} }

View File

@@ -37,7 +37,7 @@
#include <QDateTime> #include <QDateTime>
namespace Monero { namespace Monero {
class TransactionHistory; struct TransactionHistory;
} }
class TransactionInfo; class TransactionInfo;

View File

@@ -61,14 +61,14 @@ quint64 TransactionInfo::atomicAmount() const
QString TransactionInfo::displayAmount() const QString TransactionInfo::displayAmount() const
{ {
return WalletManager::instance()->displayAmount(m_amount); return WalletManager::displayAmount(m_amount);
} }
QString TransactionInfo::fee() const QString TransactionInfo::fee() const
{ {
if(m_fee == 0) if(m_fee == 0)
return ""; return "";
return WalletManager::instance()->displayAmount(m_fee); return WalletManager::displayAmount(m_fee);
} }
quint64 TransactionInfo::blockHeight() const quint64 TransactionInfo::blockHeight() const
@@ -132,7 +132,7 @@ QString TransactionInfo::destinations_formatted() const
for (auto const& t: m_transfers) { for (auto const& t: m_transfers) {
if (!destinations.isEmpty()) if (!destinations.isEmpty())
destinations += "<br> "; destinations += "<br> ";
destinations += WalletManager::instance()->displayAmount(t->amount()) + ": " + t->address(); destinations += WalletManager::displayAmount(t->amount()) + ": " + t->address();
} }
return destinations; return destinations;
} }

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