Browse Source

Merge pull request #28 from MyHush/dev

Release v1.1.0
pull/78/head
Denio 5 years ago
committed by GitHub
parent
commit
9bdbb187bd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 24
      .travis.yml
  2. 8
      README.md
  3. 4
      application.qrc
  4. 6
      lib/Cargo.lock
  5. 2
      lib/Cargo.toml
  6. 9
      lib/src/lib.rs
  7. 4
      res/Info.plist
  8. BIN
      res/zec_qt_wallet_de.qm
  9. 516
      res/zec_qt_wallet_de.ts
  10. 514
      res/zec_qt_wallet_es.ts
  11. BIN
      res/zec_qt_wallet_fr.qm
  12. 522
      res/zec_qt_wallet_fr.ts
  13. BIN
      res/zec_qt_wallet_it.qm
  14. 522
      res/zec_qt_wallet_it.ts
  15. BIN
      res/zec_qt_wallet_pt.qm
  16. 522
      res/zec_qt_wallet_pt.ts
  17. BIN
      res/zec_qt_wallet_tr.qm
  18. 518
      res/zec_qt_wallet_tr.ts
  19. BIN
      res/zec_qt_wallet_zh.qm
  20. 518
      res/zec_qt_wallet_zh.ts
  21. 1
      silentdragon-lite.pro
  22. 27
      src/about.ui
  23. 145
      src/camount.cpp
  24. 21
      src/camount.h
  25. 6
      src/connection.cpp
  26. 6
      src/connection.h
  27. 2
      src/connection.ui
  28. 279
      src/controller.cpp
  29. 14
      src/controller.h
  30. 2
      src/createhushconfdialog.ui
  31. 16
      src/liteinterface.cpp
  32. 4
      src/liteinterface.h
  33. 2
      src/main.cpp
  34. 125
      src/mainwindow.cpp
  35. 3
      src/mainwindow.h
  36. 28
      src/mainwindow.ui
  37. 77
      src/recurring.cpp
  38. 55
      src/requestdialog.cpp
  39. 27
      src/scripts/dounifiedbuild.ps1
  40. 12
      src/scripts/mkmacdmg.sh
  41. 13
      src/scripts/mkwininstaller.ps1
  42. 2
      src/scripts/signbinaries.sh
  43. 17
      src/scripts/zec-qt-wallet.wxs
  44. 190
      src/sendtab.cpp
  45. 47
      src/settings.cpp
  46. 47
      src/settings.h
  47. 363
      src/settings.ui
  48. 43
      src/txtablemodel.cpp
  49. 2
      src/version.h
  50. 2
      src/websockets.cpp

24
.travis.yml

@ -1,27 +1,43 @@
language: rust
matrix:
include:
# works on Precise and Trusty
- os: linux
- dist: xenial
compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.7']
packages: ['clang-3.7', 'g++-8']
packages: ['clang-3.7', 'g++-5']
before_script:
- export PATH="$PATH:$HOME/.cargo/bin"
before_install:
- gem install bundler
- curl -sSL https://sh.rustup.rs | sh -s -- -y --default-toolchain=nightly --profile=minimal
- export PATH="$PATH:$HOME/.cargo/bin"
- sudo add-apt-repository ppa:beineri/opt-qt591-xenial -y
- sudo apt-get update -qq
- sudo apt-get install qt59base qt59websockets libgl1-mesa-dev
- source /opt/qt59/bin/qt59-env.sh
script:
- qmake -v
- clang++ -v
- g++-8 -v
- g++-5 -v
- qmake silentdragon-lite.pro CONFIG+=release -spec linux-clang
- make CC=clang CXX=clang++ -j2
- make distclean
- qmake silentdragon-lite.pro CONFIG+=release -spec linux-g++
- res/libsodium/buildlibsodium.sh
- make CC=gcc-8 CXX=g++-8 -j2
- make CC=gcc-5 CXX=g++-5 -j2

8
README.md

@ -18,6 +18,14 @@ This means your IP address is known to these servers. Enable Tor setting in Sile
Go to the releases page and grab the latest installers or binary. https://github.com/MyHush/SilentDragonLite/releases
### Note Management
SilentDragonLite does automatic note and utxo management, which means it doesn't allow you to manually select which address to send outgoing transactions from. It follows these principles:
* Defaults to sending shielded transactions, even if you're sending to a transparent address
* Sapling funds need at least 2 confirmations before they can be spent
* Can select funds from multiple shielded addresses in the same transaction
* Will automatically shield your transparent funds at the first opportunity
* When sending an outgoing transaction to a shielded address, SilentDragonLite can decide to use the transaction to additionally shield your transparent funds (i.e., send your transparent funds to your own shielded address in the same transaction)
## Compiling from source
* SilentDragonLite is written in C++ 14, and can be compiled with g++/clang++/visual c++.
* It also depends on Qt5, which you can get from [here](https://www.qt.io/download).

4
application.qrc

@ -14,6 +14,10 @@
</qresource>
<qresource prefix="/translations">
<file>res/zec_qt_wallet_de.qm</file>
<file>res/zec_qt_wallet_es.qm</file>
<file>res/zec_qt_wallet_fr.qm</file>
<file>res/zec_qt_wallet_pt.qm</file>
<file>res/zec_qt_wallet_it.qm</file>
</qresource>
<qresource prefix="/css">
<file>res/css/blue.css</file>

6
lib/Cargo.lock

@ -1051,7 +1051,7 @@ version = "0.1.0"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"silentdragonlitelib 0.1.0 (git+https://github.com/MyHush/silentdragonlite-cli?rev=099ad194dac6ee51474b3637d357aca0665a8181)",
"silentdragonlitelib 0.1.0 (git+https://github.com/MyHush/silentdragonlite-cli?rev=ce987b373505c19784f6482fd900fa1bb988cbce)",
]
[[package]]
@ -1467,7 +1467,7 @@ dependencies = [
[[package]]
name = "silentdragonlitelib"
version = "0.1.0"
source = "git+https://github.com/MyHush/silentdragonlite-cli?rev=099ad194dac6ee51474b3637d357aca0665a8181#099ad194dac6ee51474b3637d357aca0665a8181"
source = "git+https://github.com/MyHush/silentdragonlite-cli?rev=ce987b373505c19784f6482fd900fa1bb988cbce#ce987b373505c19784f6482fd900fa1bb988cbce"
dependencies = [
"base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bellman 0.1.0 (git+https://github.com/DenioD/librustzcash.git?rev=caaee693c47c2ee9ecd1e1546b8fe3c714f342bc)",
@ -2481,7 +2481,7 @@ dependencies = [
"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
"checksum silentdragonlitelib 0.1.0 (git+https://github.com/MyHush/silentdragonlite-cli?rev=099ad194dac6ee51474b3637d357aca0665a8181)" = "<none>"
"checksum silentdragonlitelib 0.1.0 (git+https://github.com/MyHush/silentdragonlite-cli?rev=ce987b373505c19784f6482fd900fa1bb988cbce)" = "<none>"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
"checksum sodiumoxide 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585232e78a4fc18133eef9946d3080befdf68b906c51b621531c37e91787fa2b"

2
lib/Cargo.toml

@ -11,4 +11,4 @@ crate-type = ["staticlib"]
[dependencies]
libc = "0.2.58"
lazy_static = "1.4.0"
silentdragonlitelib = { git = "https://github.com/MyHush/silentdragonlite-cli", rev = "099ad194dac6ee51474b3637d357aca0665a8181" }
silentdragonlitelib = { git = "https://github.com/MyHush/silentdragonlite-cli", rev = "ce987b373505c19784f6482fd900fa1bb988cbce" }

9
lib/src/lib.rs

@ -57,6 +57,9 @@ pub extern fn litelib_initialize_new(dangerous: bool, server: *const c_char) ->
}
};
// Initialize logging
let _ = lightclient.init_logging();
let seed = match lightclient.do_seed_phrase() {
Ok(s) => s.dump(),
Err(e) => {
@ -105,6 +108,9 @@ pub extern fn litelib_initialize_new_from_phrase(dangerous: bool, server: *const
}
};
// Initialize logging
let _ = lightclient.init_logging();
LIGHTCLIENT.lock().unwrap().replace(Some(Arc::new(lightclient)));
let c_str = CString::new("OK").unwrap();
@ -137,6 +143,9 @@ pub extern fn litelib_initialize_existing(dangerous: bool, server: *const c_char
}
};
// Initialize logging
let _ = lightclient.init_logging();
LIGHTCLIENT.lock().unwrap().replace(Some(Arc::new(lightclient)));
let c_str = CString::new("OK").unwrap();

4
res/Info.plist

@ -9,7 +9,7 @@
<key>CFBundleIconFile</key>
<string>logo.icns</string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.silentdragon</string>
<string>com.yourcompany.SilentDragonLite</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
@ -39,4 +39,4 @@
<key>NSUIElement</key>
<true/>
</dict>
</plist>
</plist>

BIN
res/zec_qt_wallet_de.qm

Binary file not shown.

516
res/zec_qt_wallet_de.ts

File diff suppressed because it is too large

514
res/zec_qt_wallet_es.ts

File diff suppressed because it is too large

BIN
res/zec_qt_wallet_fr.qm

Binary file not shown.

522
res/zec_qt_wallet_fr.ts

File diff suppressed because it is too large

BIN
res/zec_qt_wallet_it.qm

Binary file not shown.

522
res/zec_qt_wallet_it.ts

File diff suppressed because it is too large

BIN
res/zec_qt_wallet_pt.qm

Binary file not shown.

522
res/zec_qt_wallet_pt.ts

File diff suppressed because it is too large

BIN
res/zec_qt_wallet_tr.qm

Binary file not shown.

518
res/zec_qt_wallet_tr.ts

File diff suppressed because it is too large

BIN
res/zec_qt_wallet_zh.qm

Binary file not shown.

518
res/zec_qt_wallet_zh.ts

File diff suppressed because it is too large

1
silentdragon-lite.pro

@ -124,7 +124,6 @@ TRANSLATIONS = res/zec_qt_wallet_es.ts \
res/zec_qt_wallet_zh.ts \
res/zec_qt_wallet_tr.ts
include(singleapplication/singleapplication.pri)
DEFINES += QAPPLICATION_CLASS=QApplication

27
src/about.ui

@ -17,7 +17,7 @@
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string notr="true">SilentDragon Lite</string>
<string notr="true">SilentDragonLite</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
@ -41,7 +41,7 @@
<x>0</x>
<y>0</y>
<width>463</width>
<height>534</height>
<height>551</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
@ -52,17 +52,18 @@
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Copyright (c) 2018-2019 DenioD (MIT License)&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Special thanks to:&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Aditya Kulkarni for the awesome open source code&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;JSON for Modern C++ : &lt;a href=&quot;https://nlohmann.github.io/json/&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;https://nlohmann.github.io/json/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;QR Code generator library Nayuki : &lt;a href=&quot;https://www.nayuki.io/page/qr-code-generator-library&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;https://www.nayuki.io/page/qr-code-ge…&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Made with QT : &lt;a href=&quot;https://www.qt.io/&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;https://www.qt.io/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;LICENSE:&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &amp;quot;Software&amp;quot;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:&lt;/p&gt;
&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.&lt;/li&gt;
&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The Software is provided &amp;quot;as is&amp;quot;, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software.&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu';&quot;&gt;Copyright (c) 2019-2020 DenioD (MIT License)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu';&quot;&gt;Copyright (c) 2018-2019 Aditya Kulkarni (MIT License)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu';&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu';&quot;&gt;Special thanks to:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu';&quot;&gt;Aditya Kulkarni for the awesome open source code&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu';&quot;&gt;JSON for Modern C++ : &lt;/span&gt;&lt;a href=&quot;https://nlohmann.github.io/json/&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;https://nlohmann.github.io/json/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu';&quot;&gt;QR Code generator library Nayuki : &lt;/span&gt;&lt;a href=&quot;https://www.nayuki.io/page/qr-code-generator-library&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;https://www.nayuki.io/page/qr-code-ge…&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu';&quot;&gt;Made with QT : &lt;/span&gt;&lt;a href=&quot;https://www.qt.io/&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;https://www.qt.io/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu';&quot;&gt;LICENSE:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu';&quot;&gt;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &amp;quot;Software&amp;quot;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; font-family:'Ubuntu';&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.&lt;/li&gt;
&lt;li style=&quot; font-family:'Ubuntu';&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The Software is provided &amp;quot;as is&amp;quot;, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software.&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>

145
src/camount.cpp

@ -37,7 +37,68 @@ QString CAmount::toDecimalUSDString() const {
double dblAmount = static_cast<double>(this->amount) / COIN;
double price = Settings::getInstance()->getZECPrice();
return "$" + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
return "$ " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
}
QString CAmount::toDecimalEURString() const {
double dblAmount = static_cast<double>(this->amount) / COIN;
double price = Settings::getInstance()->getEURPrice();
return QLocale(QLocale::English).toString(dblAmount*price, 'f', 2) + "";
}
QString CAmount::toDecimalBTCString() const {
double dblAmount = static_cast<double>(this->amount) / COIN;
double price = Settings::getInstance()->getBTCPrice();
return "BTC " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 9);
}
QString CAmount::toDecimalCNYString() const {
double dblAmount = static_cast<double>(this->amount) / COIN;
double price = Settings::getInstance()->getCNYPrice();
return "¥ /元 " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
}
QString CAmount::toDecimalRUBString() const {
double dblAmount = static_cast<double>(this->amount) / COIN;
double price = Settings::getInstance()->getRUBPrice();
return "" + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
}
QString CAmount::toDecimalCADString() const {
double dblAmount = static_cast<double>(this->amount) / COIN;
double price = Settings::getInstance()->getCADPrice();
return "$ " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
}
QString CAmount::toDecimalSGDString() const {
double dblAmount = static_cast<double>(this->amount) / COIN;
double price = Settings::getInstance()->getSGDPrice();
return "$ " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
}
QString CAmount::toDecimalCHFString() const {
double dblAmount = static_cast<double>(this->amount) / COIN;
double price = Settings::getInstance()->getCHFPrice();
return "CHF " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
}
QString CAmount::toDecimalINRString() const {
double dblAmount = static_cast<double>(this->amount) / COIN;
double price = Settings::getInstance()->getINRPrice();
return "" + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
}
QString CAmount::toDecimalGBPString() const {
double dblAmount = static_cast<double>(this->amount) / COIN;
double price = Settings::getInstance()->getGBPPrice();
return "£ " + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
}
QString CAmount::toDecimalAUDString() const {
double dblAmount = static_cast<double>(this->amount) / COIN;
double price = Settings::getInstance()->getAUDPrice();
return " $" + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
}
QString CAmount::toDecimalhushString() const {
@ -52,6 +113,88 @@ QString CAmount::toDecimalhushUSDString() const {
return this->toDecimalhushString();
}
QString CAmount::toDecimalhushEURString() const {
auto eurString = this->toDecimalEURString();
if (!eurString.isEmpty())
return this->toDecimalhushString() % " (" % eurString % ")";
else
return this->toDecimalhushString();
}
QString CAmount::toDecimalhushBTCString() const {
auto btcString = this->toDecimalBTCString();
if (!btcString.isEmpty())
return this->toDecimalhushString() % " (" % btcString % ")";
else
return this->toDecimalhushString();
}
QString CAmount::toDecimalhushCNYString() const {
auto cnyString = this->toDecimalCNYString();
if (!cnyString.isEmpty())
return this->toDecimalhushString() % " (" % cnyString % ")";
else
return this->toDecimalhushString();
}
QString CAmount::toDecimalhushRUBString() const {
auto rubString = this->toDecimalRUBString();
if (!rubString.isEmpty())
return this->toDecimalhushString() % " (" % rubString % ")";
else
return this->toDecimalhushString();
}
QString CAmount::toDecimalhushCADString() const {
auto cadString = this->toDecimalCADString();
if (!cadString.isEmpty())
return this->toDecimalhushString() % " (" % cadString % ")";
else
return this->toDecimalhushString();
}
QString CAmount::toDecimalhushSGDString() const {
auto sgdString = this->toDecimalSGDString();
if (!sgdString.isEmpty())
return this->toDecimalhushString() % " (" % sgdString % ")";
else
return this->toDecimalhushString();
}
QString CAmount::toDecimalhushCHFString() const {
auto chfString = this->toDecimalCHFString();
if (!chfString.isEmpty())
return this->toDecimalhushString() % " (" % chfString % ")";
else
return this->toDecimalhushString();
}
QString CAmount::toDecimalhushINRString() const {
auto inrString = this->toDecimalINRString();
if (!inrString.isEmpty())
return this->toDecimalhushString() % " (" % inrString % ")";
else
return this->toDecimalhushString();
}
QString CAmount::toDecimalhushGBPString() const {
auto gbpString = this->toDecimalGBPString();
if (!gbpString.isEmpty())
return this->toDecimalhushString() % " (" % gbpString % ")";
else
return this->toDecimalhushString();
}
QString CAmount::toDecimalhushAUDString() const {
auto audString = this->toDecimalAUDString();
if (!audString.isEmpty())
return this->toDecimalhushString() % " (" % audString % ")";
else
return this->toDecimalhushString();
}
CAmount CAmount::fromDecimalString(QString decimalString) {
auto amtParts = decimalString.split(".");
qint64 r = amtParts[0].toULongLong() * COIN;

21
src/camount.h

@ -27,8 +27,29 @@ public:
double toDecimalDouble() const;
QString toDecimalString() const;
QString toDecimalUSDString() const;
QString toDecimalEURString() const;
QString toDecimalBTCString() const;
QString toDecimalCNYString() const;
QString toDecimalRUBString() const;
QString toDecimalCADString() const;
QString toDecimalSGDString() const;
QString toDecimalCHFString() const;
QString toDecimalINRString() const;
QString toDecimalGBPString() const;
QString toDecimalAUDString() const;
QString toDecimalhushString() const;
QString toDecimalhushUSDString() const;
QString toDecimalhushEURString() const;
QString toDecimalhushBTCString() const;
QString toDecimalhushCNYString() const;
QString toDecimalhushRUBString() const;
QString toDecimalhushCADString() const;
QString toDecimalhushSGDString() const;
QString toDecimalhushCHFString() const;
QString toDecimalhushINRString() const;
QString toDecimalhushGBPString() const;
QString toDecimalhushAUDString() const;
qint64 toqint64() const { return amount; };
CAmount operator+ (const CAmount& other) const {

6
src/connection.cpp

@ -49,7 +49,7 @@ void ConnectionLoader::doAutoConnect() {
main->logger->write(QObject::tr("Attempting to initialize library with ") + config->server);
// Check to see if there's an existing wallet
if (litelib_wallet_exists(Settings::getChainName().toStdString().c_str())) {
if (litelib_wallet_exists(Settings::getDefaultChainName().toStdString().c_str())) {
main->logger->write(QObject::tr("Using existing wallet."));
char* resp = litelib_initialize_existing(config->dangerous, config->server.toStdString().c_str());
QString response = litelib_process_response(resp);
@ -68,9 +68,10 @@ void ConnectionLoader::doAutoConnect() {
auto me = this;
// After the lib is initialized, try to do get info
connection->doRPC("info", "", [=](auto) {
connection->doRPC("info", "", [=](auto reply) {
// If success, set the connection
main->logger->write("Connection is online.");
connection->setInfo(reply);
isSyncing = new QAtomicInteger<bool>();
isSyncing->store(true);
@ -138,7 +139,6 @@ Connection* ConnectionLoader::makeConnection(std::shared_ptr<ConnectionConfig> c
// Update the UI with the status
void ConnectionLoader::showInformation(QString info, QString detail) {
qDebug() << "Showing info " << info << ":" << detail;
connD->status->setText(info);
connD->statusDetail->setText(detail);

6
src/connection.h

@ -123,8 +123,12 @@ public:
void showTxError(const QString& error);
json getInfo() { return serverInfo; }
void setInfo(const json& info) { serverInfo = info; }
private:
bool shutdownInProgress = false;
bool shutdownInProgress = false;
json serverInfo;
};
#endif

2
src/connection.ui

@ -14,7 +14,7 @@
</rect>
</property>
<property name="windowTitle">
<string>silentdragon</string>
<string>SilentDragonLite</string>
</property>
<property name="modal">
<bool>true</bool>

279
src/controller.cpp

@ -28,10 +28,11 @@ Controller::Controller(MainWindow* main) {
// Set up timer to refresh Price
priceTimer = new QTimer(main);
QObject::connect(priceTimer, &QTimer::timeout, [=]() {
if (Settings::getInstance()->getAllowFetchPrices())
refreshZECPrice();
if (Settings::getInstance()->getAllowFetchPrices())
refreshZECPrice();
});
priceTimer->start(Settings::priceRefreshSpeed); // Every hour
priceTimer->start(Settings::priceRefreshSpeed); // Every 5 Min
// Set up a timer to refresh the UI every few seconds
timer = new QTimer(main);
@ -58,7 +59,6 @@ Controller::~Controller() {
delete zrpc;
}
// Called when a connection to hushd is available.
void Controller::setConnection(Connection* c) {
if (c == nullptr) return;
@ -80,7 +80,6 @@ void Controller::setConnection(Connection* c) {
refresh(true);
}
// Build the RPC JSON Parameters for this tx
void Controller::fillTxJsonParams(json& allRecepients, Tx tx) {
Q_ASSERT(allRecepients.is_array());
@ -100,7 +99,6 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) {
}
}
void Controller::noConnection() {
QIcon i = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical);
main->statusIcon->setPixmap(i.pixmap(16, 16));
@ -137,49 +135,77 @@ void Controller::refresh(bool force) {
getInfoThenRefresh(force);
}
void Controller::processInfo(const json& info) {
// Testnet?
QString chainName;
if (!info["chain_name"].is_null()) {
chainName = QString::fromStdString(info["chain_name"].get<json::string_t>());
Settings::getInstance()->setTestnet(chainName == "test");
};
QString version = QString::fromStdString(info["version"].get<json::string_t>());
Settings::getInstance()->sethushdVersion(version);
// Recurring pamynets are testnet only
if (!Settings::getInstance()->isTestnet())
main->disableRecurring();
}
void Controller::getInfoThenRefresh(bool force) {
if (!zrpc->haveConnection())
return noConnection();
static bool prevCallSucceeded = false;
zrpc->fetchInfo([=] (const json& reply) {
prevCallSucceeded = true;
// Testnet?
QString chainName;
if (!reply["chain_name"].is_null()) {
chainName = QString::fromStdString(reply["chain_name"].get<json::string_t>());
Settings::getInstance()->setTestnet(chainName == "test");
};
zrpc->fetchLatestBlock([=] (const json& reply) {
prevCallSucceeded = true;
// Recurring pamynets are testnet only
if (!Settings::getInstance()->isTestnet())
main->disableRecurring();
int curBlock = reply["latest_block_height"].get<json::number_integer_t>();
int curBlock = reply["height"].get<json::number_integer_t>();
bool doUpdate = force || (model->getLatestBlock() != curBlock);
model->setLatestBlock(curBlock);
ui->blockHeight->setText(QString::number(curBlock));
main->logger->write(QString("Refresh. curblock ") % QString::number(curBlock) % ", update=" % (doUpdate ? "true" : "false") );
// Connected, so display checkmark.
auto tooltip = Settings::getInstance()->getSettings().server + "\n" + QString::fromStdString(reply.dump());
auto tooltip = Settings::getInstance()->getSettings().server + "\n" +
QString::fromStdString(zrpc->getConnection()->getInfo().dump());
QIcon i(":/icons/res/connected.gif");
QString chainName = Settings::getInstance()->isTestnet() ? "test" : "main";
main->statusLabel->setText(chainName + "(" + QString::number(curBlock) + ")");
main->statusLabel->setText(" HUSH/USD=$" + QString::number( (double) Settings::getInstance()->getZECPrice() ));
// use currency ComboBox as input
if (Settings::getInstance()->get_currency_name() == "USD") {
main->statusLabel->setText(" HUSH/USD=$ " + QString::number( (double) Settings::getInstance()->getZECPrice() ,'f',2));
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
main->statusLabel->setText(" HUSH/EUR=€ " + QString::number( (double) Settings::getInstance()->getEURPrice() ,'f',2));
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
main->statusLabel->setText(" HUSH/BTC=BTC " + QString::number((double) Settings::getInstance()->getBTCPrice() ,'f',8));
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
main->statusLabel->setText(" HUSH/CNY=¥ /元 " + QString::number( (double) Settings::getInstance()->getCNYPrice() ,'f',2));
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
main->statusLabel->setText(" HUSH/RUB=₽ " + QString::number((double) Settings::getInstance()->getRUBPrice() ,'f',2));
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
main->statusLabel->setText(" HUSH/CAD=$ " + QString::number( (double) Settings::getInstance()->getCADPrice() ,'f',2));
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
main->statusLabel->setText(" HUSH/SGD=$ " + QString::number((double) Settings::getInstance()->getSGDPrice() ,'f',2));
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
main->statusLabel->setText(" HUSH/CHF=CHF " + QString::number((double) Settings::getInstance()->getCHFPrice() ,'f',2));
} else if (Settings::getInstance()->get_currency_name() == "INR") {
main->statusLabel->setText(" HUSH/INR=₹ " + QString::number( (double) Settings::getInstance()->getINRPrice() ,'f',2));
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
main->statusLabel->setText(" HUSH/GBP=£ " + QString::number((double) Settings::getInstance()->getGBPPrice() ,'f',2));
}else if (Settings::getInstance()->get_currency_name() == "AUD") {
main->statusLabel->setText(" HUSH/AUD=$ " + QString::number((double) Settings::getInstance()->getAUDPrice() ,'f',2));
} else {
main->statusLabel->setText(" error Input" + QString::number(Settings::getInstance()->getEURPrice() ));
}
main->statusLabel->setToolTip(tooltip);
main->statusIcon->setPixmap(i.pixmap(16, 16));
main->statusIcon->setToolTip(tooltip);
//int version = reply["version"].get<json::string_t>();
int version = 1;
Settings::getInstance()->sethushdVersion(version);
ui->Version->setText(QString::fromStdString(reply["version"].get<json::string_t>()));
ui->Vendor->setText(QString::fromStdString(reply["vendor"].get<json::string_t>()));
// See if recurring payments needs anything
Recurring::getInstance()->processPending(main);
@ -297,14 +323,98 @@ void Controller::updateUIBalances() {
ui->balTransparent->setText(balT.toDecimalhushString());
ui->balTotal ->setText(balTotal.toDecimalhushString());
if (Settings::getInstance()->get_currency_name() == "USD") {
ui->balSheilded ->setToolTip(balZ.toDecimalUSDString());
ui->balVerified ->setToolTip(balVerified.toDecimalUSDString());
ui->balTransparent->setToolTip(balT.toDecimalUSDString());
ui->balTotal ->setToolTip(balTotal.toDecimalUSDString());
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
ui->balSheilded ->setToolTip(balZ.toDecimalEURString());
ui->balVerified ->setToolTip(balVerified.toDecimalEURString());
ui->balTransparent->setToolTip(balT.toDecimalEURString());
ui->balTotal ->setToolTip(balTotal.toDecimalEURString());
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
ui->balSheilded ->setToolTip(balZ.toDecimalBTCString());
ui->balVerified ->setToolTip(balVerified.toDecimalBTCString());
ui->balTransparent->setToolTip(balT.toDecimalBTCString());
ui->balTotal ->setToolTip(balTotal.toDecimalBTCString());
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
ui->balSheilded ->setToolTip(balZ.toDecimalCNYString());
ui->balVerified ->setToolTip(balVerified.toDecimalCNYString());
ui->balTransparent->setToolTip(balT.toDecimalCNYString());
ui->balTotal ->setToolTip(balTotal.toDecimalCNYString());
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
ui->balSheilded ->setToolTip(balZ.toDecimalRUBString());
ui->balVerified ->setToolTip(balVerified.toDecimalRUBString());
ui->balTransparent->setToolTip(balT.toDecimalRUBString());
ui->balTotal ->setToolTip(balTotal.toDecimalRUBString());
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
ui->balSheilded ->setToolTip(balZ.toDecimalCADString());
ui->balVerified ->setToolTip(balVerified.toDecimalCADString());
ui->balTransparent->setToolTip(balT.toDecimalCADString());
ui->balTotal ->setToolTip(balTotal.toDecimalCADString());
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
ui->balSheilded ->setToolTip(balZ.toDecimalSGDString());
ui->balVerified ->setToolTip(balVerified.toDecimalSGDString());
ui->balTransparent->setToolTip(balT.toDecimalSGDString());
ui->balTotal ->setToolTip(balTotal.toDecimalSGDString());
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
ui->balSheilded ->setToolTip(balZ.toDecimalCHFString());
ui->balVerified ->setToolTip(balVerified.toDecimalCHFString());
ui->balTransparent->setToolTip(balT.toDecimalCHFString());
ui->balTotal ->setToolTip(balTotal.toDecimalCHFString());
} else if (Settings::getInstance()->get_currency_name() == "INR") {
ui->balSheilded ->setToolTip(balZ.toDecimalINRString());
ui->balVerified ->setToolTip(balVerified.toDecimalINRString());
ui->balTransparent->setToolTip(balT.toDecimalINRString());
ui->balTotal ->setToolTip(balTotal.toDecimalINRString());
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
ui->balSheilded ->setToolTip(balZ.toDecimalGBPString());
ui->balVerified ->setToolTip(balVerified.toDecimalGBPString());
ui->balTransparent->setToolTip(balT.toDecimalGBPString());
ui->balTotal ->setToolTip(balTotal.toDecimalGBPString());
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
ui->balSheilded ->setToolTip(balZ.toDecimalAUDString());
ui->balVerified ->setToolTip(balVerified.toDecimalAUDString());
ui->balTransparent->setToolTip(balT.toDecimalAUDString());
ui->balTotal ->setToolTip(balTotal.toDecimalAUDString());
}
// Send tab
ui->txtAvailablehush->setText(balAvailable.toDecimalhushString());
ui->txtAvailableUSD->setText(balAvailable.toDecimalUSDString());
if (Settings::getInstance()->get_currency_name() == "USD") {
ui->txtAvailableUSD->setText(balAvailable.toDecimalUSDString());
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
ui->txtAvailableUSD->setText(balAvailable.toDecimalEURString());
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
ui->txtAvailableUSD->setText(balAvailable.toDecimalBTCString());
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
ui->txtAvailableUSD->setText(balAvailable.toDecimalCNYString());
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
ui->txtAvailableUSD->setText(balAvailable.toDecimalRUBString());
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
ui->txtAvailableUSD->setText(balAvailable.toDecimalCADString());
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
ui->txtAvailableUSD->setText(balAvailable.toDecimalSGDString());
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
ui->txtAvailableUSD->setText(balAvailable.toDecimalCHFString());
} else if (Settings::getInstance()->get_currency_name() == "INR") {
ui->txtAvailableUSD->setText(balAvailable.toDecimalINRString());
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
ui->txtAvailableUSD->setText(balAvailable.toDecimalGBPString());
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
ui->txtAvailableUSD->setText(balAvailable.toDecimalAUDString());
}
}
void Controller::refreshBalances() {
@ -621,7 +731,7 @@ void Controller::refreshZECPrice() {
return noConnection();
// TODO: use/render all this data
QUrl cmcURL("https://api.coingecko.com/api/v3/simple/price?ids=hush&vs_currencies=btc%2Cusd%2Ceur&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true");
QUrl cmcURL("https://api.coingecko.com/api/v3/simple/price?ids=hush&vs_currencies=btc%2Cusd%2Ceur%2Ceth%2Cgbp%2Ccny%2Cjpy%2Crub%2Ccad%2Csgd%2Cchf%2Cinr%2Caud%2Cinr&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true");
QNetworkRequest req;
req.setUrl(cmcURL);
@ -642,6 +752,17 @@ void Controller::refreshZECPrice() {
qDebug() << reply->errorString();
}
Settings::getInstance()->setZECPrice(0);
Settings::getInstance()->setEURPrice(0);
Settings::getInstance()->setBTCPrice(0);
Settings::getInstance()->setCNYPrice(0);
Settings::getInstance()->setRUBPrice(0);
Settings::getInstance()->setCADPrice(0);
Settings::getInstance()->setSGDPrice(0);
Settings::getInstance()->setCHFPrice(0);
Settings::getInstance()->setGBPPrice(0);
Settings::getInstance()->setAUDPrice(0);
Settings::getInstance()->setINRPrice(0);
return;
}
@ -651,6 +772,16 @@ void Controller::refreshZECPrice() {
auto parsed = json::parse(all, nullptr, false);
if (parsed.is_discarded()) {
Settings::getInstance()->setZECPrice(0);
Settings::getInstance()->setEURPrice(0);
Settings::getInstance()->setBTCPrice(0);
Settings::getInstance()->setCNYPrice(0);
Settings::getInstance()->setRUBPrice(0);
Settings::getInstance()->setCADPrice(0);
Settings::getInstance()->setSGDPrice(0);
Settings::getInstance()->setCHFPrice(0);
Settings::getInstance()->setGBPPrice(0);
Settings::getInstance()->setAUDPrice(0);
Settings::getInstance()->setINRPrice(0);
return;
}
@ -659,21 +790,91 @@ void Controller::refreshZECPrice() {
const json& item = parsed.get<json::object_t>();
const json& hush = item["hush"].get<json::object_t>();
if (hush["usd"] >= 0) {
if (hush["usd"] >= 0) {
qDebug() << "Found hush key in price json";
// TODO: support BTC/EUR prices as well
//QString price = QString::fromStdString(hush["usd"].get<json::string_t>());
qDebug() << "HUSH = $" << QString::number((double)hush["usd"]);
Settings::getInstance()->setZECPrice( hush["usd"] );
return;
}
if (hush["eur"] >= 0)
{
qDebug() << "HUSH = €" << QString::number((double)hush["eur"]);
Settings::getInstance()->setEURPrice(hush["eur"]);
}
if (hush["btc"] >= 0)
{
qDebug() << "HUSH = BTC" << QString::number((double)hush["btc"]);
Settings::getInstance()->setBTCPrice( hush["btc"]);
}
if (hush["cny"] >= 0)
{
qDebug() << "HUSH = CNY" << QString::number((double)hush["cny"]);
Settings::getInstance()->setCNYPrice( hush["cny"]);
}
if (hush["rub"] >= 0)
{
qDebug() << "HUSH = RUB" << QString::number((double)hush["rub"]);
Settings::getInstance()->setRUBPrice( hush["rub"]);
}
if (hush["cad"] >= 0)
{
qDebug() << "HUSH = CAD" << QString::number((double)hush["cad"]);
Settings::getInstance()->setCADPrice( hush["cad"]);
}
if (hush["sgd"] >= 0)
{
qDebug() << "HUSH = SGD" << QString::number((double)hush["sgd"]);
Settings::getInstance()->setSGDPrice( hush["sgd"]);
}
if (hush["chf"] >= 0)
{
qDebug() << "HUSH = CHF" << QString::number((double)hush["chf"]);
Settings::getInstance()->setCADPrice( hush["chf"]);
}
if (hush["inr"] >= 0)
{
qDebug() << "HUSH = INR" << QString::number((double)hush["inr"]);
Settings::getInstance()->setINRPrice( hush["inr"]);
}
if (hush["gbp"] >= 0)
{
qDebug() << "HUSH = GBP" << QString::number((double)hush["gbp"]);
Settings::getInstance()->setGBPPrice( hush["gbp"]);
}
if (hush["aud"] >= 0)
{
qDebug() << "HUSH = AUD" << QString::number((double)hush["aud"]);
Settings::getInstance()->setAUDPrice( hush["aud"]);
}
return;
} catch (const std::exception& e) {
// If anything at all goes wrong, just set the price to 0 and move on.
qDebug() << QString("Caught something nasty: ") << e.what();
}
// If nothing, then set the price to 0;
Settings::getInstance()->setZECPrice(0);
Settings::getInstance()->setZECPrice(0);
Settings::getInstance()->setEURPrice(0);
Settings::getInstance()->setBTCPrice(0);
Settings::getInstance()->setCNYPrice(0);
Settings::getInstance()->setRUBPrice(0);
Settings::getInstance()->setCADPrice(0);
Settings::getInstance()->setSGDPrice(0);
Settings::getInstance()->setCHFPrice(0);
Settings::getInstance()->setGBPPrice(0);
Settings::getInstance()->setAUDPrice(0);
Settings::getInstance()->setINRPrice(0);
});
}

14
src/controller.h

@ -37,6 +37,17 @@ public:
void checkForUpdate(bool silent = true);
void refreshZECPrice();
void refreshEURPrice();
void refreshBTCPrice();
void refreshCNYPrice();
void refreshRUBPrice();
void refreshCADPrice();
void refreshSGDPrice();
void refreshCHFPrice();
void refreshINRPrice();
void refreshGBPPrice();
void refreshAUDPrice();
void executeStandardUITransaction(Tx tx);
@ -61,6 +72,8 @@ public:
void saveWallet(const std::function<void(json)>& cb) { zrpc->saveWallet(cb); }
void clearWallet(const std::function<void(json)>& cb) { zrpc->clearWallet(cb); }
void createNewZaddr(bool sapling, const std::function<void(json)>& cb) {
unlockIfEncrypted([=] () {
zrpc->createNewZaddr(sapling, cb);
@ -106,6 +119,7 @@ public:
QString getDefaultTAddress();
private:
void processInfo(const json&);
void refreshBalances();
void refreshTransactions();

2
src/createhushconfdialog.ui

@ -109,7 +109,7 @@
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Allow connections to the internet to check for updates, get hush/USD prices etc...</string>
<string>Allow connections to the internet to check for updates, get hush prices etc...</string>
</property>
</widget>
</item>

16
src/liteinterface.cpp

@ -84,6 +84,13 @@ void LiteInterface::saveWallet(const std::function<void(json)>& cb) {
conn->doRPCWithDefaultErrorHandling("save", "", cb);
}
void LiteInterface::clearWallet(const std::function<void(json)>& cb) {
if (conn == nullptr)
return;
conn->doRPCWithDefaultErrorHandling("clear", "", cb);
}
void LiteInterface::unlockWallet(QString password, const std::function<void(json)>& cb) {
if (conn == nullptr)
return;
@ -130,6 +137,15 @@ void LiteInterface::fetchInfo(const std::function<void(json)>& cb,
conn->doRPC("info", "", cb, err);
}
void LiteInterface::fetchLatestBlock(const std::function<void(json)>& cb,
const std::function<void(QString)>& err) {
if (conn == nullptr)
return;
conn->doRPC("height", "", cb, err);
}
/**
* Method to get all the private keys for both z and t addresses. It will make 2 batch calls,
* combine the result, and call the callback with a single list containing both the t-addr and z-addr

4
src/liteinterface.h

@ -44,6 +44,9 @@ public:
void fetchInfo(const std::function<void(json)>& cb,
const std::function<void(QString)>& err);
void fetchLatestBlock(const std::function<void(json)>& cb,
const std::function<void(QString)>& err);
void fetchBalance(const std::function<void(json)>& cb);
@ -56,6 +59,7 @@ public:
void fetchSeed(const std::function<void(json)>&);
void saveWallet(const std::function<void(json)>& cb);
void clearWallet(const std::function<void(json)>& cb);
void fetchWalletEncryptionStatus(const std::function<void(json)>& cb);
void encryptWallet(QString password, const std::function<void(json)>& cb);

2
src/main.cpp

@ -205,7 +205,7 @@ public:
w = new MainWindow();
w->setWindowTitle("SilentDragon Lite v" + QString(APP_VERSION));
w->setWindowTitle("SilentDragonLite v" + QString(APP_VERSION));
// If there was a payment URI on the command line, pay it
if (parser.positionalArguments().length() > 0) {

125
src/mainwindow.cpp

@ -16,6 +16,7 @@
#include "connection.h"
#include "requestdialog.h"
#include "websockets.h"
#include <QRegularExpression>
using json = nlohmann::json;
@ -36,6 +37,7 @@ MainWindow::MainWindow(QWidget *parent) :
this->slot_change_theme(theme_name);
ui->setupUi(this);
logger = new Logger(this, QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("silentdragonlite-wallet.log"));
@ -107,6 +109,20 @@ MainWindow::MainWindow(QWidget *parent) :
AppDataServer::getInstance()->connectAppDialog(this);
});
// Rescan
QObject::connect(ui->actionRescan, &QAction::triggered, [=]() {
// To rescan, we clear the wallet state, and then reload the connection
// This will start a sync, and show the scanning status.
getRPC()->clearWallet([=] (auto) {
// Save the wallet
getRPC()->saveWallet([=] (auto) {
// Then reload the connection. The ConnectionLoader deletes itself.
auto cl = new ConnectionLoader(this, rpc);
cl->loadConnection();
});
});
});
// Address Book
QObject::connect(ui->action_Address_Book, &QAction::triggered, this, &MainWindow::addressBook);
@ -393,6 +409,21 @@ void MainWindow::setupSettingsModal() {
Ui_Settings settings;
settings.setupUi(&settingsDialog);
Settings::saveRestore(&settingsDialog);
// Include currencies
QString currency_name;
try
{
currency_name = Settings::getInstance()->get_currency_name();
}
catch (...)
{
currency_name = "USD";
}
this->slot_change_currency(currency_name);
// Setup theme combo
int theme_index = settings.comboBoxTheme->findText(Settings::getInstance()->get_theme_name(), Qt::MatchExactly);
@ -404,25 +435,35 @@ void MainWindow::setupSettingsModal() {
QMessageBox::information(this, tr("Restart"), tr("Please restart Silentdragonlite to have the theme apply"), QMessageBox::Ok);
});
// Get Currency Data
int currency_index = settings.comboBoxCurrency->findText(Settings::getInstance()->get_currency_name(), Qt::MatchExactly);
settings.comboBoxCurrency->setCurrentIndex(currency_index);
QObject::connect(settings.comboBoxCurrency, &QComboBox::currentTextChanged, [=] (QString currency_name) {
this->slot_change_currency(currency_name);
// Tell the user to restart
QMessageBox::information(this, tr("Currency Change"), tr("Please restart SilentDragonLite to have new currencies apply"), QMessageBox::Ok);
});
// Check for updates
settings.chkCheckUpdates->setChecked(Settings::getInstance()->getCheckForUpdates());
// Fetch prices
settings.chkFetchPrices->setChecked(Settings::getInstance()->getAllowFetchPrices());
// List of default servers
settings.cmbServer->addItem("https://hush-lightwallet.de:443");
settings.cmbServer->addItem("https://hush-lightwallet.de:443");
// Load current values into the dialog
auto conf = Settings::getInstance()->getSettings();
settings.txtServer->setText(conf.server);
settings.cmbServer->setCurrentText(conf.server);
// Connection tab by default
settings.tabWidget->setCurrentIndex(0);
// Enable the troubleshooting options only if using embedded hushd
if (!rpc->isEmbedded()) {
settings.chkRescan->setEnabled(false);
settings.chkRescan->setToolTip(tr("You're using an external hushd. Please restart hushd with -rescan"));
}
if (settingsDialog.exec() == QDialog::Accepted) {
// Check for updates
Settings::getInstance()->setCheckForUpdates(settings.chkCheckUpdates->isChecked());
@ -431,14 +472,22 @@ void MainWindow::setupSettingsModal() {
Settings::getInstance()->setAllowFetchPrices(settings.chkFetchPrices->isChecked());
// Save the server
Settings::getInstance()->saveSettings(settings.txtServer->text().trimmed());
bool reloadConnection = false;
if (conf.server != settings.cmbServer->currentText().trimmed()) {
reloadConnection = true;
}
Settings::getInstance()->saveSettings(settings.cmbServer->currentText().trimmed());
if (false /* connection needs reloading?*/) {
if (reloadConnection) {
// Save settings
Settings::getInstance()->saveSettings(settings.txtServer->text());
auto cl = new ConnectionLoader(this, rpc);
cl->loadConnection();
Settings::getInstance()->saveSettings(settings.cmbServer->currentText());
// Save the wallet
getRPC()->saveWallet([=] (auto) {
// Then reload the connection. The ConnectionLoader deletes itself.
auto cl = new ConnectionLoader(this, rpc);
cl->loadConnection();
});
}
}
});
@ -446,7 +495,7 @@ void MainWindow::setupSettingsModal() {
void MainWindow::addressBook() {
// Check to see if there is a target.
QRegExp re("Address[0-9]+", Qt::CaseInsensitive);
QRegularExpression re("Address[0-9]+", QRegularExpression::CaseInsensitiveOption);
for (auto target: ui->sendToWidgets->findChildren<QLineEdit *>(re)) {
if (target->hasFocus()) {
AddressBook::open(this, target);
@ -1093,7 +1142,30 @@ void MainWindow::setupReceiveTab() {
}
ui->rcvLabel->setText(label);
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushUSDString());
if (Settings::getInstance()->get_currency_name() == "USD") {
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushUSDString());
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushEURString());
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushBTCString());
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushCNYString());
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushRUBString());
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushCADString());
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushSGDString());
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushCHFString());
} else if (Settings::getInstance()->get_currency_name() == "INR") {
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushINRString());
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushGBPString());
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalhushAUDString());
}
ui->txtReceive->setPlainText(addr);
ui->qrcodeDisplay->setQrcodeString(addr);
if (rpc->getModel()->getUsedAddresses().value(addr, false)) {
@ -1235,9 +1307,32 @@ void MainWindow::updateLabels() {
updateLabelsAutoComplete();
}
void MainWindow::slot_change_currency(const QString& currency_name)
{
Settings::getInstance()->set_currency_name(currency_name);
// Include currency
QString saved_currency_name;
try
{
saved_currency_name = Settings::getInstance()->get_currency_name();
}
catch (...)
{
saved_currency_name = "USD";
}
}
void MainWindow::slot_change_theme(const QString& theme_name)
{
Settings::getInstance()->set_theme_name(theme_name);
// Include css
QString saved_theme_name;

3
src/mainwindow.h

@ -78,7 +78,8 @@ public:
public slots:
void slot_change_theme(const QString& themeName);
void slot_change_currency(const QString& currencyName);
private:
void closeEvent(QCloseEvent* event);

28
src/mainwindow.ui

@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
<string>silentdragon</string>
<string>SilentDragonLite</string>
</property>
<property name="windowIcon">
<iconset resource="../application.qrc">
@ -22,7 +22,7 @@
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -79,9 +79,16 @@
<layout class="QHBoxLayout" name="horizontalLayout_17">
<item>
<widget class="QLabel" name="label_15">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
<pointsize>11</pointsize>
<kerning>true</kerning>
</font>
</property>
<property name="text">
@ -93,7 +100,7 @@
<widget class="QLabel" name="balVerified">
<property name="font">
<font>
<pointsize>10</pointsize>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
@ -392,8 +399,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1226</width>
<height>504</height>
<width>1162</width>
<height>344</height>
</rect>
</property>
<layout class="QVBoxLayout" name="sendToLayout">
@ -1088,7 +1095,7 @@
<x>0</x>
<y>0</y>
<width>1274</width>
<height>22</height>
<height>39</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@ -1132,6 +1139,8 @@
<addaction name="separator"/>
<addaction name="actionEncrypt_Wallet"/>
<addaction name="actionRemove_Wallet_Encryption"/>
<addaction name="separator"/>
<addaction name="actionRescan"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menu_Edit"/>
@ -1238,6 +1247,11 @@
<string>Remove Wallet Encryption</string>
</property>
</action>
<action name="actionRescan">
<property name="text">
<string>Rescan</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

77
src/recurring.cpp

@ -83,7 +83,29 @@ QJsonObject RecurringPaymentInfo::toJson() {
QString RecurringPaymentInfo::getAmountPretty() const {
CAmount amount = CAmount::fromDouble(amt);
if (Settings::getInstance()->get_currency_name() == "USD") {
return currency == "USD" ? amount.toDecimalUSDString() : amount.toDecimalhushString();
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
return currency == "EUR" ? amount.toDecimalEURString() : amount.toDecimalhushString();
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
return currency == "BTC" ? amount.toDecimalBTCString() : amount.toDecimalhushString();
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
return currency == "CNY" ? amount.toDecimalCNYString() : amount.toDecimalhushString();
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
return currency == "RUB" ? amount.toDecimalRUBString() : amount.toDecimalhushString();
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
return currency == "CAD" ? amount.toDecimalCADString() : amount.toDecimalhushString();
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
return currency == "SGD" ? amount.toDecimalSGDString() : amount.toDecimalhushString();
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
return currency == "CHF" ? amount.toDecimalCHFString() : amount.toDecimalhushString();
} else if (Settings::getInstance()->get_currency_name() == "INR") {
return currency == "INR" ? amount.toDecimalINRString() : amount.toDecimalhushString();
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
return currency == "GBP" ? amount.toDecimalGBPString() : amount.toDecimalhushString();
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
return currency == "AUD" ? amount.toDecimalAUDString() : amount.toDecimalhushString();
}
}
QString RecurringPaymentInfo::getScheduleDescription() const {
@ -136,8 +158,31 @@ RecurringPaymentInfo* Recurring::getNewRecurringFromTx(QWidget* parent, MainWind
if (tx.toAddrs.length() > 0) {
ui.lblTo->setText(tx.toAddrs[0].addr);
// Default is USD
// Change it with currency in Settings
if (Settings::getInstance()->get_currency_name() == "USD") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalUSDString());
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalEURString());
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalBTCString());
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalCNYString());
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalRUBString());
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalCADString());
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalSGDString());
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalCHFString());
} else if (Settings::getInstance()->get_currency_name() == "INR") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalINRString());
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalGBPString());
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalAUDString());
}
ui.txtMemo->setPlainText(tx.toAddrs[0].memo);
ui.txtMemo->setEnabled(false);
@ -147,10 +192,36 @@ RecurringPaymentInfo* Recurring::getNewRecurringFromTx(QWidget* parent, MainWind
QObject::connect(ui.cmbCurrency, &QComboBox::currentTextChanged, [&](QString c) {
if (tx.toAddrs.length() < 1)
return;
if (c == "USD") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalUSDString());
} else if (c == "EUR") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalEURString());
} else if
(c == "BTC") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalBTCString());
} else if (c == "CNY") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalCNYString());
} else if
(c == "RUB") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalRUBString());
} else if (c == "CAD") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalCADString());
} else if
(c == "SGD") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalSGDString());
} else if (c == "CHF") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalCHFString());
} else if
(c == "INR") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalINRString());
} else if (c == "GBP") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalGBPString());
} else if
(c == "AUD") {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalAUDString());
}
else {
ui.lblAmt->setText(tx.toAddrs[0].amount.toDecimalString());
}
@ -472,6 +543,8 @@ void Recurring::executeRecurringPayment(MainWindow* main, RecurringPaymentInfo r
PaymentStatus::ERROR);
}
return;
}
// Translate it into hush

55
src/requestdialog.cpp

@ -74,7 +74,13 @@ void RequestDialog::showPaymentConfirmation(MainWindow* main, QString paymentURI
req.txtMemo->setPlainText(payInfo.memo);
req.txtAmount->setText(payInfo.amt);
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
if (Settings::getInstance()->get_currency_name() == "USD") {
req.txtAmountUSD->setText(amount.toDecimalUSDString());
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
req.txtAmountUSD->setText(amount.toDecimalEURString());
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
req.txtAmountUSD->setText(amount.toDecimalBTCString());
}
req.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Pay"));
@ -114,11 +120,54 @@ void RequestDialog::showRequesthush(MainWindow* main) {
req.txtAmount->setValidator(main->getAmountValidator());
QObject::connect(req.txtAmount, &QLineEdit::textChanged, [=] (auto text) {
CAmount amount = CAmount::fromDecimalString(text);
req.txtAmountUSD->setText(amount.toDecimalUSDString());
if (Settings::getInstance()->get_currency_name() == "USD") {
req.txtAmountUSD->setText(amount.toDecimalUSDString());
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
req.txtAmountUSD->setText(amount.toDecimalEURString());
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
req.txtAmountUSD->setText(amount.toDecimalBTCString());
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
req.txtAmountUSD->setText(amount.toDecimalCNYString());
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
req.txtAmountUSD->setText(amount.toDecimalRUBString());
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
req.txtAmountUSD->setText(amount.toDecimalCADString());
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
req.txtAmountUSD->setText(amount.toDecimalSGDString());
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
req.txtAmountUSD->setText(amount.toDecimalCHFString());
} else if (Settings::getInstance()->get_currency_name() == "INR") {
req.txtAmountUSD->setText(amount.toDecimalINRString());
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
req.txtAmountUSD->setText(amount.toDecimalGBPString());
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
req.txtAmountUSD->setText(amount.toDecimalBTCString());
}
});
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
req.txtAmountUSD->setText(amount.toDecimalUSDString());
if (Settings::getInstance()->get_currency_name() == "USD") {
req.txtAmountUSD->setText(amount.toDecimalUSDString());
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
req.txtAmountUSD->setText(amount.toDecimalEURString());
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
req.txtAmountUSD->setText(amount.toDecimalBTCString());
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
req.txtAmountUSD->setText(amount.toDecimalCNYString());
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
req.txtAmountUSD->setText(amount.toDecimalRUBString());
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
req.txtAmountUSD->setText(amount.toDecimalCADString());
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
req.txtAmountUSD->setText(amount.toDecimalSGDString());
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
req.txtAmountUSD->setText(amount.toDecimalCHFString());
} else if (Settings::getInstance()->get_currency_name() == "INR") {
req.txtAmountUSD->setText(amount.toDecimalINRString());
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
req.txtAmountUSD->setText(amount.toDecimalGBPString());
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
req.txtAmountUSD->setText(amount.toDecimalBTCString());
}
req.txtMemo->setAcceptButton(req.buttonBox->button(QDialogButtonBox::Ok));
req.txtMemo->setLenDisplayLabel(req.lblMemoLen);
req.txtMemo->setMaxLen(400);

27
src/scripts/dounifiedbuild.ps1

@ -2,16 +2,17 @@
param (
[Parameter(Mandatory=$true)][string]$version,
[Parameter(Mandatory=$true)][string]$prev,
[Parameter(Mandatory=$true)][string]$certificate,
[Parameter(Mandatory=$true)][string]$server,
[Parameter(Mandatory=$true)][string]$winserver
)
Write-Host "[Initializing]"
Remove-Item -Force -ErrorAction Ignore ./artifacts/linux-binaries-silentdragon-v$version.tar.gz
Remove-Item -Force -ErrorAction Ignore ./artifacts/linux-deb-silentdragon-v$version.deb
Remove-Item -Force -ErrorAction Ignore ./artifacts/Windows-binaries-silentdragon-v$version.zip
Remove-Item -Force -ErrorAction Ignore ./artifacts/Windows-installer-silentdragon-v$version.msi
Remove-Item -Force -ErrorAction Ignore ./artifacts/macOS-silentdragon-v$version.dmg
Remove-Item -Force -ErrorAction Ignore ./artifacts/linux-binaries-SilentDragonLite-v$version.tar.gz
Remove-Item -Force -ErrorAction Ignore ./artifacts/linux-deb-SilentDragonLite-v$version.deb
Remove-Item -Force -ErrorAction Ignore ./artifacts/Windows-binaries-SilentDragonLite-v$version.zip
Remove-Item -Force -ErrorAction Ignore ./artifacts/Windows-installer-SilentDragonLite-v$version.msi
Remove-Item -Force -ErrorAction Ignore ./artifacts/macOS-SilentDragonLite-v$version.dmg
Remove-Item -Force -ErrorAction Ignore ./artifacts/signatures-v$version.tar.gz
@ -27,7 +28,7 @@ Write-Host ""
Write-Host "[Building on Mac]"
bash src/scripts/mkmacdmg.sh --qt_path ~/Qt/5.11.1/clang_64/ --version $version --hush_path ~/prod/hush
bash src/scripts/mkmacdmg.sh --qt_path ~/Qt/5.11.1/clang_64/ --version $version --certificate "$certificate"
if (! $?) {
Write-Output "[Error]"
exit 1;
@ -37,9 +38,11 @@ Write-Host ""
Write-Host "[Building Linux + Windows]"
Write-Host -NoNewline "Copying files.........."
# Cleanup some local files to aid copying
rm -rf lib/target/
ssh $server "rm -rf /tmp/zqwbuild"
ssh $server "mkdir /tmp/zqwbuild"
scp -r src/ singleapplication/ res/ ./silentdragonlite.pro ./application.qrc ./LICENSE ./README.md ${server}:/tmp/zqwbuild/ | Out-Null
scp -r src/ singleapplication/ res/ ./silentdragon-lite.pro ./application.qrc ./LICENSE ./README.md ${server}:/tmp/zqwbuild/ | Out-Null
ssh $server "dos2unix -q /tmp/zqwbuild/src/scripts/mkrelease.sh" | Out-Null
ssh $server "dos2unix -q /tmp/zqwbuild/src/version.h"
Write-Host "[OK]"
@ -86,11 +89,11 @@ Write-Host "[OK]"
# Finally, test to make sure all files exist
Write-Host -NoNewline "Checking Build........."
if (! (Test-Path ./artifacts/linux-binaries-silentdragon-v$version.tar.gz) -or
! (Test-Path ./artifacts/linux-deb-silentdragon-v$version.deb) -or
! (Test-Path ./artifacts/Windows-binaries-silentdragon-v$version.zip) -or
! (Test-Path ./artifacts/macOS-silentdragon-v$version.dmg) -or
! (Test-Path ./artifacts/Windows-installer-silentdragon-v$version.msi) ) {
if (! (Test-Path ./artifacts/linux-binaries-SilentDragonLite-v$version.tar.gz) -or
! (Test-Path ./artifacts/linux-deb-SilentDragonLite-v$version.deb) -or
! (Test-Path ./artifacts/Windows-binaries-SilentDragonLite-v$version.zip) -or
! (Test-Path ./artifacts/macOS-SilentDragonLite-v$version.dmg) -or
! (Test-Path ./artifacts/Windows-installer-SilentDragonLite-v$version.msi) ) {
Write-Host "[Error]"
exit 1;
}

12
src/scripts/mkmacdmg.sh

@ -12,8 +12,8 @@ case $key in
shift # past argument
shift # past value
;;
-z|--hush_path)
hush_DIR="$2"
-c|--certificate)
CERTIFICATE="$2"
shift # past argument
shift # past value
;;
@ -35,6 +35,11 @@ if [ -z $QT_PATH ]; then
exit 1;
fi
if [ -z $CERTIFICATE ]; then
echo "CERTIFICATE is not set. Please set it the name of the MacOS developer certificate to sign the binary with";
exit 1;
fi
if [ -z $APP_VERSION ]; then
echo "APP_VERSION is not set. Please set it to the current release version of the app";
exit 1;
@ -70,7 +75,8 @@ echo -n "Deploying.............."
mkdir artifacts >/dev/null 2>&1
rm -f artifcats/Silentdragonlite.dmg >/dev/null 2>&1
rm -f artifacts/rw* >/dev/null 2>&1
$QT_PATH/bin/macdeployqt Silentdragonlite.app
$QT_PATH/bin/macdeployqt SilentDragonLite.app
codesign --deep --force --verify --verbose -s "$CERTIFICATE" --options runtime --timestamp SilentDragonLite.app/
echo "[OK]"

13
src/scripts/mkwininstaller.ps1

@ -2,16 +2,13 @@ param (
[Parameter(Mandatory=$true)][string]$version
)
$target="silentdragon-v$version"
$target="SilentDragonLite-v$version"
Remove-Item -Path release/wininstaller -Recurse -ErrorAction Ignore | Out-Null
New-Item release/wininstaller -itemtype directory | Out-Null
Copy-Item release/$target/silentdragon.exe release/wininstaller/
Copy-Item release/$target/LICENSE release/wininstaller/
Copy-Item release/$target/README.md release/wininstaller/
Copy-Item release/$target/hushd.exe release/wininstaller/
Copy-Item release/$target/hush-cli.exe release/wininstaller/
Copy-Item release/$target/SilentDragonLite.exe release/wininstaller/
Copy-Item release/$target/LICENSE release/wininstaller/
Get-Content src/scripts/silentdragonlite.wxs | ForEach-Object { $_ -replace "RELEASE_VERSION", "$version" } | Out-File -Encoding utf8 release/wininstaller/silentdragonlite.wxs
@ -20,10 +17,10 @@ if (!$?) {
exit 1;
}
light.exe -ext WixUIExtension -cultures:en-us release/wininstaller/silentdragonlite.wixobj -out release/wininstaller/silentdragon.msi
light.exe -ext WixUIExtension -cultures:en-us release/wininstaller/SilentDragonLite.wixobj -out release/wininstaller/SilentDragonLite.msi
if (!$?) {
exit 1;
}
New-Item artifacts -itemtype directory -Force | Out-Null
Copy-Item release/wininstaller/silentdragon.msi ./artifacts/Windows-installer-$target.msi
Copy-Item release/wininstaller/SilentDragonLite.msi ./artifacts/Windows-installer-$target.msi

2
src/scripts/signbinaries.sh

@ -35,7 +35,7 @@ rm -f signatures-v$APP_VERSION.tar.gz
# sha256sum the binaries
gsha256sum *$APP_VERSION* > sha256sum-v$APP_VERSION.txt
for i in $( ls *silentdragon-v$APP_VERSION* sha256sum-v$APP_VERSION* ); do
for i in $( ls *SilentDragonLite-v$APP_VERSION* sha256sum-v$APP_VERSION* ); do
echo "Signing" $i
gpg --batch --output ../release/signatures/$i.sig --detach-sig $i
done

17
src/scripts/zec-qt-wallet.wxs

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="silentdragon vRELEASE_VERSION" Language="1033" Version="RELEASE_VERSION" Manufacturer="silentdragonlite-org" UpgradeCode="fb9bf166-b55f-46b5-a990-9189bdf64533">
<Product Id="*" Name="SilentDragonLite vRELEASE_VERSION" Language="1033" Version="RELEASE_VERSION" Manufacturer="silentdragonlite-org" UpgradeCode="fb9bf166-b55f-46b5-a990-9189bdf64533">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<Icon Id="silentdragonlite.exe" SourceFile="res/icon.ico"/>
<Property Id="ARPPRODUCTICON" Value="silentdragonlite.exe" />
<Icon Id="SilentDragonLite.exe" SourceFile="res/icon.ico"/>
<Property Id="ARPPRODUCTICON" Value="SilentDragonLite.exe" />
<Feature Id="ProductFeature" Title="silentdragonlite" Level="1">
<ComponentGroupRef Id="ProductComponents" />
@ -55,24 +55,21 @@
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="ProductComponent" Guid="0D210F5A-53E0-4E7E-CAAD-15A26995505E">
<File Source="silentdragon.exe" KeyPath="yes">
<File Source="SilentDragonLite.exe" KeyPath="yes">
<Shortcut Id="startMenuShotcut" Advertise="yes" Directory="ApplicationProgramsFolder"
Name="silentdragon" WorkingDirectory="INSTALLFOLDER" Icon="silentdragonlite.exe" >
Name="SilentDragonLite" WorkingDirectory="INSTALLFOLDER" Icon="SilentDragonLite.exe" >
</Shortcut>
</File>
<File Source="LICENSE" />
<File Source="hushd.exe" />
<File Source="hush-cli.exe" />
<File Source="README.md" />
<RegistryKey Root="HKCR" Key="hush">
<RegistryValue Type="string" Name="URL Protocol" Value=""/>
<RegistryValue Type="string" Value="URL:hush URI protocol"/>
<RegistryKey Key="DefaultIcon">
<RegistryValue Type="string" Value="silentdragon.exe" />
<RegistryValue Type="string" Value="SilentDragonLite.exe" />
</RegistryKey>
<RegistryKey Key="shell\open\command">
<RegistryValue Type="string" Value="&quot;[INSTALLFOLDER]silentdragon.exe&quot; &quot;%1&quot;" />
<RegistryValue Type="string" Value="&quot;[INSTALLFOLDER]SilentDragonLite.exe&quot; &quot;%1&quot;" />
</RegistryKey>
</RegistryKey>
</Component>

190
src/sendtab.cpp

@ -58,7 +58,30 @@ void MainWindow::setupSendTab() {
ui->minerFeeAmt->setReadOnly(true);
QObject::connect(ui->minerFeeAmt, &QLineEdit::textChanged, [=](auto txt) {
CAmount fee = CAmount::fromDecimalString(txt);
if (Settings::getInstance()->get_currency_name() == "USD") {
ui->lblMinerFeeUSD->setText(fee.toDecimalUSDString());
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
ui->lblMinerFeeUSD->setText(fee.toDecimalEURString());
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
ui->lblMinerFeeUSD->setText(fee.toDecimalBTCString());
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
ui->lblMinerFeeUSD->setText(fee.toDecimalCNYString());
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
ui->lblMinerFeeUSD->setText(fee.toDecimalRUBString());
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
ui->lblMinerFeeUSD->setText(fee.toDecimalCADString());
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
ui->lblMinerFeeUSD->setText(fee.toDecimalSGDString());
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
ui->lblMinerFeeUSD->setText(fee.toDecimalCHFString());
} else if (Settings::getInstance()->get_currency_name() == "INR") {
ui->lblMinerFeeUSD->setText(fee.toDecimalINRString());
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
ui->lblMinerFeeUSD->setText(fee.toDecimalGBPString());
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
ui->lblMinerFeeUSD->setText(fee.toDecimalAUDString());
}
});
ui->minerFeeAmt->setText(Settings::getMinerFee().toDecimalString());
@ -66,9 +89,42 @@ void MainWindow::setupSendTab() {
QObject::connect(ui->tabWidget, &QTabWidget::currentChanged, [=] (int pos) {
if (pos == 1) {
QString txt = ui->minerFeeAmt->text();
if (Settings::getInstance()->get_currency_name() == "USD") {
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalUSDString();
ui->lblMinerFeeUSD->setText(feeUSD);
}
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalEURString();
ui->lblMinerFeeUSD->setText(feeUSD);
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalEURString();
ui->lblMinerFeeUSD->setText(feeUSD);
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalCNYString();
ui->lblMinerFeeUSD->setText(feeUSD);
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalRUBString();
ui->lblMinerFeeUSD->setText(feeUSD);
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalCADString();
ui->lblMinerFeeUSD->setText(feeUSD);
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalSGDString();
ui->lblMinerFeeUSD->setText(feeUSD);
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalCHFString();
ui->lblMinerFeeUSD->setText(feeUSD);
} else if (Settings::getInstance()->get_currency_name() == "INR") {
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalINRString();
ui->lblMinerFeeUSD->setText(feeUSD);
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalGBPString();
ui->lblMinerFeeUSD->setText(feeUSD);
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalAUDString();
ui->lblMinerFeeUSD->setText(feeUSD);
}
}
});
//Fees validator
@ -158,7 +214,7 @@ void MainWindow::updateLabelsAutoComplete() {
labelCompleter->setCaseSensitivity(Qt::CaseInsensitive);
// Then, find all the address fields and update the completer.
QRegExp re("Address[0-9]+", Qt::CaseInsensitive);
QRegularExpression re("Address[0-9]+", QRegularExpression::CaseInsensitiveOption);
for (auto target: ui->sendToWidgets->findChildren<QLineEdit *>(re)) {
target->setCompleter(labelCompleter);
}
@ -275,7 +331,30 @@ void MainWindow::addressChanged(int itemNumber, const QString& text) {
void MainWindow::amountChanged(int item, const QString& text) {
auto usd = ui->sendToWidgets->findChild<QLabel*>(QString("AmtUSD") % QString::number(item));
CAmount amt = CAmount::fromDecimalString(text);
if (Settings::getInstance()->get_currency_name() == "USD") {
usd->setText(amt.toDecimalUSDString());
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
usd->setText(amt.toDecimalEURString());
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
usd->setText(amt.toDecimalBTCString());
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
usd->setText(amt.toDecimalCNYString());
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
usd->setText(amt.toDecimalRUBString());
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
usd->setText(amt.toDecimalCADString());
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
usd->setText(amt.toDecimalSGDString());
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
usd->setText(amt.toDecimalCHFString());
} else if (Settings::getInstance()->get_currency_name() == "INR") {
usd->setText(amt.toDecimalINRString());
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
usd->setText(amt.toDecimalGBPString());
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
usd->setText(amt.toDecimalAUDString());
}
// If there is a recurring payment, update the info there as well
if (sendTxRecurringInfo != nullptr) {
@ -535,12 +614,93 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
totalSpending = totalSpending + toAddr.amount;
// Amount (USD)
if (Settings::getInstance()->get_currency_name() == "USD") {
auto AmtUSD = new QLabel(confirm.sendToAddrs);
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
AmtUSD->setText(toAddr.amount.toDecimalUSDString());
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
// Amount (EUR)
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
auto AmtUSD = new QLabel(confirm.sendToAddrs);
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
AmtUSD->setText(toAddr.amount.toDecimalEURString());
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
// Amount (BTC)
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
auto AmtUSD = new QLabel(confirm.sendToAddrs);
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
AmtUSD->setText(toAddr.amount.toDecimalBTCString());
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
// Amount (CNY)
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
auto AmtUSD = new QLabel(confirm.sendToAddrs);
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
AmtUSD->setText(toAddr.amount.toDecimalCNYString());
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
// Amount (RUB)
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
auto AmtUSD = new QLabel(confirm.sendToAddrs);
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
AmtUSD->setText(toAddr.amount.toDecimalRUBString());
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
// Amount (CAD)
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
auto AmtUSD = new QLabel(confirm.sendToAddrs);
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
AmtUSD->setText(toAddr.amount.toDecimalCADString());
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
// Amount (SGD)
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
auto AmtUSD = new QLabel(confirm.sendToAddrs);
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
AmtUSD->setText(toAddr.amount.toDecimalSGDString());
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
// Amount (CHF)
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
auto AmtUSD = new QLabel(confirm.sendToAddrs);
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
AmtUSD->setText(toAddr.amount.toDecimalCHFString());
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
// Amount (INR)
} else if (Settings::getInstance()->get_currency_name() == "INR") {
auto AmtUSD = new QLabel(confirm.sendToAddrs);
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
AmtUSD->setText(toAddr.amount.toDecimalINRString());
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
// Amount (GBP)
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
auto AmtUSD = new QLabel(confirm.sendToAddrs);
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
AmtUSD->setText(toAddr.amount.toDecimalGBPString());
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
// Amount (AUD)
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
auto AmtUSD = new QLabel(confirm.sendToAddrs);
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
AmtUSD->setText(toAddr.amount.toDecimalAUDString());
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
}
// Memo
if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.isEmpty()) {
row++;
@ -588,7 +748,29 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
minerFeeUSD->setObjectName(QStringLiteral("minerFeeUSD"));
minerFeeUSD->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
confirm.gridLayout->addWidget(minerFeeUSD, row, 2, 1, 1);
minerFeeUSD->setText(tx.fee.toDecimalUSDString());
if (Settings::getInstance()->get_currency_name() == "USD") {
minerFeeUSD->setText(tx.fee.toDecimalUSDString());
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
minerFeeUSD->setText(tx.fee.toDecimalEURString());
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
minerFeeUSD->setText(tx.fee.toDecimalBTCString());
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
minerFeeUSD->setText(tx.fee.toDecimalCNYString());
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
minerFeeUSD->setText(tx.fee.toDecimalRUBString());
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
minerFeeUSD->setText(tx.fee.toDecimalCADString());
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
minerFeeUSD->setText(tx.fee.toDecimalSGDString());
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
minerFeeUSD->setText(tx.fee.toDecimalCHFString());
} else if (Settings::getInstance()->get_currency_name() == "INR") {
minerFeeUSD->setText(tx.fee.toDecimalINRString());
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
minerFeeUSD->setText(tx.fee.toDecimalGBPString());
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
minerFeeUSD->setText(tx.fee.toDecimalAUDString());
}
}
// Recurring payment info, show only if there is exactly one destination address

47
src/settings.cpp

@ -74,11 +74,11 @@ bool Settings::isTAddress(QString addr) {
return addr.startsWith("R");
}
int Settings::gethushdVersion() {
QString Settings::gethushdVersion() {
return _hushdVersion;
}
void Settings::sethushdVersion(int version) {
void Settings::sethushdVersion(QString version) {
_hushdVersion = version;
}
@ -105,6 +105,36 @@ bool Settings::isSaplingActive() {
double Settings::getZECPrice() {
return ZECPrice;
}
double Settings::getEURPrice() {
return EURPrice;
}
double Settings::getBTCPrice() {
return BTCPrice;
}
double Settings::getCNYPrice() {
return CNYPrice;
}
double Settings::getRUBPrice() {
return RUBPrice;
}
double Settings::getCADPrice() {
return CADPrice;
}
double Settings::getSGDPrice() {
return SGDPrice;
}
double Settings::getCHFPrice() {
return CHFPrice;
}
double Settings::getINRPrice() {
return INRPrice;
}
double Settings::getGBPPrice() {
return GBPPrice;
}
double Settings::getAUDPrice() {
return AUDPrice;
}
bool Settings::getCheckForUpdates() {
return QSettings().value("options/allowcheckupdates", true).toBool();
@ -122,6 +152,19 @@ void Settings::setAllowFetchPrices(bool allow) {
QSettings().setValue("options/allowfetchprices", allow);
}
QString Settings::get_currency_name() {
// Load from the QT Settings.
return QSettings().value("options/currency_name", false).toString();
}
void Settings::set_currency_name(QString currency_name) {
QSettings().setValue("options/currency_name", currency_name);
}
QString Settings::get_theme_name() {
// Load from the QT Settings.
return QSettings().value("options/theme_name", false).toString();

47
src/settings.h

@ -42,8 +42,8 @@ public:
bool isSyncing();
void setSyncing(bool syncing);
int gethushdVersion();
void sethushdVersion(int version);
QString gethushdVersion();
void sethushdVersion(QString version);
void setUseEmbedded(bool r) { _useEmbedded = r; }
bool useEmbedded() { return _useEmbedded; }
@ -63,10 +63,34 @@ public:
QString get_theme_name();
void set_theme_name(QString theme_name);
QString get_currency_name();
void set_currency_name(QString currency_name);
bool isSaplingActive();
void setZECPrice(double p) { ZECPrice = p; }
void setEURPrice(double p) { EURPrice = p; }
void setBTCPrice(double p) { BTCPrice = p; }
void setCNYPrice(double p) { CNYPrice = p; }
void setRUBPrice(double p) { RUBPrice = p; }
void setCADPrice(double p) { CADPrice = p; }
void setSGDPrice(double p) { SGDPrice = p; }
void setCHFPrice(double p) { CHFPrice = p; }
void setINRPrice(double p) { INRPrice = p; }
void setGBPPrice(double p) { GBPPrice = p; }
void setAUDPrice(double p) { AUDPrice = p; }
double getZECPrice();
double getEURPrice();
double getBTCPrice();
double getCNYPrice();
double getRUBPrice();
double getCADPrice();
double getSGDPrice();
double getCHFPrice();
double getINRPrice();
double getGBPPrice();
double getAUDPrice();
// Static stuff
static const QString txidStatusMessage;
@ -95,13 +119,12 @@ public:
static bool isValidAddress(QString addr);
static QString getChainName() { return QString("main"); }
static QString getDefaultChainName() { return QString("main"); }
static const QString labelRegExp;
static const int updateSpeed = 20 * 1000; // 10 sec
static const int quickUpdateSpeed = 5 * 1000; // 3 sec
static const int priceRefreshSpeed = 60 * 60 * 1000; // 15 mins
static const int updateSpeed = 30 * 1000; // 30 sec
static const int priceRefreshSpeed = 5 * 60 * 1000; // 1 hr
private:
// This class can only be accessed through Settings::getInstance()
@ -114,11 +137,21 @@ private:
bool _isTestnet = false;
bool _isSyncing = false;
int _blockNumber = 0;
int _hushdVersion = 0;
QString _hushdVersion = 0;
bool _useEmbedded = false;
bool _headless = false;
double ZECPrice = 0.0;
double BTCPrice = 0.0;
double EURPrice = 0.0;
double CNYPrice = 0.0;
double RUBPrice = 0.0;
double CADPrice = 0.0;
double SGDPrice = 0.0;
double CHFPrice = 0.0;
double INRPrice = 0.0;
double GBPPrice = 0.0;
double AUDPrice = 0.0;
};

363
src/settings.ui

@ -6,16 +6,10 @@
<rect>
<x>0</x>
<y>0</y>
<width>540</width>
<width>733</width>
<height>539</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>540</width>
<height>500</height>
</size>
</property>
<property name="windowTitle">
<string>Settings</string>
</property>
@ -26,7 +20,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -52,19 +46,20 @@
</size>
</property>
<property name="text">
<string>Server</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtServer">
<property name="placeholderText">
<string/>
<string>Lightwallet Server</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2"/>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QComboBox" name="cmbServer">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
@ -85,152 +80,218 @@
<attribute name="title">
<string>Options</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="6" column="1">
<widget class="QComboBox" name="comboBoxTheme">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>default</string>
</property>
</item>
<item>
<property name="text">
<string>blue</string>
</property>
</item>
<item>
<property name="text">
<string>light</string>
</property>
</item>
<item>
<property name="text">
<string>dark</string>
</property>
</item>
</widget>
<widget class="QComboBox" name="comboBoxTheme">
<property name="geometry">
<rect>
<x>80</x>
<y>110</y>
<width>80</width>
<height>25</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>default</string>
</property>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="chkFetchPrices">
<property name="text">
<string>Fetch hush / USD prices</string>
</property>
</widget>
<item>
<property name="text">
<string>blue</string>
</property>
</item>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="chkCheckUpdates">
<property name="text">
<string>Check github for updates at startup</string>
</property>
</widget>
<item>
<property name="text">
<string>light</string>
</property>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Connect to github on startup to check for updates</string>
</property>
</widget>
<item>
<property name="text">
<string>dark</string>
</property>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_20">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Theme</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</widget>
<widget class="QCheckBox" name="chkFetchPrices">
<property name="geometry">
<rect>
<x>9</x>
<y>61</y>
<width>184</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Fetch hush prices</string>
</property>
</widget>
<widget class="QCheckBox" name="chkCheckUpdates">
<property name="geometry">
<rect>
<x>9</x>
<y>9</y>
<width>267</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Check github for updates at startup</string>
</property>
</widget>
<widget class="QLabel" name="label_8">
<property name="geometry">
<rect>
<x>9</x>
<y>38</y>
<width>340</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Connect to github on startup to check for updates</string>
</property>
</widget>
<widget class="QLabel" name="label_20">
<property name="geometry">
<rect>
<x>9</x>
<y>113</y>
<width>47</width>
<height>17</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Theme</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="Line" name="line_2">
<property name="geometry">
<rect>
<x>10</x>
<y>180</y>
<width>500</width>
<height>16</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label_10">
<property name="geometry">
<rect>
<x>9</x>
<y>90</y>
<width>297</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Connect to the internet to fetch hush prices</string>
</property>
</widget>
<widget class="QLabel" name="label_21">
<property name="geometry">
<rect>
<x>10</x>
<y>150</y>
<width>61</width>
<height>20</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Currency</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
<widget class="QComboBox" name="comboBoxCurrency">
<property name="geometry">
<rect>
<x>80</x>
<y>150</y>
<width>80</width>
<height>25</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>AUD</string>
</property>
</item>
<item row="8" column="0" colspan="2">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
<item>
<property name="text">
<string>BTC</string>
</property>
</item>
<item row="7" column="0" colspan="2">
<widget class="Line" name="line_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<item>
<property name="text">
<string>CAD</string>
</property>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Connect to the internet to fetch hush prices</string>
</property>
</widget>
<item>
<property name="text">
<string>CHF</string>
</property>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Troubleshooting</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="5" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
<item>
<property name="text">
<string>CNY</string>
</property>
</item>
<item row="2" column="0">
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<item>
<property name="text">
<string>EUR</string>
</property>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Rescan the blockchain for any missing wallet transactions and to correct your wallet balance. This may take several hours. You need to restart hushWallet for this to take effect</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<item>
<property name="text">
<string>GBP</string>
</property>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="chkRescan">
<property name="text">
<string>Rescan</string>
</property>
</widget>
<item>
<property name="text">
<string>INR</string>
</property>
</item>
</layout>
<item>
<property name="text">
<string>USD</string>
</property>
</item>
</widget>
</widget>
</widget>
</item>

43
src/txtablemodel.cpp

@ -70,15 +70,18 @@ bool TxTableModel::exportToCsv(QString fileName) const {
}
QString TxTableModel::concatMultipleMemos(const TransactionItem& dat) const {
// Concat all the memos
QString memo;
for (auto item : dat.items) {
if (!item.memo.trimmed().isEmpty()) {
memo += item.address + ": \"" + item.memo + "\"\n";
if (dat.items.length() == 1) {
return dat.items[0].memo;
} else {
// Concat all the memos
QString memo;
for (auto item : dat.items) {
if (!item.memo.trimmed().isEmpty()) {
memo += item.address + ": \"" + item.memo + "\"\n";
}
}
return memo;
}
return memo;
};
QVariant TxTableModel::data(const QModelIndex &index, int role) const {
@ -155,7 +158,31 @@ QVariant TxTableModel::data(const QModelIndex &index, int role) const {
for (int i=0; i < dat.items.length(); i++) {
total = total + dat.items[i].amount;
}
return total.toDecimalUSDString();
if (Settings::getInstance()->get_currency_name() == "USD") {
return total.toDecimalUSDString();
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
return total.toDecimalEURString();
} else if (Settings::getInstance()->get_currency_name() == "BTC") {
return total.toDecimalBTCString();
} else if (Settings::getInstance()->get_currency_name() == "EUR") {
return total.toDecimalEURString();
} else if (Settings::getInstance()->get_currency_name() == "CNY") {
return total.toDecimalCNYString();
} else if (Settings::getInstance()->get_currency_name() == "RUB") {
return total.toDecimalRUBString();
} else if (Settings::getInstance()->get_currency_name() == "CAD") {
return total.toDecimalCADString();
} else if (Settings::getInstance()->get_currency_name() == "SGD") {
return total.toDecimalSGDString();
} else if (Settings::getInstance()->get_currency_name() == "CHF") {
return total.toDecimalCHFString();
} else if (Settings::getInstance()->get_currency_name() == "INR") {
return total.toDecimalINRString();
} else if (Settings::getInstance()->get_currency_name() == "GBP") {
return total.toDecimalGBPString();
} else if (Settings::getInstance()->get_currency_name() == "AUD") {
return total.toDecimalAUDString();
}
}
}
}

2
src/version.h

@ -1 +1 @@
#define APP_VERSION "1.0.1"
#define APP_VERSION "1.1.0"

2
src/websockets.cpp

@ -112,7 +112,7 @@ void WormholeClient::connect() {
QObject::connect(m_webSocket, &QWebSocket::connected, this, &WormholeClient::onConnected);
QObject::connect(m_webSocket, &QWebSocket::disconnected, this, &WormholeClient::closed);
m_webSocket->open(QUrl("wss://wormhole.silentdragonlite.com:443"));
m_webSocket->open(QUrl("wss://wormhole.myhush.org:443"));
//m_webSocket->open(QUrl("ws://127.0.0.1:7070"));
}

Loading…
Cancel
Save