Compare commits
201 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f03ea0461c | ||
|
|
6ce9a3cba0 | ||
|
|
8cd32987d4 | ||
|
|
648b775a25 | ||
|
|
b24ccc2fe3 | ||
|
|
00783e7b68 | ||
|
|
dafc47050a | ||
|
|
0e65d89172 | ||
|
|
fd9e7d00ed | ||
|
|
3d7ded209a | ||
|
|
e81a589a8d | ||
|
|
074d8fb42e | ||
|
|
b632d078e5 | ||
|
|
1c2920a339 | ||
|
|
676b8d6921 | ||
|
|
9d5eb002ae | ||
|
|
63d4ba6df8 | ||
|
|
c2dbda63c6 | ||
|
|
6e7b4ff9f9 | ||
|
|
1269f0a13a | ||
|
|
04b91e76f2 | ||
|
|
c9c7bb9171 | ||
|
|
619661a61d | ||
|
|
457b1dee49 | ||
|
|
7cca39ad48 | ||
|
|
90406dfd1e | ||
|
|
6d7abaf5c0 | ||
|
|
bc40942889 | ||
|
|
646d3394d3 | ||
|
|
c06cb5cc58 | ||
|
|
983a3ba7ad | ||
|
|
265afe1610 | ||
|
|
32f7666912 | ||
|
|
20a58143b6 | ||
|
|
4cc3d3f3e2 | ||
|
|
2ab3d8ebf2 | ||
|
|
9e4bfb1ef2 | ||
|
|
7b0cd19487 | ||
|
|
c0fa4f5d27 | ||
|
|
d5f4d5d93f | ||
|
|
9ba1960207 | ||
|
|
04a665db0c | ||
|
|
f47335f89f | ||
|
|
f75aa22b26 | ||
|
|
50e1ce1460 | ||
|
|
df02532fd5 | ||
|
|
bd20626460 | ||
|
|
8738210991 | ||
|
|
6c2c17ada1 | ||
|
|
380f218b3a | ||
|
|
12647fac73 | ||
|
|
9f0f40af80 | ||
|
|
c316fab29f | ||
|
|
37de27d7f6 | ||
|
|
c61d857a67 | ||
|
|
56023facaa | ||
|
|
1dc45bad87 | ||
|
|
0daf2aacf5 | ||
|
|
06ccded94e | ||
|
|
ff38e965bd | ||
|
|
a9a59fd314 | ||
|
|
e2a187f892 | ||
|
|
4a526810ce | ||
|
|
2f5c47e95f | ||
|
|
34b216e6dc | ||
|
|
d2b9d5690b | ||
|
|
d10f1b5d30 | ||
|
|
fea3bb503f | ||
|
|
d92cc944cb | ||
|
|
f57b2d57cd | ||
|
|
cf0e5a811e | ||
|
|
ea8f51d168 | ||
|
|
e8befc4c67 | ||
|
|
5518771a8b | ||
|
|
47bc0f2a3c | ||
|
|
8bd820b909 | ||
|
|
f948d0e214 | ||
|
|
3a7c9e6c8e | ||
|
|
5a65d28d29 | ||
|
|
e9cdaf4dbe | ||
|
|
17f032ea11 | ||
|
|
ef565e5fa3 | ||
|
|
92f9bec1e7 | ||
|
|
0e3f3c13a1 | ||
|
|
74e12ce71d | ||
|
|
5fe6b48517 | ||
|
|
7f7a39292c | ||
|
|
2e1e227b4c | ||
|
|
ee68bcb6e9 | ||
|
|
025a638082 | ||
|
|
33babc5d85 | ||
|
|
a4c17ac82b | ||
|
|
06ba205320 | ||
|
|
5df14abed2 | ||
|
|
cdad85c0ef | ||
|
|
40e2d2045b | ||
|
|
212c8dd054 | ||
|
|
290582d428 | ||
|
|
582267a923 | ||
|
|
fe3c06c36b | ||
|
|
95d7826163 | ||
|
|
5e2099ad47 | ||
|
|
44280d1e52 | ||
|
|
897d879dad | ||
|
|
631a1c49c8 | ||
|
|
d3b20d2c04 | ||
|
|
c60c9ee69a | ||
|
|
965081c554 | ||
|
|
e6458b58ef | ||
|
|
9207462676 | ||
|
|
ab020358e7 | ||
|
|
135cfbac68 | ||
|
|
3dbf09e7ad | ||
|
|
32257c8fab | ||
|
|
5ecca50977 | ||
|
|
ae2fdc7ab3 | ||
|
|
f72ed257ce | ||
|
|
947e265a1a | ||
|
|
77ff362b58 | ||
|
|
9d40baa3ef | ||
|
|
d3b81cb6f8 | ||
|
|
c87ebf1f31 | ||
|
|
4905341999 | ||
|
|
047dee4eb4 | ||
|
|
dd1046b31f | ||
|
|
2b82a472ae | ||
|
|
8d5ef035d2 | ||
|
|
a3d41a80bf | ||
|
|
413507bba9 | ||
|
|
2ca76ff13c | ||
|
|
a6cd010695 | ||
|
|
411505bff5 | ||
|
|
4f4e879f8d | ||
|
|
448727f4b5 | ||
|
|
ca8138bb46 | ||
|
|
10764b8a68 | ||
|
|
b91afaf5c7 | ||
|
|
31501316c9 | ||
|
|
120a62257f | ||
|
|
a1e416ee83 | ||
|
|
3cf2dc0c04 | ||
|
|
6df9e584b3 | ||
|
|
0d247a9b8a | ||
|
|
bc22de47f9 | ||
|
|
a5b2d5e727 | ||
|
|
2c78f77eb2 | ||
|
|
738e802f3c | ||
|
|
8dab0755d3 | ||
|
|
5f81b573c0 | ||
|
|
a267712d10 | ||
|
|
0abaae073d | ||
|
|
a6791561d6 | ||
|
|
3ca2473239 | ||
|
|
779cc3e24d | ||
|
|
cfd2139310 | ||
|
|
4c05bff21e | ||
|
|
5392dd7ed0 | ||
|
|
cb9cb6eb09 | ||
|
|
3a33ddeecd | ||
|
|
a83910d7de | ||
|
|
336ed9d6e5 | ||
|
|
346e942e93 | ||
|
|
13a5be7306 | ||
|
|
bdceff6380 | ||
|
|
17c61f897a | ||
|
|
9a58e88ec6 | ||
|
|
355cccaa64 | ||
|
|
29580de2c7 | ||
|
|
67e08da918 | ||
|
|
e660b2d169 | ||
|
|
40bdf692d1 | ||
|
|
562c46660a | ||
|
|
0724dd0043 | ||
|
|
c0932a1bd5 | ||
|
|
d7a65fafad | ||
|
|
239e27c1b5 | ||
|
|
1ca10373a3 | ||
|
|
ac6687f6ff | ||
|
|
b616e1c8f6 | ||
|
|
1ec22b3d0c | ||
|
|
a01ffc6e1a | ||
|
|
e1bbc1e525 | ||
|
|
049cef9ce3 | ||
|
|
18f7a6a694 | ||
|
|
30a3abedbe | ||
|
|
2f5c926c82 | ||
|
|
55b4425c5d | ||
|
|
dc49d7af38 | ||
|
|
e01c2e903a | ||
|
|
886be81af2 | ||
|
|
671ddf5bef | ||
|
|
5f8cb04fee | ||
|
|
3f06560c51 | ||
|
|
f666e6f42e | ||
|
|
e546ce83b4 | ||
|
|
059a2d754e | ||
|
|
1e64ebe17a | ||
|
|
8abf8f844f | ||
|
|
01740a253d | ||
|
|
2d72f55e57 | ||
|
|
ab47b4a783 |
34
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
name: GUI build
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-macos:
|
||||||
|
|
||||||
|
runs-on: macOS-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: update brew and install dependencies
|
||||||
|
run: brew update && brew install boost hidapi zmq libpgm unbound libsodium miniupnpc ldns expat doxygen graphviz libunwind-headers protobuf qt5
|
||||||
|
- name: build
|
||||||
|
run: export PATH=$PATH:/usr/local/opt/qt/bin && ./build.sh
|
||||||
|
- name: test qml
|
||||||
|
run: build/release/bin/monero-wallet-gui.app/Contents/MacOS/monero-wallet-gui --test-qml
|
||||||
|
|
||||||
|
build-ubuntu:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: update apt
|
||||||
|
run: sudo apt update
|
||||||
|
- name: install monero dependencies
|
||||||
|
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev
|
||||||
|
- name: install monero gui dependencies
|
||||||
|
run: sudo apt -y install qtbase5-dev qt5-default qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-dialogs qml-module-qtquick-xmllistmodel qml-module-qt-labs-settings qml-module-qt-labs-folderlistmodel qttools5-dev-tools qml-module-qtquick-templates2 libqt5svg5-dev xvfb
|
||||||
|
- name: build
|
||||||
|
run: ./build.sh
|
||||||
|
- name: test qml
|
||||||
|
run: xvfb-run -a build/release/bin/monero-wallet-gui --test-qml
|
||||||
359
LeftPanel.qml
@@ -40,17 +40,17 @@ import "components/effects/" as MoneroEffects
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
id: panel
|
id: panel
|
||||||
|
|
||||||
property alias unlockedBalanceText: unlockedBalanceText.text
|
property int currentAccountIndex
|
||||||
property alias unlockedBalanceVisible: unlockedBalanceText.visible
|
property alias currentAccountLabel: accountLabel.text
|
||||||
property alias unlockedBalanceLabelVisible: unlockedBalanceLabel.visible
|
property string balanceString: "?.??"
|
||||||
property alias balanceLabelText: balanceLabel.text
|
property string balanceUnlockedString: "?.??"
|
||||||
property alias balanceText: balanceText.text
|
property string balanceFiatString: "?.??"
|
||||||
property alias balanceTextFiat: balanceTextFiat.text
|
property string minutesToUnlock: ""
|
||||||
property alias unlockedBalanceTextFiat: unlockedBalanceTextFiat.text
|
property bool isSyncing: false
|
||||||
property alias networkStatus : networkStatus
|
property alias networkStatus : networkStatus
|
||||||
property alias progressBar : progressBar
|
property alias progressBar : progressBar
|
||||||
property alias daemonProgressBar : daemonProgressBar
|
property alias daemonProgressBar : daemonProgressBar
|
||||||
property alias minutesToUnlockTxt: unlockedBalanceLabel.text
|
|
||||||
property int titleBarHeight: 50
|
property int titleBarHeight: 50
|
||||||
property string copyValue: ""
|
property string copyValue: ""
|
||||||
Clipboard { id: clipboard }
|
Clipboard { id: clipboard }
|
||||||
@@ -84,7 +84,7 @@ Rectangle {
|
|||||||
menuColumn.previousButton.checked = true
|
menuColumn.previousButton.checked = true
|
||||||
}
|
}
|
||||||
|
|
||||||
width: (isMobile)? appWindow.width : 300
|
width: 300
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
@@ -108,7 +108,7 @@ Rectangle {
|
|||||||
visible: true
|
visible: true
|
||||||
z: 2
|
z: 2
|
||||||
id: column1
|
id: column1
|
||||||
height: 210
|
height: 175
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
@@ -127,9 +127,9 @@ Rectangle {
|
|||||||
id: card
|
id: card
|
||||||
visible: !isOpenGL || MoneroComponents.Style.blackTheme
|
visible: !isOpenGL || MoneroComponents.Style.blackTheme
|
||||||
width: 260
|
width: 260
|
||||||
height: 170
|
height: 135
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: "qrc:///images/card-background.png"
|
source: MoneroComponents.Style.blackTheme ? "qrc:///images/card-background-black.png" : "qrc:///images/card-background-white.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
DropShadow {
|
DropShadow {
|
||||||
@@ -171,57 +171,6 @@ Rectangle {
|
|||||||
color: "#ff9323"
|
color: "#ff9323"
|
||||||
themeTransition: false
|
themeTransition: false
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
height: (logoutImage.height + 8)
|
|
||||||
width: (logoutImage.width + 8)
|
|
||||||
color: "transparent"
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 8
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 25
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: logoutImage
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
height: 16
|
|
||||||
width: 13
|
|
||||||
source: "qrc:///images/logout.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea{
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
middlePanel.addressBookView.clearFields();
|
|
||||||
middlePanel.transferView.clearFields();
|
|
||||||
middlePanel.receiveView.clearFields();
|
|
||||||
appWindow.showWizard();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MoneroComponents.Label {
|
|
||||||
fontSize: 20
|
|
||||||
text: "¥"
|
|
||||||
color: "white"
|
|
||||||
visible: persistentSettings.fiatPriceEnabled
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 45
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 28
|
|
||||||
themeTransition: false
|
|
||||||
|
|
||||||
MouseArea{
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
persistentSettings.fiatPriceToggle = !persistentSettings.fiatPriceToggle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@@ -232,177 +181,151 @@ Rectangle {
|
|||||||
height: 490
|
height: 490
|
||||||
width: 50
|
width: 50
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
MoneroComponents.Label {
|
||||||
visible: !(persistentSettings.fiatPriceToggle && persistentSettings.fiatPriceEnabled)
|
fontSize: 12
|
||||||
id: balanceText
|
id: accountIndex
|
||||||
themeTransition: false
|
text: qsTr("Account") + translationManager.emptyString + " #" + currentAccountIndex
|
||||||
|
color: MoneroComponents.Style.blackTheme ? "white" : "black"
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 20
|
anchors.leftMargin: 60
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 76
|
anchors.topMargin: 23
|
||||||
font.family: "Arial"
|
|
||||||
color: "#FFFFFF"
|
|
||||||
text: "N/A"
|
|
||||||
// dynamically adjust text size
|
|
||||||
font.pixelSize: {
|
|
||||||
if (persistentSettings.hideBalance) {
|
|
||||||
return 20;
|
|
||||||
}
|
|
||||||
var digits = text.split('.')[0].length
|
|
||||||
var defaultSize = 22;
|
|
||||||
if(digits > 2) {
|
|
||||||
return defaultSize - 1.1*digits
|
|
||||||
}
|
|
||||||
return defaultSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
hoverEnabled: true
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onEntered: {
|
|
||||||
parent.color = MoneroComponents.Style.orange
|
|
||||||
}
|
|
||||||
onExited: {
|
|
||||||
parent.color = MoneroComponents.Style.white
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
console.log("Copied to clipboard");
|
|
||||||
clipboard.setText(parent.text);
|
|
||||||
appWindow.showStatusMessage(qsTr("Copied to clipboard"),3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
visible: !balanceText.visible
|
|
||||||
id: balanceTextFiat
|
|
||||||
themeTransition: false
|
themeTransition: false
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 20
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 76
|
|
||||||
font.family: "Arial"
|
|
||||||
color: "#FFFFFF"
|
|
||||||
text: "N/A"
|
|
||||||
font.pixelSize: balanceText.font.pixelSize
|
|
||||||
MouseArea {
|
|
||||||
hoverEnabled: true
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onEntered: {
|
|
||||||
parent.color = MoneroComponents.Style.orange
|
|
||||||
}
|
|
||||||
onExited: {
|
|
||||||
parent.color = MoneroComponents.Style.white
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
console.log("Copied to clipboard");
|
|
||||||
clipboard.setText(parent.text);
|
|
||||||
appWindow.showStatusMessage(qsTr("Copied to clipboard"),3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
MouseArea{
|
||||||
id: unlockedBalanceText
|
|
||||||
visible: !(persistentSettings.fiatPriceToggle && persistentSettings.fiatPriceEnabled)
|
|
||||||
themeTransition: false
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 20
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 126
|
|
||||||
font.family: "Arial"
|
|
||||||
color: "#FFFFFF"
|
|
||||||
text: "N/A"
|
|
||||||
// dynamically adjust text size
|
|
||||||
font.pixelSize: {
|
|
||||||
if (persistentSettings.hideBalance) {
|
|
||||||
return 20;
|
|
||||||
}
|
|
||||||
var digits = text.split('.')[0].length
|
|
||||||
var defaultSize = 20;
|
|
||||||
if(digits > 3) {
|
|
||||||
return defaultSize - 0.6*digits
|
|
||||||
}
|
|
||||||
return defaultSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
hoverEnabled: true
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onEntered: {
|
|
||||||
parent.color = MoneroComponents.Style.orange
|
|
||||||
}
|
|
||||||
onExited: {
|
|
||||||
parent.color = MoneroComponents.Style.white
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
console.log("Copied to clipboard");
|
|
||||||
clipboard.setText(parent.text);
|
|
||||||
appWindow.showStatusMessage(qsTr("Copied to clipboard"),3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
id: unlockedBalanceTextFiat
|
|
||||||
themeTransition: false
|
|
||||||
visible: !unlockedBalanceText.visible
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 20
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 126
|
|
||||||
font.family: "Arial"
|
|
||||||
color: "#FFFFFF"
|
|
||||||
text: "N/A"
|
|
||||||
font.pixelSize: unlockedBalanceText.font.pixelSize
|
|
||||||
MouseArea {
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onEntered: {
|
onClicked: appWindow.showPageRequest("Account")
|
||||||
parent.color = MoneroComponents.Style.orange
|
|
||||||
}
|
|
||||||
onExited: {
|
|
||||||
parent.color = MoneroComponents.Style.white
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
console.log("Copied to clipboard");
|
|
||||||
clipboard.setText(parent.text);
|
|
||||||
appWindow.showStatusMessage(qsTr("Copied to clipboard"),3)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.Label {
|
MoneroComponents.Label {
|
||||||
id: unlockedBalanceLabel
|
fontSize: 16
|
||||||
visible: true
|
id: accountLabel
|
||||||
text: qsTr("Unlocked balance") + translationManager.emptyString
|
textWidth: 170
|
||||||
color: "white"
|
color: MoneroComponents.Style.blackTheme ? "white" : "black"
|
||||||
fontSize: 14
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 20
|
anchors.leftMargin: 60
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 110
|
anchors.topMargin: 36
|
||||||
themeTransition: false
|
themeTransition: false
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.Label {
|
|
||||||
visible: !isMobile
|
|
||||||
id: balanceLabel
|
|
||||||
text: qsTr("Balance") + translationManager.emptyString
|
|
||||||
color: "white"
|
|
||||||
fontSize: 14
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 20
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 60
|
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
textWidth: 238
|
|
||||||
|
MouseArea {
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: appWindow.showPageRequest("Account")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.Label {
|
||||||
|
fontSize: 16
|
||||||
|
visible: isSyncing
|
||||||
|
text: qsTr("Syncing...")
|
||||||
|
color: MoneroComponents.Style.blackTheme ? "white" : "black"
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 20
|
||||||
|
anchors.bottom: currencyLabel.top
|
||||||
|
anchors.bottomMargin: 15
|
||||||
themeTransition: false
|
themeTransition: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoneroComponents.TextPlain {
|
||||||
|
id: currencyLabel
|
||||||
|
font.pixelSize: 16
|
||||||
|
text: {
|
||||||
|
if (persistentSettings.fiatPriceEnabled && persistentSettings.fiatPriceToggle) {
|
||||||
|
return appWindow.fiatApiCurrencySymbol();
|
||||||
|
} else {
|
||||||
|
return "XMR"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
color: MoneroComponents.Style.blackTheme ? "white" : "black"
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 20
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 100
|
||||||
|
themeTransition: false
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: persistentSettings.fiatPriceEnabled
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: persistentSettings.fiatPriceToggle = !persistentSettings.fiatPriceToggle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.TextPlain {
|
||||||
|
id: balancePart1
|
||||||
|
themeTransition: false
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 58
|
||||||
|
anchors.baseline: currencyLabel.baseline
|
||||||
|
color: MoneroComponents.Style.blackTheme ? "white" : "black"
|
||||||
|
text: {
|
||||||
|
if (persistentSettings.fiatPriceEnabled && persistentSettings.fiatPriceToggle) {
|
||||||
|
return balanceFiatString.split('.')[0] + "."
|
||||||
|
} else {
|
||||||
|
return balanceString.split('.')[0] + "."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
font.pixelSize: {
|
||||||
|
var defaultSize = 29;
|
||||||
|
var digits = (balancePart1.text.length - 1)
|
||||||
|
if (digits > 2 && !(persistentSettings.fiatPriceEnabled && persistentSettings.fiatPriceToggle)) {
|
||||||
|
return defaultSize - 1.1 * digits
|
||||||
|
} else {
|
||||||
|
return defaultSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
id: balancePart1MouseArea
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onEntered: {
|
||||||
|
balancePart1.color = MoneroComponents.Style.orange
|
||||||
|
balancePart2.color = MoneroComponents.Style.orange
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
balancePart1.color = Qt.binding(function() { return MoneroComponents.Style.blackTheme ? "white" : "black" })
|
||||||
|
balancePart2.color = Qt.binding(function() { return MoneroComponents.Style.blackTheme ? "white" : "black" })
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
console.log("Copied to clipboard");
|
||||||
|
clipboard.setText(balancePart1.text + balancePart2.text);
|
||||||
|
appWindow.showStatusMessage(qsTr("Copied to clipboard"),3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MoneroComponents.TextPlain {
|
||||||
|
id: balancePart2
|
||||||
|
themeTransition: false
|
||||||
|
anchors.left: balancePart1.right
|
||||||
|
anchors.leftMargin: 2
|
||||||
|
anchors.baseline: currencyLabel.baseline
|
||||||
|
color: MoneroComponents.Style.blackTheme ? "white" : "black"
|
||||||
|
text: {
|
||||||
|
if (persistentSettings.fiatPriceEnabled && persistentSettings.fiatPriceToggle) {
|
||||||
|
return balanceFiatString.split('.')[1]
|
||||||
|
} else {
|
||||||
|
return balanceString.split('.')[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
font.pixelSize: 16
|
||||||
|
MouseArea {
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onEntered: balancePart1MouseArea.entered()
|
||||||
|
onExited: balancePart1MouseArea.exited()
|
||||||
|
onClicked: balancePart1MouseArea.clicked(mouse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Item { //separator
|
Item { //separator
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -418,7 +341,7 @@ Rectangle {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.top: (isMobile)? parent.top : column1.bottom
|
anchors.top: column1.bottom
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
|
|||||||
@@ -46,11 +46,6 @@ Rectangle {
|
|||||||
|
|
||||||
property Item currentView
|
property Item currentView
|
||||||
property Item previousView
|
property Item previousView
|
||||||
property bool basicMode : isMobile
|
|
||||||
property string balanceLabelText: qsTr("Balance") + translationManager.emptyString
|
|
||||||
property string balanceText
|
|
||||||
property string unlockedBalanceLabelText: qsTr("Unlocked Balance") + translationManager.emptyString
|
|
||||||
property string unlockedBalanceText
|
|
||||||
property int minHeight: (appWindow.height > 800) ? appWindow.height : 800
|
property int minHeight: (appWindow.height > 800) ? appWindow.height : 800
|
||||||
property alias contentHeight: mainFlickable.contentHeight
|
property alias contentHeight: mainFlickable.contentHeight
|
||||||
property alias flickable: mainFlickable
|
property alias flickable: mainFlickable
|
||||||
@@ -173,23 +168,6 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
// color stripe at the top
|
|
||||||
Row {
|
|
||||||
id: styledRow
|
|
||||||
visible: currentView !== merchantView
|
|
||||||
height: 4
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
z: parent.z + 1
|
|
||||||
|
|
||||||
Rectangle { height: 4; width: parent.width / 5; color: "#FFE00A" }
|
|
||||||
Rectangle { height: 4; width: parent.width / 5; color: "#6B0072" }
|
|
||||||
Rectangle { height: 4; width: parent.width / 5; color: "#FF6C3C" }
|
|
||||||
Rectangle { height: 4; width: parent.width / 5; color: "#FFD781" }
|
|
||||||
Rectangle { height: 4; width: parent.width / 5; color: "#FF4F41" }
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: {
|
anchors.margins: {
|
||||||
@@ -200,6 +178,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
anchors.topMargin: appWindow.persistentSettings.customDecorations ? 50 : 0
|
anchors.topMargin: appWindow.persistentSettings.customDecorations ? 50 : 0
|
||||||
|
anchors.bottomMargin: 0
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
@@ -258,7 +237,7 @@ Rectangle {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
id: borderLeft
|
id: borderLeft
|
||||||
visible: middlePanel.state !== "Merchant"
|
visible: middlePanel.state !== "Merchant"
|
||||||
anchors.top: styledRow.bottom
|
anchors.top: parent.top
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
width: 1
|
width: 1
|
||||||
|
|||||||
10
README.md
@@ -9,7 +9,7 @@ Copyright (c) 2014-2019, The Monero Project
|
|||||||
- Mail: [dev@getmonero.org](mailto:dev@getmonero.org)
|
- Mail: [dev@getmonero.org](mailto:dev@getmonero.org)
|
||||||
- Github: [https://github.com/monero-project/monero-gui](https://github.com/monero-project/monero-gui)
|
- Github: [https://github.com/monero-project/monero-gui](https://github.com/monero-project/monero-gui)
|
||||||
- IRC: [#monero-dev on Freenode](irc://chat.freenode.net/#monero-dev)
|
- IRC: [#monero-dev on Freenode](irc://chat.freenode.net/#monero-dev)
|
||||||
- Translation platform (Pootle): [translate.getmonero.org](https://translate.getmonero.org)
|
- Translation platform (Weblate): [translate.getmonero.org](https://translate.getmonero.org)
|
||||||
|
|
||||||
## Vulnerability response
|
## Vulnerability response
|
||||||
|
|
||||||
@@ -75,6 +75,8 @@ Packaging for your favorite distribution would be a welcome contribution!
|
|||||||
|
|
||||||
## Compiling the Monero GUI from source
|
## Compiling the Monero GUI from source
|
||||||
|
|
||||||
|
*Note*: Qt 5.9.7 is the minimum version required to build the GUI.
|
||||||
|
|
||||||
### On Linux:
|
### On Linux:
|
||||||
|
|
||||||
(Tested on Ubuntu 17.10 x64, Ubuntu 18.04 x64 and Gentoo x64)
|
(Tested on Ubuntu 17.10 x64, Ubuntu 18.04 x64 and Gentoo x64)
|
||||||
@@ -83,7 +85,7 @@ Packaging for your favorite distribution would be a welcome contribution!
|
|||||||
|
|
||||||
- For Debian distributions (Debian, Ubuntu, Mint, Tails...)
|
- For Debian distributions (Debian, Ubuntu, Mint, Tails...)
|
||||||
|
|
||||||
`sudo apt install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev`
|
`sudo apt install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev`
|
||||||
|
|
||||||
- For Gentoo
|
- For Gentoo
|
||||||
|
|
||||||
@@ -91,11 +93,11 @@ Packaging for your favorite distribution would be a welcome contribution!
|
|||||||
|
|
||||||
- For Fedora
|
- For Fedora
|
||||||
|
|
||||||
`sudo dnf install make automake cmake gcc-c++ boost-devel miniupnpc-devel graphviz doxygen unbound-devel libunwind-devel pkgconfig openssl-devel libcurl-devel hidapi-devel libusb-devel`
|
`sudo dnf install make automake cmake gcc-c++ boost-devel miniupnpc-devel graphviz doxygen unbound-devel libunwind-devel pkgconfig openssl-devel libcurl-devel hidapi-devel libusb-devel zeromq-devel`
|
||||||
|
|
||||||
2. Install Qt:
|
2. Install Qt:
|
||||||
|
|
||||||
*Note*: Qt 5.9.7 is the minimum version required to build the GUI. This makes **some** distributions (mostly based on debian, like Ubuntu 16.x or Linux Mint 18.x) obsolete due to their repositories containing an older Qt version.
|
*Note*: The Qt 5.9.7 or newer requirement makes **some** distributions (mostly based on debian, like Ubuntu 16.x or Linux Mint 18.x) obsolete due to their repositories containing an older Qt version.
|
||||||
|
|
||||||
The recommended way is to install 5.9.7 from the [official Qt installer](https://www.qt.io/download-qt-installer) or [compiling it yourself](https://wiki.qt.io/Install_Qt_5_on_Ubuntu). This ensures you have the correct version. Higher versions *can* work but as it differs from our production build target, slight differences may occur.
|
The recommended way is to install 5.9.7 from the [official Qt installer](https://www.qt.io/download-qt-installer) or [compiling it yourself](https://wiki.qt.io/Install_Qt_5_on_Ubuntu). This ensures you have the correct version. Higher versions *can* work but as it differs from our production build target, slight differences may occur.
|
||||||
|
|
||||||
|
|||||||
@@ -38,8 +38,10 @@ Item {
|
|||||||
property alias text: label.text
|
property alias text: label.text
|
||||||
property string checkedIcon: "qrc:///images/check-white.svg"
|
property string checkedIcon: "qrc:///images/check-white.svg"
|
||||||
property string uncheckedIcon
|
property string uncheckedIcon
|
||||||
|
property bool fontAwesomeIcons: false
|
||||||
property int imgWidth: 13
|
property int imgWidth: 13
|
||||||
property int imgHeight: 13
|
property int imgHeight: 13
|
||||||
|
property bool toggleOnClick: true
|
||||||
property bool checked: false
|
property bool checked: false
|
||||||
property alias background: backgroundRect.color
|
property alias background: backgroundRect.color
|
||||||
property bool border: true
|
property bool border: true
|
||||||
@@ -51,14 +53,16 @@ Item {
|
|||||||
width: checkBoxLayout.width
|
width: checkBoxLayout.width
|
||||||
|
|
||||||
function toggle(){
|
function toggle(){
|
||||||
checkBox.checked = !checkBox.checked
|
if (checkBox.toggleOnClick) {
|
||||||
|
checkBox.checked = !checkBox.checked
|
||||||
|
}
|
||||||
checkBox.clicked()
|
checkBox.clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: checkBoxLayout
|
id: checkBoxLayout
|
||||||
layoutDirection: iconOnTheLeft ? Qt.LeftToRight : Qt.RightToLeft
|
layoutDirection: iconOnTheLeft ? Qt.LeftToRight : Qt.RightToLeft
|
||||||
spacing: (!isMobile ? 10 : 8)
|
spacing: 10
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: checkMark
|
id: checkMark
|
||||||
@@ -86,9 +90,11 @@ Item {
|
|||||||
width: checkBox.imgWidth
|
width: checkBox.imgWidth
|
||||||
height: checkBox.imgHeight
|
height: checkBox.imgHeight
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
fontAwesomeFallbackIcon: FontAwesome.plus
|
fontAwesomeFallbackIcon: checkBox.fontAwesomeIcons ? getIcon() : FontAwesome.plus
|
||||||
fontAwesomeFallbackSize: 14
|
fontAwesomeFallbackSize: 14
|
||||||
image: {
|
image: checkBox.fontAwesomeIcons ? "" : getIcon()
|
||||||
|
|
||||||
|
function getIcon() {
|
||||||
if (checkBox.checked || checkBox.uncheckedIcon == "")
|
if (checkBox.checked || checkBox.uncheckedIcon == "")
|
||||||
return checkBox.checkedIcon;
|
return checkBox.checkedIcon;
|
||||||
return checkBox.uncheckedIcon;
|
return checkBox.uncheckedIcon;
|
||||||
|
|||||||
40
components/ContextMenu.qml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
|
||||||
|
import FontAwesome 1.0
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
signal paste()
|
||||||
|
|
||||||
|
id: root
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if (mouse.button === Qt.RightButton)
|
||||||
|
contextMenu.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
id: contextMenu
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
border.color: MoneroComponents.Style.buttonBackgroundColorDisabledHover
|
||||||
|
border.width: 1
|
||||||
|
radius: 2
|
||||||
|
color: MoneroComponents.Style.buttonBackgroundColorDisabled
|
||||||
|
}
|
||||||
|
|
||||||
|
padding: 1
|
||||||
|
width: 100
|
||||||
|
x: root.mouseX
|
||||||
|
y: root.mouseY
|
||||||
|
|
||||||
|
MoneroComponents.ContextMenuItem {
|
||||||
|
enabled: root.parent.canPaste === true
|
||||||
|
glyphIcon: FontAwesome.paste
|
||||||
|
onTriggered: root.paste()
|
||||||
|
text: qsTr("Paste") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
52
components/ContextMenuItem.qml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import FontAwesome 1.0
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
id: menuItem
|
||||||
|
|
||||||
|
property bool glyphIconSolid: true
|
||||||
|
property alias glyphIcon: glyphIcon.text
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: MoneroComponents.Style.buttonBackgroundColorDisabledHover
|
||||||
|
opacity: mouse.containsMouse ? 1 : 0
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouse
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: menuItem.triggered()
|
||||||
|
visible: menuItem.enabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
opacity: menuItem.enabled ? 1 : 0.4
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: glyphIcon
|
||||||
|
|
||||||
|
color: MoneroComponents.Style.buttonTextColor
|
||||||
|
font.family: glyphIconSolid ? FontAwesome.fontFamilySolid : FontAwesome.fontFamily
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.styleName: glyphIconSolid ? "Solid" : "Regular"
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: MoneroComponents.Style.buttonTextColor
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: 14
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: menuItem.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -178,7 +178,11 @@ Window {
|
|||||||
onAccepted: {
|
onAccepted: {
|
||||||
if(text.length > 0) {
|
if(text.length > 0) {
|
||||||
textArea.logCommand(">>> " + text)
|
textArea.logCommand(">>> " + text)
|
||||||
daemonManager.sendCommand(text, currentWallet.nettype);
|
daemonManager.sendCommandAsync(text.split(" "), currentWallet.nettype, function(result) {
|
||||||
|
if (!result) {
|
||||||
|
appWindow.showStatusMessage(qsTr("Failed to send command"), 3);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
text = ""
|
text = ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
import QtQuick 2.9
|
import QtQuick 2.9
|
||||||
import QtQuick.Controls 1.2
|
import QtQuick.Controls 1.2
|
||||||
|
import QtQuick.Controls 2.2 as QtQuickControls2
|
||||||
import QtQuick.Layouts 1.2
|
import QtQuick.Layouts 1.2
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
import QtQuick.Controls.Styles 1.2
|
import QtQuick.Controls.Styles 1.2
|
||||||
@@ -37,8 +38,7 @@ import "effects/" as MoneroEffects
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: datePicker
|
id: datePicker
|
||||||
z: parent.z + 1
|
readonly property alias expanded: popup.visible
|
||||||
property bool expanded: false
|
|
||||||
property date currentDate
|
property date currentDate
|
||||||
property bool showCurrentDate: true
|
property bool showCurrentDate: true
|
||||||
property color backgroundColor : MoneroComponents.Style.appWindowBorderColor
|
property color backgroundColor : MoneroComponents.Style.appWindowBorderColor
|
||||||
@@ -52,19 +52,6 @@ Item {
|
|||||||
|
|
||||||
onExpandedChanged: if(expanded) appWindow.currentItem = datePicker
|
onExpandedChanged: if(expanded) appWindow.currentItem = datePicker
|
||||||
|
|
||||||
function hide() { datePicker.expanded = false }
|
|
||||||
function containsPoint(px, py) {
|
|
||||||
if(px < 0)
|
|
||||||
return false
|
|
||||||
if(px > width)
|
|
||||||
return false
|
|
||||||
if(py < 0)
|
|
||||||
return false
|
|
||||||
if(py > height + calendarRect.height)
|
|
||||||
return false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: inputLabelRect
|
id: inputLabelRect
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
@@ -253,7 +240,7 @@ Item {
|
|||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: datePicker.expanded = !datePicker.expanded
|
onClicked: datePicker.expanded ? popup.close() : popup.open()
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
}
|
}
|
||||||
@@ -261,195 +248,204 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
QtQuickControls2.Popup {
|
||||||
id: calendarRect
|
id: popup
|
||||||
anchors.left: parent.left
|
padding: 0
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: head.bottom
|
|
||||||
anchors.topMargin: 10
|
|
||||||
color: MoneroComponents.Style.middlePanelBackgroundColor
|
|
||||||
border.width: 1
|
|
||||||
border.color: MoneroComponents.Style.appWindowBorderColor
|
|
||||||
height: datePicker.expanded ? calendar.height + 2 : 0
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
Behavior on height {
|
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.left: parent.left
|
id: calendarRect
|
||||||
anchors.right: parent.right
|
width: head.width
|
||||||
anchors.leftMargin: 1
|
x: head.x
|
||||||
anchors.rightMargin: 1
|
y: head.y + head.height + 10
|
||||||
anchors.top: parent.top
|
|
||||||
color: MoneroComponents.Style.appWindowBorderColor
|
|
||||||
height: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
Calendar {
|
color: MoneroComponents.Style.middlePanelBackgroundColor
|
||||||
id: calendar
|
border.width: 1
|
||||||
anchors.left: parent.left
|
border.color: MoneroComponents.Style.appWindowBorderColor
|
||||||
anchors.right: parent.right
|
height: datePicker.expanded ? calendar.height + 2 : 0
|
||||||
anchors.top: parent.top
|
clip: true
|
||||||
anchors.margins: 1
|
|
||||||
anchors.bottomMargin: 10
|
|
||||||
height: 220
|
|
||||||
frameVisible: false
|
|
||||||
|
|
||||||
style: CalendarStyle {
|
Behavior on height {
|
||||||
gridVisible: false
|
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
||||||
background: Rectangle { color: MoneroComponents.Style.middlePanelBackgroundColor }
|
}
|
||||||
dayDelegate: Item {
|
|
||||||
z: parent.z + 1
|
|
||||||
implicitHeight: implicitWidth
|
|
||||||
implicitWidth: calendar.width / 7
|
|
||||||
|
|
||||||
Rectangle {
|
MouseArea {
|
||||||
id: dayRect
|
anchors.fill: parent
|
||||||
anchors.fill: parent
|
}
|
||||||
radius: parent.implicitHeight / 2
|
|
||||||
color: {
|
Rectangle {
|
||||||
if(dayArea.pressed && styleData.visibleMonth)
|
anchors.left: parent.left
|
||||||
return MoneroComponents.Style.blackTheme ? "#20FFFFFF" : "#10000000"
|
anchors.right: parent.right
|
||||||
return "transparent";
|
anchors.leftMargin: 1
|
||||||
|
anchors.rightMargin: 1
|
||||||
|
anchors.top: parent.top
|
||||||
|
color: MoneroComponents.Style.appWindowBorderColor
|
||||||
|
height: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Calendar {
|
||||||
|
id: calendar
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.margins: 1
|
||||||
|
anchors.bottomMargin: 10
|
||||||
|
height: 220
|
||||||
|
frameVisible: false
|
||||||
|
|
||||||
|
style: CalendarStyle {
|
||||||
|
gridVisible: false
|
||||||
|
background: Rectangle { color: MoneroComponents.Style.middlePanelBackgroundColor }
|
||||||
|
dayDelegate: Item {
|
||||||
|
z: parent.z + 1
|
||||||
|
implicitHeight: implicitWidth
|
||||||
|
implicitWidth: calendar.width / 7
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: dayRect
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: parent.implicitHeight / 2
|
||||||
|
color: {
|
||||||
|
if(dayArea.pressed && styleData.visibleMonth)
|
||||||
|
return MoneroComponents.Style.blackTheme ? "#20FFFFFF" : "#10000000"
|
||||||
|
return "transparent";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.TextPlain {
|
||||||
|
id: dayText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
font.family: MoneroComponents.Style.fontMonoRegular.name
|
||||||
|
font.pixelSize: {
|
||||||
|
if(!styleData.visibleMonth) return 12
|
||||||
|
return 14
|
||||||
|
}
|
||||||
|
font.bold: {
|
||||||
|
if(dayArea.pressed || styleData.visibleMonth) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
text: styleData.date.getDate()
|
||||||
|
themeTransition: false
|
||||||
|
color: {
|
||||||
|
if(!styleData.visibleMonth) return MoneroComponents.Style.lightGreyFontColor
|
||||||
|
if(dayArea.pressed) return MoneroComponents.Style.defaultFontColor
|
||||||
|
if(styleData.today) return MoneroComponents.Style.orange
|
||||||
|
return MoneroComponents.Style.defaultFontColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: dayArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onEntered: dayRect.color = MoneroComponents.Style.blackTheme ? "#20FFFFFF" : "#10000000"
|
||||||
|
onExited: dayRect.color = "transparent"
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
if(styleData.visibleMonth) {
|
||||||
|
currentDate = styleData.date
|
||||||
|
popup.close()
|
||||||
|
} else {
|
||||||
|
var date = styleData.date
|
||||||
|
if(date.getMonth() > calendar.visibleMonth)
|
||||||
|
calendar.showNextMonth()
|
||||||
|
else calendar.showPreviousMonth()
|
||||||
|
}
|
||||||
|
|
||||||
|
datePicker.dateChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
dayOfWeekDelegate: Item {
|
||||||
id: dayText
|
implicitHeight: 20
|
||||||
anchors.centerIn: parent
|
implicitWidth: calendar.width / 7
|
||||||
font.family: MoneroComponents.Style.fontMonoRegular.name
|
|
||||||
font.pixelSize: {
|
MoneroComponents.TextPlain {
|
||||||
if(!styleData.visibleMonth) return 12
|
anchors.centerIn: parent
|
||||||
return 14
|
elide: Text.ElideRight
|
||||||
}
|
font.family: MoneroComponents.Style.fontMonoRegular.name
|
||||||
font.bold: {
|
font.pixelSize: 12
|
||||||
if(dayArea.pressed || styleData.visibleMonth) return true;
|
color: MoneroComponents.Style.lightGreyFontColor
|
||||||
return false;
|
themeTransition: false
|
||||||
}
|
text: {
|
||||||
text: styleData.date.getDate()
|
var locale = Qt.locale()
|
||||||
themeTransition: false
|
return locale.dayName(styleData.dayOfWeek, Locale.ShortFormat)
|
||||||
color: {
|
}
|
||||||
if(!styleData.visibleMonth) return MoneroComponents.Style.lightGreyFontColor
|
|
||||||
if(dayArea.pressed) return MoneroComponents.Style.defaultFontColor
|
|
||||||
if(styleData.today) return MoneroComponents.Style.orange
|
|
||||||
return MoneroComponents.Style.defaultFontColor
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
navigationBar: Rectangle {
|
||||||
id: dayArea
|
color: MoneroComponents.Style.middlePanelBackgroundColor
|
||||||
anchors.fill: parent
|
implicitWidth: calendar.width
|
||||||
hoverEnabled: true
|
implicitHeight: 30
|
||||||
onEntered: dayRect.color = MoneroComponents.Style.blackTheme ? "#20FFFFFF" : "#10000000"
|
|
||||||
onExited: dayRect.color = "transparent"
|
MoneroComponents.TextPlain {
|
||||||
cursorShape: Qt.PointingHandCursor
|
anchors.centerIn: parent
|
||||||
onClicked: {
|
font.family: MoneroComponents.Style.fontMonoRegular.name
|
||||||
if(styleData.visibleMonth) {
|
font.pixelSize: 14
|
||||||
currentDate = styleData.date
|
color: MoneroComponents.Style.dimmedFontColor
|
||||||
datePicker.expanded = false
|
themeTransition: false
|
||||||
} else {
|
text: styleData.title
|
||||||
var date = styleData.date
|
}
|
||||||
if(date.getMonth() > calendar.visibleMonth)
|
|
||||||
calendar.showNextMonth()
|
|
||||||
else calendar.showPreviousMonth()
|
Item {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 4
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
width: height
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: prevMonthIcon
|
||||||
|
anchors.centerIn: parent
|
||||||
|
source: "qrc:///images/prevMonth.png"
|
||||||
|
visible: false
|
||||||
}
|
}
|
||||||
|
|
||||||
datePicker.dateChanged();
|
ColorOverlay {
|
||||||
}
|
source: prevMonthIcon
|
||||||
}
|
anchors.fill: prevMonthIcon
|
||||||
}
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
opacity: 0.5
|
||||||
|
}
|
||||||
|
|
||||||
dayOfWeekDelegate: Item {
|
MouseArea {
|
||||||
implicitHeight: 20
|
hoverEnabled: true
|
||||||
implicitWidth: calendar.width / 7
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
anchors.fill: parent
|
||||||
MoneroComponents.TextPlain {
|
onClicked: calendar.showPreviousMonth()
|
||||||
anchors.centerIn: parent
|
}
|
||||||
elide: Text.ElideRight
|
|
||||||
font.family: MoneroComponents.Style.fontMonoRegular.name
|
|
||||||
font.pixelSize: 12
|
|
||||||
color: MoneroComponents.Style.lightGreyFontColor
|
|
||||||
themeTransition: false
|
|
||||||
text: {
|
|
||||||
var locale = Qt.locale()
|
|
||||||
return locale.dayName(styleData.dayOfWeek, Locale.ShortFormat)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
navigationBar: Rectangle {
|
|
||||||
color: MoneroComponents.Style.middlePanelBackgroundColor
|
|
||||||
implicitWidth: calendar.width
|
|
||||||
implicitHeight: 30
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
font.family: MoneroComponents.Style.fontMonoRegular.name
|
|
||||||
font.pixelSize: 14
|
|
||||||
color: MoneroComponents.Style.dimmedFontColor
|
|
||||||
themeTransition: false
|
|
||||||
text: styleData.title
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 4
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
width: height
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: prevMonthIcon
|
|
||||||
anchors.centerIn: parent
|
|
||||||
source: "qrc:///images/prevMonth.png"
|
|
||||||
visible: false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorOverlay {
|
Item {
|
||||||
source: prevMonthIcon
|
anchors.right: parent.right
|
||||||
anchors.fill: prevMonthIcon
|
anchors.rightMargin: 4
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
anchors.top: parent.top
|
||||||
opacity: 0.5
|
anchors.bottom: parent.bottom
|
||||||
}
|
width: height
|
||||||
|
|
||||||
MouseArea {
|
Image {
|
||||||
hoverEnabled: true
|
id: nextMonthIcon
|
||||||
cursorShape: Qt.PointingHandCursor
|
anchors.centerIn: parent
|
||||||
anchors.fill: parent
|
source: "qrc:///images/prevMonth.png"
|
||||||
onClicked: calendar.showPreviousMonth()
|
visible: false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
ColorOverlay {
|
||||||
anchors.right: parent.right
|
source: nextMonthIcon
|
||||||
anchors.rightMargin: 4
|
anchors.fill: nextMonthIcon
|
||||||
anchors.top: parent.top
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
anchors.bottom: parent.bottom
|
opacity: 0.5
|
||||||
width: height
|
rotation: 180
|
||||||
|
}
|
||||||
|
|
||||||
Image {
|
MouseArea {
|
||||||
id: nextMonthIcon
|
hoverEnabled: true
|
||||||
anchors.centerIn: parent
|
cursorShape: Qt.PointingHandCursor
|
||||||
source: "qrc:///images/prevMonth.png"
|
anchors.fill: parent
|
||||||
visible: false
|
onClicked: calendar.showNextMonth()
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorOverlay {
|
|
||||||
source: nextMonthIcon
|
|
||||||
anchors.fill: nextMonthIcon
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
opacity: 0.5
|
|
||||||
rotation: 180
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: calendar.showNextMonth()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import QtQuick 2.9
|
|||||||
import "../components" as MoneroComponents
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
TextField {
|
TextField {
|
||||||
|
id: textField
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
font.pixelSize: 18
|
font.pixelSize: 18
|
||||||
font.bold: true
|
font.bold: true
|
||||||
@@ -44,4 +45,12 @@ TextField {
|
|||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoneroComponents.ContextMenu {
|
||||||
|
cursorShape: Qt.IBeamCursor
|
||||||
|
onPaste: {
|
||||||
|
textField.clear();
|
||||||
|
textField.paste();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ Item {
|
|||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
}
|
}
|
||||||
|
|
||||||
TextField {
|
MoneroComponents.Input {
|
||||||
id : input
|
id : input
|
||||||
focus: true
|
focus: true
|
||||||
Layout.topMargin: 6
|
Layout.topMargin: 6
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ TextArea {
|
|||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
if(addressValidation){
|
if(addressValidation){
|
||||||
// js replacement for `RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g }`
|
// js replacement for `RegExpValidator { regExp: /[0-9A-Fa-f]{95}/g }`
|
||||||
|
if (textArea.text.startsWith("monero:")) {
|
||||||
|
error = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
textArea.text = textArea.text.replace(/[^a-z0-9.@\-]/gi,'');
|
textArea.text = textArea.text.replace(/[^a-z0-9.@\-]/gi,'');
|
||||||
var address_ok = TxUtils.checkAddress(textArea.text, appWindow.persistentSettings.nettype) || TxUtils.isValidOpenAliasAddress(textArea.text);
|
var address_ok = TxUtils.checkAddress(textArea.text, appWindow.persistentSettings.nettype) || TxUtils.isValidOpenAliasAddress(textArea.text);
|
||||||
if(!address_ok) error = true;
|
if(!address_ok) error = true;
|
||||||
@@ -64,4 +68,12 @@ TextArea {
|
|||||||
TextArea.cursorPosition = textArea.text.length;
|
TextArea.cursorPosition = textArea.text.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoneroComponents.ContextMenu {
|
||||||
|
cursorShape: Qt.IBeamCursor
|
||||||
|
onPaste: {
|
||||||
|
textArea.clear();
|
||||||
|
textArea.paste();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ Item {
|
|||||||
property alias horizontalAlignment: label.horizontalAlignment
|
property alias horizontalAlignment: label.horizontalAlignment
|
||||||
property alias elide: label.elide
|
property alias elide: label.elide
|
||||||
property alias textWidth: label.width
|
property alias textWidth: label.width
|
||||||
|
property alias styleName: label.font.styleName
|
||||||
property alias themeTransition: label.themeTransition
|
property alias themeTransition: label.themeTransition
|
||||||
signal linkActivated()
|
signal linkActivated()
|
||||||
height: label.height
|
height: label.height
|
||||||
@@ -68,5 +69,10 @@ Item {
|
|||||||
color: fontColor
|
color: fontColor
|
||||||
onLinkActivated: item.linkActivated()
|
onLinkActivated: item.linkActivated()
|
||||||
textFormat: parent.textFormat
|
textFormat: parent.textFormat
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ Item {
|
|||||||
property alias inlineButtonText: inlineButtonId.text
|
property alias inlineButtonText: inlineButtonId.text
|
||||||
property alias inlineIcon: inlineIcon.visible
|
property alias inlineIcon: inlineIcon.visible
|
||||||
property bool copyButton: false
|
property bool copyButton: false
|
||||||
|
property alias copyButtonText: copyButtonId.text
|
||||||
|
property alias copyButtonEnabled: copyButtonId.enabled
|
||||||
|
|
||||||
property bool borderDisabled: false
|
property bool borderDisabled: false
|
||||||
property string borderColor: {
|
property string borderColor: {
|
||||||
|
|||||||
@@ -80,9 +80,6 @@ ColumnLayout {
|
|||||||
property alias readOnly: input.readOnly
|
property alias readOnly: input.readOnly
|
||||||
property bool copyButton: false
|
property bool copyButton: false
|
||||||
property bool pasteButton: false
|
property bool pasteButton: false
|
||||||
property var onPaste: function(clipboardText) {
|
|
||||||
item.text = clipboardText;
|
|
||||||
}
|
|
||||||
property bool showingHeader: labelText != "" || copyButton || pasteButton
|
property bool showingHeader: labelText != "" || copyButton || pasteButton
|
||||||
property var wrapMode: Text.NoWrap
|
property var wrapMode: Text.NoWrap
|
||||||
property alias addressValidation: input.addressValidation
|
property alias addressValidation: input.addressValidation
|
||||||
@@ -146,7 +143,10 @@ ColumnLayout {
|
|||||||
|
|
||||||
MoneroComponents.LabelButton {
|
MoneroComponents.LabelButton {
|
||||||
id: pasteButtonId
|
id: pasteButtonId
|
||||||
onClicked: item.onPaste(clipboard.text())
|
onClicked: {
|
||||||
|
input.clear();
|
||||||
|
input.paste();
|
||||||
|
}
|
||||||
text: qsTr("Paste") + translationManager.emptyString
|
text: qsTr("Paste") + translationManager.emptyString
|
||||||
visible: pasteButton
|
visible: pasteButton
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,118 +0,0 @@
|
|||||||
import QtQuick 2.9
|
|
||||||
import QtGraphicalEffects 1.0
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
|
|
||||||
import moneroComponents.Wallet 1.0
|
|
||||||
import "../components" as MoneroComponents
|
|
||||||
|
|
||||||
// BasicPanel header
|
|
||||||
Rectangle {
|
|
||||||
id: header
|
|
||||||
anchors.leftMargin: 1
|
|
||||||
anchors.rightMargin: 1
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 64
|
|
||||||
color: "#FFFFFF"
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: logo
|
|
||||||
visible: appWindow.width > 460
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: -5
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 50
|
|
||||||
source: "qrc:///images/moneroLogo2.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: icon
|
|
||||||
visible: !logo.visible
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 40
|
|
||||||
source: "qrc:///images/moneroIcon.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
Grid {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.topMargin: 10
|
|
||||||
width: 256
|
|
||||||
columns: 3
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
id: balanceLabel
|
|
||||||
width: 116
|
|
||||||
height: 20
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 12
|
|
||||||
font.letterSpacing: -1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignBottom
|
|
||||||
color: "#535353"
|
|
||||||
text: leftPanel.balanceLabelText + ":"
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
id: balanceText
|
|
||||||
width: 110
|
|
||||||
height: 20
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 18
|
|
||||||
font.letterSpacing: -1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignBottom
|
|
||||||
color: "#000000"
|
|
||||||
text: leftPanel.balanceText
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
height: 20
|
|
||||||
width: 20
|
|
||||||
|
|
||||||
Image {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.left: parent.left
|
|
||||||
source: "qrc:///images/lockIcon.png"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
width: 116
|
|
||||||
height: 20
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 12
|
|
||||||
font.letterSpacing: -1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignBottom
|
|
||||||
color: "#535353"
|
|
||||||
text: qsTr("Unlocked Balance:")
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
id: availableBalanceText
|
|
||||||
width: 110
|
|
||||||
height: 20
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 14
|
|
||||||
font.letterSpacing: -1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignBottom
|
|
||||||
color: "#000000"
|
|
||||||
text: leftPanel.unlockedBalanceText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
height: 1
|
|
||||||
color: "#DBDBDB"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
import QtQuick 2.9
|
import QtQuick 2.9
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import FontAwesome 1.0
|
||||||
import moneroComponents.Wallet 1.0
|
import moneroComponents.Wallet 1.0
|
||||||
import "../components" as MoneroComponents
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
@@ -146,6 +147,50 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.left: statusTextVal.right
|
||||||
|
anchors.leftMargin: 16
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: refreshMouseArea.containsMouse ? MoneroComponents.Style.dimmedFontColor : MoneroComponents.Style.defaultFontColor
|
||||||
|
font.family: FontAwesome.fontFamilySolid
|
||||||
|
font.pixelSize: 24
|
||||||
|
font.styleName: "Solid"
|
||||||
|
opacity: iconItem.opacity * (refreshMouseArea.visible ? 1 : 0.5)
|
||||||
|
text: FontAwesome.random
|
||||||
|
visible: (
|
||||||
|
item.connected != Wallet.ConnectionStatus_Disconnected &&
|
||||||
|
!persistentSettings.useRemoteNode &&
|
||||||
|
persistentSettings.bootstrapNodeAddress == "auto"
|
||||||
|
)
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: refreshMouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
visible: true
|
||||||
|
onClicked: {
|
||||||
|
const callback = function(result) {
|
||||||
|
refreshMouseArea.visible = true;
|
||||||
|
if (result) {
|
||||||
|
appWindow.showStatusMessage(qsTr("Successfully switched to another public node"), 3);
|
||||||
|
appWindow.currentWallet.refreshHeightAsync();
|
||||||
|
} else {
|
||||||
|
appWindow.showStatusMessage(qsTr("Failed to switch public node"), 3);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
daemonManager.sendCommandAsync(
|
||||||
|
["set_bootstrap_daemon", "auto"],
|
||||||
|
appWindow.currentWallet.nettype,
|
||||||
|
callback);
|
||||||
|
|
||||||
|
refreshMouseArea.visible = false;
|
||||||
|
appWindow.showStatusMessage(qsTr("Switching to another public node"), 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ Item {
|
|||||||
text: qsTr("CAPSLOCKS IS ON.") + translationManager.emptyString;
|
text: qsTr("CAPSLOCKS IS ON.") + translationManager.emptyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextField {
|
MoneroComponents.Input {
|
||||||
id: passwordInput1
|
id: passwordInput1
|
||||||
Layout.topMargin: 6
|
Layout.topMargin: 6
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -203,6 +203,7 @@ Item {
|
|||||||
return passwordInput2
|
return passwordInput2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
implicitHeight: 50
|
||||||
bottomPadding: 10
|
bottomPadding: 10
|
||||||
leftPadding: 10
|
leftPadding: 10
|
||||||
topPadding: 10
|
topPadding: 10
|
||||||
@@ -296,7 +297,7 @@ Item {
|
|||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
}
|
}
|
||||||
|
|
||||||
TextField {
|
MoneroComponents.Input {
|
||||||
id: passwordInput2
|
id: passwordInput2
|
||||||
visible: !passwordDialogMode
|
visible: !passwordDialogMode
|
||||||
Layout.topMargin: 6
|
Layout.topMargin: 6
|
||||||
@@ -307,6 +308,7 @@ Item {
|
|||||||
font.pixelSize: 24
|
font.pixelSize: 24
|
||||||
echoMode: TextInput.Password
|
echoMode: TextInput.Password
|
||||||
KeyNavigation.tab: okButton
|
KeyNavigation.tab: okButton
|
||||||
|
implicitHeight: 50
|
||||||
bottomPadding: 10
|
bottomPadding: 10
|
||||||
leftPadding: 10
|
leftPadding: 10
|
||||||
topPadding: 10
|
topPadding: 10
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ Item {
|
|||||||
|
|
||||||
MoneroComponents.TextPlain {
|
MoneroComponents.TextPlain {
|
||||||
id: label
|
id: label
|
||||||
Layout.leftMargin: (!isMobile ? 10 : 8)
|
Layout.leftMargin: 10
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
font.pixelSize: radioButton.fontSize
|
font.pixelSize: radioButton.fontSize
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import "../js/Utils.js" as Utils
|
|||||||
import "../components" as MoneroComponents
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
columns: (isMobile) ? 1 : 2
|
columns: 2
|
||||||
columnSpacing: 32
|
columnSpacing: 32
|
||||||
id: root
|
id: root
|
||||||
property alias daemonAddrText: daemonAddr.text
|
property alias daemonAddrText: daemonAddr.text
|
||||||
|
|||||||
65
components/SettingsListItem.qml
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
property alias buttonText: button.text
|
||||||
|
property alias description: description.text
|
||||||
|
property alias title: title.text
|
||||||
|
signal clicked()
|
||||||
|
|
||||||
|
id: settingsListItem
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
// divider
|
||||||
|
Layout.preferredHeight: 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.bottomMargin: 8
|
||||||
|
color: MoneroComponents.Style.dividerColor
|
||||||
|
opacity: MoneroComponents.Style.dividerOpacity
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
MoneroComponents.TextPlain {
|
||||||
|
id: title
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 20
|
||||||
|
Layout.topMargin: 8
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
opacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.8
|
||||||
|
font.bold: true
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: 16
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.TextPlainArea {
|
||||||
|
id: description
|
||||||
|
color: MoneroComponents.Style.dimmedFontColor
|
||||||
|
colorBlackTheme: MoneroComponents.Style._b_dimmedFontColor
|
||||||
|
colorWhiteTheme: MoneroComponents.Style._w_dimmedFontColor
|
||||||
|
Layout.fillWidth: true
|
||||||
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
id: button
|
||||||
|
small: true
|
||||||
|
onClicked: {
|
||||||
|
settingsListItem.clicked()
|
||||||
|
}
|
||||||
|
width: 135
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -82,10 +82,8 @@ Rectangle {
|
|||||||
|
|
||||||
function open() {
|
function open() {
|
||||||
// Center
|
// Center
|
||||||
if(!isMobile) {
|
root.x = parent.width/2 - root.width/2
|
||||||
root.x = parent.width/2 - root.width/2
|
root.y = 100
|
||||||
root.y = 100
|
|
||||||
}
|
|
||||||
root.z = 11
|
root.z = 11
|
||||||
root.visible = true;
|
root.visible = true;
|
||||||
}
|
}
|
||||||
@@ -96,14 +94,14 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement without hardcoding sizes
|
// TODO: implement without hardcoding sizes
|
||||||
width: isMobile ? screenWidth : 520
|
width: 520
|
||||||
height: isMobile ? screenHeight : 380
|
height: 380
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
spacing: 10
|
spacing: 10
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: (isMobile? 17 : 20)
|
anchors.margins: 20
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: column
|
id: column
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import QtQuick 2.9
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
import "../components" as MoneroComponents
|
import "../components" as MoneroComponents
|
||||||
@@ -42,7 +43,7 @@ Item {
|
|||||||
property string releasedColor: MoneroComponents.Style.titleBarButtonHoverColor
|
property string releasedColor: MoneroComponents.Style.titleBarButtonHoverColor
|
||||||
property string textColor: MoneroComponents.Style.defaultFontColor
|
property string textColor: MoneroComponents.Style.defaultFontColor
|
||||||
property alias currentIndex: columnid.currentIndex
|
property alias currentIndex: columnid.currentIndex
|
||||||
property bool expanded: false
|
readonly property alias expanded: popup.visible
|
||||||
property int dropdownHeight: 42
|
property int dropdownHeight: 42
|
||||||
property int fontHeaderSize: 16
|
property int fontHeaderSize: 16
|
||||||
property int fontItemSize: 14
|
property int fontItemSize: 14
|
||||||
@@ -56,18 +57,6 @@ Item {
|
|||||||
signal changed();
|
signal changed();
|
||||||
|
|
||||||
onExpandedChanged: if(expanded) appWindow.currentItem = dropdown
|
onExpandedChanged: if(expanded) appWindow.currentItem = dropdown
|
||||||
function hide() { dropdown.expanded = false }
|
|
||||||
function containsPoint(px, py) {
|
|
||||||
if(px < 0)
|
|
||||||
return false
|
|
||||||
if(px > width)
|
|
||||||
return false
|
|
||||||
if(py < 0)
|
|
||||||
return false
|
|
||||||
if(py > height + droplist.height)
|
|
||||||
return false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Workaroud for suspected memory leak in 5.8 causing malloc crash on app exit
|
// Workaroud for suspected memory leak in 5.8 causing malloc crash on app exit
|
||||||
function update() {
|
function update() {
|
||||||
@@ -128,118 +117,118 @@ Item {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
id: dropArea
|
id: dropArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: dropdown.expanded = !dropdown.expanded
|
onClicked: dropdown.expanded ? popup.close() : popup.open()
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Popup {
|
||||||
id: droplist
|
id: popup
|
||||||
anchors.left: parent.left
|
padding: 0
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: head.bottom
|
|
||||||
clip: true
|
|
||||||
height: dropdown.expanded ? columnid.height : 0
|
|
||||||
color: dropdown.pressedColor
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.left: parent.left
|
id: droplist
|
||||||
anchors.top: parent.top
|
x: dropdown.x
|
||||||
width: 3; height: 3
|
width: dropdown.width
|
||||||
|
y: head.y + head.height
|
||||||
|
clip: true
|
||||||
|
height: dropdown.expanded ? columnid.height : 0
|
||||||
color: dropdown.pressedColor
|
color: dropdown.pressedColor
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.right: parent.right
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
width: 3; height: 3
|
width: 3; height: 3
|
||||||
color: dropdown.pressedColor
|
color: dropdown.pressedColor
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on height {
|
Rectangle {
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
anchors.right: parent.right
|
||||||
}
|
anchors.top: parent.top
|
||||||
|
width: 3; height: 3
|
||||||
|
color: dropdown.pressedColor
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
Behavior on height {
|
||||||
id: columnid
|
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
||||||
anchors.left: parent.left
|
}
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
property int currentIndex: 0
|
|
||||||
|
|
||||||
Repeater {
|
Column {
|
||||||
id: repeater
|
id: columnid
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
property int currentIndex: 0
|
||||||
|
|
||||||
// Workaround for translations in listElements. All translated strings needs to be listed in this file.
|
Repeater {
|
||||||
property string stringLow: qsTr("Low (x1 fee)") + translationManager.emptyString
|
id: repeater
|
||||||
property string stringMedium: qsTr("Medium (x20 fee)") + translationManager.emptyString
|
|
||||||
property string stringHigh: qsTr("High (x166 fee)") + translationManager.emptyString
|
|
||||||
property string stringSlow: qsTr("Slow (x0.25 fee)") + translationManager.emptyString
|
|
||||||
property string stringDefault: qsTr("Default (x1 fee)") + translationManager.emptyString
|
|
||||||
property string stringFast: qsTr("Fast (x5 fee)") + translationManager.emptyString
|
|
||||||
property string stringFastest: qsTr("Fastest (x41.5 fee)") + translationManager.emptyString
|
|
||||||
property string stringAll: qsTr("All") + translationManager.emptyString
|
|
||||||
property string stringSent: qsTr("Sent") + translationManager.emptyString
|
|
||||||
property string stringReceived: qsTr("Received") + translationManager.emptyString
|
|
||||||
|
|
||||||
delegate: Rectangle {
|
// Workaround for translations in listElements. All translated strings needs to be listed in this file.
|
||||||
anchors.left: parent.left
|
property string stringAutomatic: qsTr("Automatic") + translationManager.emptyString
|
||||||
anchors.right: parent.right
|
property string stringSlow: qsTr("Slow (x0.2 fee)") + translationManager.emptyString
|
||||||
height: (dropdown.dropdownHeight * 0.75)
|
property string stringNormal: qsTr("Normal (x1 fee)") + translationManager.emptyString
|
||||||
//radius: index === repeater.count - 1 ? 4 : 0
|
property string stringFast: qsTr("Fast (x5 fee)") + translationManager.emptyString
|
||||||
color: itemArea.containsMouse || index === columnid.currentIndex || itemArea.containsMouse ? dropdown.releasedColor : dropdown.pressedColor
|
property string stringFastest: qsTr("Fastest (x200 fee)") + translationManager.emptyString
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
delegate: Rectangle {
|
||||||
id: col1Text
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: col2Text.left
|
|
||||||
anchors.leftMargin: 12
|
|
||||||
anchors.rightMargin: 0
|
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
|
||||||
font.bold: true
|
|
||||||
font.pixelSize: fontItemSize
|
|
||||||
color: itemArea.containsMouse || index === columnid.currentIndex || itemArea.containsMouse ? "#FA6800" : "#FFFFFF"
|
|
||||||
text: qsTr(column1) + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
id: col2Text
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: 45
|
height: (dropdown.dropdownHeight * 0.75)
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
//radius: index === repeater.count - 1 ? 4 : 0
|
||||||
font.pixelSize: 14
|
color: itemArea.containsMouse || index === columnid.currentIndex || itemArea.containsMouse ? dropdown.releasedColor : dropdown.pressedColor
|
||||||
color: "#FFFFFF"
|
|
||||||
text: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
MoneroComponents.TextPlain {
|
||||||
anchors.left: parent.left
|
id: col1Text
|
||||||
anchors.top: parent.top
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: 3; height: 3
|
anchors.left: parent.left
|
||||||
color: parent.color
|
anchors.right: col2Text.left
|
||||||
}
|
anchors.leftMargin: 12
|
||||||
|
anchors.rightMargin: 0
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: fontItemSize
|
||||||
|
color: itemArea.containsMouse || index === columnid.currentIndex || itemArea.containsMouse ? "#FA6800" : "#FFFFFF"
|
||||||
|
text: qsTr(column1) + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
MoneroComponents.TextPlain {
|
||||||
anchors.right: parent.right
|
id: col2Text
|
||||||
anchors.top: parent.top
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: 3; height: 3
|
anchors.right: parent.right
|
||||||
color: parent.color
|
anchors.rightMargin: 45
|
||||||
}
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: 14
|
||||||
|
color: "#FFFFFF"
|
||||||
|
text: ""
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
Rectangle {
|
||||||
id: itemArea
|
anchors.left: parent.left
|
||||||
anchors.fill: parent
|
anchors.top: parent.top
|
||||||
hoverEnabled: true
|
width: 3; height: 3
|
||||||
cursorShape: Qt.PointingHandCursor
|
color: parent.color
|
||||||
|
}
|
||||||
|
|
||||||
onClicked: {
|
Rectangle {
|
||||||
dropdown.expanded = false
|
anchors.right: parent.right
|
||||||
columnid.currentIndex = index
|
anchors.top: parent.top
|
||||||
changed();
|
width: 3; height: 3
|
||||||
dropdown.update()
|
color: parent.color
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: itemArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
popup.close()
|
||||||
|
columnid.currentIndex = index
|
||||||
|
changed();
|
||||||
|
dropdown.update()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ QtObject {
|
|||||||
property string titleBarBackgroundBorderColor: blackTheme ? _b_titleBarBackgroundBorderColor : _w_titleBarBackgroundBorderColor
|
property string titleBarBackgroundBorderColor: blackTheme ? _b_titleBarBackgroundBorderColor : _w_titleBarBackgroundBorderColor
|
||||||
property string titleBarLogoSource: blackTheme ? _b_titleBarLogoSource : _w_titleBarLogoSource
|
property string titleBarLogoSource: blackTheme ? _b_titleBarLogoSource : _w_titleBarLogoSource
|
||||||
property string titleBarMinimizeSource: blackTheme ? _b_titleBarMinimizeSource : _w_titleBarMinimizeSource
|
property string titleBarMinimizeSource: blackTheme ? _b_titleBarMinimizeSource : _w_titleBarMinimizeSource
|
||||||
property string titleBarExpandSource: blackTheme ? _b_titleBarExpandSource : _w_titleBarExpandSource
|
|
||||||
property string titleBarFullscreenSource: blackTheme ? _b_titleBarFullscreenSource : _w_titleBarFullscreenSource
|
property string titleBarFullscreenSource: blackTheme ? _b_titleBarFullscreenSource : _w_titleBarFullscreenSource
|
||||||
property string titleBarCloseSource: blackTheme ? _b_titleBarCloseSource : _w_titleBarCloseSource
|
property string titleBarCloseSource: blackTheme ? _b_titleBarCloseSource : _w_titleBarCloseSource
|
||||||
property string titleBarButtonHoverColor: blackTheme ? _b_titleBarButtonHoverColor : _w_titleBarButtonHoverColor
|
property string titleBarButtonHoverColor: blackTheme ? _b_titleBarButtonHoverColor : _w_titleBarButtonHoverColor
|
||||||
@@ -108,7 +107,6 @@ QtObject {
|
|||||||
property string _b_titleBarBackgroundBorderColor: "#2f2f2f"
|
property string _b_titleBarBackgroundBorderColor: "#2f2f2f"
|
||||||
property string _b_titleBarLogoSource: "qrc:///images/titlebarLogo.png"
|
property string _b_titleBarLogoSource: "qrc:///images/titlebarLogo.png"
|
||||||
property string _b_titleBarMinimizeSource: "qrc:///images/minimize.svg"
|
property string _b_titleBarMinimizeSource: "qrc:///images/minimize.svg"
|
||||||
property string _b_titleBarExpandSource: "qrc:///images/sidebar.svg"
|
|
||||||
property string _b_titleBarFullscreenSource: "qrc:///images/fullscreen.svg"
|
property string _b_titleBarFullscreenSource: "qrc:///images/fullscreen.svg"
|
||||||
property string _b_titleBarCloseSource: "qrc:///images/close.svg"
|
property string _b_titleBarCloseSource: "qrc:///images/close.svg"
|
||||||
property string _b_titleBarButtonHoverColor: "#10FFFFFF"
|
property string _b_titleBarButtonHoverColor: "#10FFFFFF"
|
||||||
@@ -165,7 +163,6 @@ QtObject {
|
|||||||
property string _w_titleBarBackgroundBorderColor: "#DEDEDE"
|
property string _w_titleBarBackgroundBorderColor: "#DEDEDE"
|
||||||
property string _w_titleBarLogoSource: "qrc:///images/themes/white/titlebarLogo.png"
|
property string _w_titleBarLogoSource: "qrc:///images/themes/white/titlebarLogo.png"
|
||||||
property string _w_titleBarMinimizeSource: "qrc:///images/themes/white/minimize.svg"
|
property string _w_titleBarMinimizeSource: "qrc:///images/themes/white/minimize.svg"
|
||||||
property string _w_titleBarExpandSource: "qrc:///images/themes/white/expand.svg"
|
|
||||||
property string _w_titleBarFullscreenSource: "qrc:///images/themes/white/fullscreen.svg"
|
property string _w_titleBarFullscreenSource: "qrc:///images/themes/white/fullscreen.svg"
|
||||||
property string _w_titleBarCloseSource: "qrc:///images/themes/white/close.svg"
|
property string _w_titleBarCloseSource: "qrc:///images/themes/white/close.svg"
|
||||||
property string _w_titleBarButtonHoverColor: "#11000000"
|
property string _w_titleBarButtonHoverColor: "#11000000"
|
||||||
|
|||||||
@@ -38,14 +38,14 @@ import "effects/" as MoneroEffects
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
property int mouseX: 0
|
property int mouseX: 0
|
||||||
property bool basicButtonVisible: false
|
|
||||||
property bool customDecorations: persistentSettings.customDecorations
|
property bool customDecorations: persistentSettings.customDecorations
|
||||||
property bool showMinimizeButton: true
|
property bool showMinimizeButton: true
|
||||||
property bool showMaximizeButton: true
|
property bool showMaximizeButton: true
|
||||||
property bool showCloseButton: true
|
property bool showCloseButton: true
|
||||||
|
property string walletName: ""
|
||||||
|
|
||||||
height: {
|
height: {
|
||||||
if(!persistentSettings.customDecorations || isMobile) return 0;
|
if(!persistentSettings.customDecorations) return 0;
|
||||||
return 50;
|
return 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,18 +56,18 @@ Rectangle {
|
|||||||
signal maximizeClicked
|
signal maximizeClicked
|
||||||
signal minimizeClicked
|
signal minimizeClicked
|
||||||
signal languageClicked
|
signal languageClicked
|
||||||
signal goToBasicVersion(bool yes)
|
signal closeWalletClicked
|
||||||
|
|
||||||
state: "default"
|
state: "default"
|
||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
name: "default";
|
name: "default";
|
||||||
PropertyChanges { target: btnSidebarCollapse; visible: true}
|
PropertyChanges { target: btnCloseWallet; visible: true}
|
||||||
PropertyChanges { target: btnLanguageToggle; visible: true}
|
PropertyChanges { target: btnLanguageToggle; visible: true}
|
||||||
}, State {
|
}, State {
|
||||||
// show only theme switcher and window controls
|
// show only theme switcher and window controls
|
||||||
name: "essentials";
|
name: "essentials";
|
||||||
PropertyChanges { target: btnSidebarCollapse; visible: false}
|
PropertyChanges { target: btnCloseWallet; visible: false}
|
||||||
PropertyChanges { target: btnLanguageToggle; visible: false}
|
PropertyChanges { target: btnLanguageToggle; visible: false}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -93,22 +93,20 @@ Rectangle {
|
|||||||
|
|
||||||
// collapse sidebar
|
// collapse sidebar
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: btnSidebarCollapse
|
id: btnCloseWallet
|
||||||
visible: root.basicButtonVisible
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
Layout.preferredWidth: parent.height
|
Layout.preferredWidth: parent.height
|
||||||
Layout.preferredHeight: parent.height
|
Layout.preferredHeight: parent.height
|
||||||
|
|
||||||
MoneroEffects.ImageMask {
|
|
||||||
|
Text {
|
||||||
|
text: FontAwesome.signOutAlt
|
||||||
|
font.family: FontAwesome.fontFamilySolid
|
||||||
|
font.pixelSize: 16
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
font.styleName: "Solid"
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
height: 14
|
|
||||||
width: 14
|
|
||||||
image: MoneroComponents.Style.titleBarExpandSource
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
fontAwesomeFallbackIcon: FontAwesome.cube
|
|
||||||
fontAwesomeFallbackSize: 14
|
|
||||||
fontAwesomeFallbackOpacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.9
|
|
||||||
opacity: 0.75
|
opacity: 0.75
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +116,7 @@ Rectangle {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onEntered: parent.color = MoneroComponents.Style.titleBarButtonHoverColor
|
onEntered: parent.color = MoneroComponents.Style.titleBarButtonHoverColor
|
||||||
onExited: parent.color = "transparent"
|
onExited: parent.color = "transparent"
|
||||||
onClicked: root.goToBasicVersion(leftPanel.visible)
|
onClicked: root.closeWalletClicked(leftPanel.visible)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,9 +129,10 @@ Rectangle {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: FontAwesome.globe
|
text: FontAwesome.globe
|
||||||
font.family: FontAwesome.fontFamily
|
font.family: FontAwesome.fontFamilySolid
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
font.styleName: "Solid"
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
opacity: 0.75
|
opacity: 0.75
|
||||||
@@ -156,9 +155,10 @@ Rectangle {
|
|||||||
Layout.preferredHeight: parent.height
|
Layout.preferredHeight: parent.height
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: MoneroComponents.Style.blackTheme ? FontAwesome.lightbulbO : FontAwesome.moonO
|
text: FontAwesome.moonO
|
||||||
font.family: FontAwesome.fontFamily
|
font.family: MoneroComponents.Style.blackTheme ? FontAwesome.fontFamilySolid : FontAwesome.fontFamily
|
||||||
font.pixelSize: 16
|
font.styleName: MoneroComponents.Style.blackTheme ? "Solid" : "Regular"
|
||||||
|
font.pixelSize: 15
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
@@ -189,6 +189,7 @@ Rectangle {
|
|||||||
|
|
||||||
// monero logo
|
// monero logo
|
||||||
Item {
|
Item {
|
||||||
|
visible: walletName.length === 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: parent.height
|
Layout.preferredHeight: parent.height
|
||||||
|
|
||||||
@@ -216,6 +217,22 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
visible: walletName.length > 0
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: parent.height
|
||||||
|
|
||||||
|
MoneroComponents.TextPlain {
|
||||||
|
font.pixelSize: 20
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
elide: Text.ElideRight
|
||||||
|
text: walletName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// minimize
|
// minimize
|
||||||
Rectangle {
|
Rectangle {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|||||||
@@ -37,26 +37,26 @@ Rectangle {
|
|||||||
source: "qrc:///images/warning.png"
|
source: "qrc:///images/warning.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
TextArea {
|
Text {
|
||||||
id: content
|
id: content
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
font.pixelSize: root.fontSize
|
font.pixelSize: root.fontSize
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
selectByMouse: true
|
|
||||||
textFormat: Text.RichText
|
textFormat: Text.RichText
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
textMargin: 0
|
|
||||||
leftPadding: 4
|
leftPadding: 4
|
||||||
rightPadding: 18
|
rightPadding: 18
|
||||||
topPadding: 10
|
topPadding: 10
|
||||||
bottomPadding: 10
|
bottomPadding: 10
|
||||||
readOnly: true
|
|
||||||
onLinkActivated: root.linkActivated();
|
onLinkActivated: root.linkActivated();
|
||||||
|
|
||||||
selectionColor: MoneroComponents.Style.textSelectionColor
|
MouseArea {
|
||||||
selectedTextColor: MoneroComponents.Style.textSelectedColor
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,9 @@ Item {
|
|||||||
id: root
|
id: root
|
||||||
property string image: ""
|
property string image: ""
|
||||||
property string color: ""
|
property string color: ""
|
||||||
property bool fontAwesomeFallbackEnabled: true
|
|
||||||
property var fontAwesomeFallbackIcon: ""
|
property var fontAwesomeFallbackIcon: ""
|
||||||
|
property string fontAwesomeFallbackFont: FontAwesome.fontFamilySolid
|
||||||
|
property string fontAwesomeFallbackStyle: "Solid"
|
||||||
property int fontAwesomeFallbackSize: 16
|
property int fontAwesomeFallbackSize: 16
|
||||||
property double fontAwesomeFallbackOpacity: 0.8
|
property double fontAwesomeFallbackOpacity: 0.8
|
||||||
property string fontAwesomeFallbackColor: MoneroComponents.Style.defaultFontColor
|
property string fontAwesomeFallbackColor: MoneroComponents.Style.defaultFontColor
|
||||||
@@ -67,15 +68,16 @@ Item {
|
|||||||
anchors.fill: root
|
anchors.fill: root
|
||||||
source: svgMask
|
source: svgMask
|
||||||
color: root.color
|
color: root.color
|
||||||
visible: isOpenGL
|
visible: image && isOpenGL
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: fontAwesomeFallback
|
id: fontAwesomeFallback
|
||||||
visible: !isOpenGL && root.fontAwesomeFallback
|
visible: !imgMockColor.visible
|
||||||
text: !isOpenGL ? root.fontAwesomeFallbackIcon : ""
|
text: root.fontAwesomeFallbackIcon
|
||||||
font.family: FontAwesome.fontFamily
|
font.family: root.fontAwesomeFallbackFont
|
||||||
font.pixelSize: root.fontAwesomeFallbackSize
|
font.pixelSize: root.fontAwesomeFallbackSize
|
||||||
|
font.styleName: root.fontAwesomeFallbackStyle
|
||||||
color: root.fontAwesomeFallbackColor
|
color: root.fontAwesomeFallbackColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|||||||
@@ -4,10 +4,23 @@ import QtQuick 2.9
|
|||||||
Object {
|
Object {
|
||||||
|
|
||||||
FontLoader {
|
FontLoader {
|
||||||
source: "./fontawesome-webfont.ttf"
|
id: regular
|
||||||
|
source: "./fa-regular-400.ttf"
|
||||||
}
|
}
|
||||||
|
|
||||||
property string fontFamily: "FontAwesome"
|
FontLoader {
|
||||||
|
id: brands
|
||||||
|
source: "./fa-brands-400.ttf"
|
||||||
|
}
|
||||||
|
|
||||||
|
FontLoader {
|
||||||
|
id: solid
|
||||||
|
source: "./fa-solid-900.ttf"
|
||||||
|
}
|
||||||
|
|
||||||
|
property string fontFamily: regular.name
|
||||||
|
property string fontFamilyBrands: brands.name
|
||||||
|
property string fontFamilySolid: solid.name
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
property string addressBook : "\uf2b9"
|
property string addressBook : "\uf2b9"
|
||||||
@@ -594,6 +607,7 @@ Object {
|
|||||||
property string shower : "\uf2cc"
|
property string shower : "\uf2cc"
|
||||||
property string signIn : "\uf090"
|
property string signIn : "\uf090"
|
||||||
property string signLanguage : "\uf2a7"
|
property string signLanguage : "\uf2a7"
|
||||||
|
property string signOutAlt : "\uf2f5"
|
||||||
property string signOut : "\uf08b"
|
property string signOut : "\uf08b"
|
||||||
property string signal : "\uf012"
|
property string signal : "\uf012"
|
||||||
property string signing : "\uf2a7"
|
property string signing : "\uf2a7"
|
||||||
|
|||||||
BIN
fonts/FontAwesome/fa-brands-400.ttf
Normal file
BIN
fonts/FontAwesome/fa-regular-400.ttf
Normal file
BIN
fonts/FontAwesome/fa-solid-900.ttf
Normal file
@@ -17,7 +17,7 @@ if [ ! -d $MONERO_DIR/src ]; then
|
|||||||
fi
|
fi
|
||||||
git submodule update --remote
|
git submodule update --remote
|
||||||
git -C $MONERO_DIR fetch
|
git -C $MONERO_DIR fetch
|
||||||
git -C $MONERO_DIR checkout v0.14.1.2
|
git -C $MONERO_DIR checkout v0.15.0.1
|
||||||
|
|
||||||
# get monero core tag
|
# get monero core tag
|
||||||
pushd $MONERO_DIR
|
pushd $MONERO_DIR
|
||||||
@@ -144,9 +144,9 @@ make_exec="make"
|
|||||||
if [ "$platform" == "darwin" ]; then
|
if [ "$platform" == "darwin" ]; then
|
||||||
echo "Configuring build for MacOS.."
|
echo "Configuring build for MacOS.."
|
||||||
if [ "$STATIC" == true ]; then
|
if [ "$STATIC" == true ]; then
|
||||||
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D BUILD_TAG="mac-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
else
|
else
|
||||||
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_TAG="mac-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
fi
|
fi
|
||||||
|
|
||||||
## LINUX 64
|
## LINUX 64
|
||||||
@@ -156,9 +156,9 @@ elif [ "$platform" == "linux64" ]; then
|
|||||||
echo "Configuring build for Android on Linux host"
|
echo "Configuring build for Android on Linux host"
|
||||||
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="armv7-a" -D ANDROID=true -D BUILD_GUI_DEPS=ON -D USE_LTO=OFF -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="armv7-a" -D ANDROID=true -D BUILD_GUI_DEPS=ON -D USE_LTO=OFF -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
elif [ "$STATIC" == true ]; then
|
elif [ "$STATIC" == true ]; then
|
||||||
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="x86-64" -D BUILD_64=ON -D BUILD_TAG="linux-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
else
|
else
|
||||||
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_TAG="linux-x64" -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
||||||
fi
|
fi
|
||||||
|
|
||||||
## LINUX 32
|
## LINUX 32
|
||||||
@@ -194,7 +194,7 @@ elif [ "$platform" == "mingw64" ]; then
|
|||||||
# Do something under Windows NT platform
|
# Do something under Windows NT platform
|
||||||
echo "Configuring build for MINGW64.."
|
echo "Configuring build for MINGW64.."
|
||||||
BOOST_ROOT=/mingw64/boost
|
BOOST_ROOT=/mingw64/boost
|
||||||
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D BOOST_ROOT="$BOOST_ROOT" -D ARCH="x86-64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" -D CMAKE_TOOLCHAIN_FILE=../../cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys64 ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D BOOST_ROOT="$BOOST_ROOT" -D ARCH="x86-64" -D BUILD_TAG="win-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" -D CMAKE_TOOLCHAIN_FILE=../../cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys64 ../..
|
||||||
|
|
||||||
## Windows 32
|
## Windows 32
|
||||||
elif [ "$platform" == "mingw32" ]; then
|
elif [ "$platform" == "mingw32" ]; then
|
||||||
@@ -253,4 +253,7 @@ if [ -d $MONERO_DIR/build/$BUILD_TYPE/external/unbound ]; then
|
|||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# install randomx
|
||||||
|
eval make -C $MONERO_DIR/build/$BUILD_TYPE/external/randomx all install
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|||||||
BIN
images/card-background-black.png
Executable file
|
After Width: | Height: | Size: 24 KiB |
BIN
images/card-background-black@2x.png
Executable file
|
After Width: | Height: | Size: 68 KiB |
BIN
images/card-background-white.png
Executable file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
images/card-background-white@2x.png
Executable file
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 419 B |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 436 B |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 612 B |
|
Before Width: | Height: | Size: 170 B |
|
Before Width: | Height: | Size: 170 B |
|
Before Width: | Height: | Size: 399 B |
|
Before Width: | Height: | Size: 760 B |
|
Before Width: | Height: | Size: 193 B |
|
Before Width: | Height: | Size: 195 B |
@@ -1,6 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="27" height="27" viewBox="0 0 27 27">
|
|
||||||
<g fill="none" fill-rule="evenodd" stroke="#FFF" stroke-linecap="round" stroke-width="1.25">
|
|
||||||
<path d="M1.595 2.19h5.357v5.358"/>
|
|
||||||
<path d="M6.682 3.021A12.49 12.49 0 0 0 1 13.5C1 20.404 6.596 26 13.5 26S26 20.404 26 13.5 20.404 1 13.5 1"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 359 B |
@@ -1,7 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="27" viewBox="0 0 22 27">
|
|
||||||
<g fill="none" fill-rule="evenodd" stroke="#FFF" stroke-linecap="round" stroke-width="1.071">
|
|
||||||
<path d="M20.412 7.818h-6.47v-6.25"/>
|
|
||||||
<path d="M21 26H1V1h12.941L21 7.818z"/>
|
|
||||||
<path d="M7.154 15.404l3.333-3.333 3.334 3.334M10.487 20.286v-7.548"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 371 B |
@@ -1,6 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
|
|
||||||
<g fill="none" fill-rule="evenodd" stroke="#FFF" stroke-width="1.636" opacity="1">
|
|
||||||
<rect width="16.364" height="16.364" x=".818" y=".818" rx="1.636"/>
|
|
||||||
<path fill="#FFF" d="M6.182 17.182V.818H1.64a.822.822 0 0 0-.822.822v14.72c0 .454.368.822.822.822h4.542z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 379 B |
@@ -1,6 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
|
|
||||||
<g fill="none" fill-rule="evenodd" opacity="1">
|
|
||||||
<path fill="none" d="M-11-11h36v36h-36z" opacity="1"/>
|
|
||||||
<path stroke="#000" stroke-linecap="round" stroke-width="1.556" d="M13 13L1.686 1.686M1 7.222V1h6.222"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 328 B |
@@ -1,6 +1,7 @@
|
|||||||
; Monero Boron Butterfly GUI Wallet Installer for Windows
|
; Monero Carbon Chamaeleon GUI Wallet Installer for Windows
|
||||||
; Copyright (c) 2017-2019, The Monero Project
|
; Copyright (c) 2017-2019, The Monero Project
|
||||||
; See LICENSE
|
; See LICENSE
|
||||||
|
#define GuiVersion GetFileVersion("bin\monero-wallet-gui.exe")
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
AppName=Monero GUI Wallet
|
AppName=Monero GUI Wallet
|
||||||
@@ -8,7 +9,8 @@ AppName=Monero GUI Wallet
|
|||||||
; Thus it's important to keep this stable over releases
|
; Thus it's important to keep this stable over releases
|
||||||
; With a different "AppName" InnoSetup would treat a mere update as a completely new application and thus mess up
|
; With a different "AppName" InnoSetup would treat a mere update as a completely new application and thus mess up
|
||||||
|
|
||||||
AppVersion=0.14.1.2
|
AppVersion={#GuiVersion}
|
||||||
|
VersionInfoVersion={#GuiVersion}
|
||||||
DefaultDirName={pf}\Monero GUI Wallet
|
DefaultDirName={pf}\Monero GUI Wallet
|
||||||
DefaultGroupName=Monero GUI Wallet
|
DefaultGroupName=Monero GUI Wallet
|
||||||
UninstallDisplayIcon={app}\monero-wallet-gui.exe
|
UninstallDisplayIcon={app}\monero-wallet-gui.exe
|
||||||
@@ -39,6 +41,8 @@ UsedUserAreasWarning=no
|
|||||||
; play a role in only in few cases as the first standard user in a Windows installation does have admin rights.
|
; play a role in only in few cases as the first standard user in a Windows installation does have admin rights.
|
||||||
; So, for the time being, this installer simply disregards this problem.
|
; So, for the time being, this installer simply disregards this problem.
|
||||||
|
|
||||||
|
[Messages]
|
||||||
|
SetupWindowTitle=%1 {#GuiVersion} Installer
|
||||||
|
|
||||||
[Languages]
|
[Languages]
|
||||||
Name: "en"; MessagesFile: "compiler:Default.isl"
|
Name: "en"; MessagesFile: "compiler:Default.isl"
|
||||||
@@ -58,14 +62,14 @@ Name: "en"; MessagesFile: "compiler:Default.isl"
|
|||||||
; .exe/.dll file possibly with version info).
|
; .exe/.dll file possibly with version info).
|
||||||
;
|
;
|
||||||
; This is far more robust than relying on version info or on file dates (flag "comparetimestamp").
|
; This is far more robust than relying on version info or on file dates (flag "comparetimestamp").
|
||||||
; As of version 0.14.1.0, the Monero .exe files do not carry version info anyway in their .exe headers.
|
; As of version 0.15.0.0, the Monero .exe files do not carry version info anyway in their .exe headers.
|
||||||
; The only small drawback seems to be somewhat longer update times because each and every file is
|
; The only small drawback seems to be somewhat longer update times because each and every file is
|
||||||
; copied again, even if already present with correct file date and identical content.
|
; copied again, even if already present with correct file date and identical content.
|
||||||
;
|
;
|
||||||
; Note that it would be very dangerous to use "ignoreversion" on files that may be shared with other
|
; Note that it would be very dangerous to use "ignoreversion" on files that may be shared with other
|
||||||
; applications somehow. Luckily this is no issue here because ALL files are "private" to Monero.
|
; applications somehow. Luckily this is no issue here because ALL files are "private" to Monero.
|
||||||
|
|
||||||
Source: "ReadMe.htm"; DestDir: "{app}"; Flags: ignoreversion
|
Source: {#file AddBackslash(SourcePath) + "ReadMe.htm"}; DestDir: "{app}"; DestName: "ReadMe.htm"; Flags: ignoreversion
|
||||||
Source: "FinishImage.bmp"; Flags: dontcopy
|
Source: "FinishImage.bmp"; Flags: dontcopy
|
||||||
|
|
||||||
; Monero GUI wallet exe and guide
|
; Monero GUI wallet exe and guide
|
||||||
@@ -197,7 +201,7 @@ begin
|
|||||||
// Additional wizard page for entering a special blockchain location
|
// Additional wizard page for entering a special blockchain location
|
||||||
blockChainDefaultDir := ExpandConstant('{commonappdata}\bitmonero');
|
blockChainDefaultDir := ExpandConstant('{commonappdata}\bitmonero');
|
||||||
s := 'The default folder to store the Monero blockchain is ' + blockChainDefaultDir;
|
s := 'The default folder to store the Monero blockchain is ' + blockChainDefaultDir;
|
||||||
s := s + '. As this will need more than 70 GB of free space, you may want to use a folder on a different drive.';
|
s := s + '. As this will need more than 74 GB of free space, you may want to use a folder on a different drive.';
|
||||||
s := s + ' If yes, specify that folder here.';
|
s := s + ' If yes, specify that folder here.';
|
||||||
|
|
||||||
BlockChainDirPage := CreateInputDirPage(wpSelectDir,
|
BlockChainDirPage := CreateInputDirPage(wpSelectDir,
|
||||||
@@ -313,7 +317,7 @@ end;
|
|||||||
; Icons in the "Monero GUI Wallet" program group
|
; Icons in the "Monero GUI Wallet" program group
|
||||||
; Windows will almost always display icons in alphabetical order, per level, so specify the text accordingly
|
; Windows will almost always display icons in alphabetical order, per level, so specify the text accordingly
|
||||||
Name: "{group}\GUI Wallet"; Filename: "{app}\monero-wallet-gui.exe";
|
Name: "{group}\GUI Wallet"; Filename: "{app}\monero-wallet-gui.exe";
|
||||||
Name: "{group}\GUI Wallet Guide"; Filename: "{app}\monero-GUI-guide.pdf"; IconFilename: "{app}\monero-wallet-gui.exe"
|
Name: "{group}\GUI Wallet Guide"; Filename: "{app}\monero-gui-wallet-guide.pdf"; IconFilename: "{app}\monero-wallet-gui.exe"
|
||||||
Name: "{group}\Uninstall GUI Wallet"; Filename: "{uninstallexe}"
|
Name: "{group}\Uninstall GUI Wallet"; Filename: "{uninstallexe}"
|
||||||
|
|
||||||
; Sub-folder "Utilities";
|
; Sub-folder "Utilities";
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ Copyright (c) 2017-2019, The Monero Project
|
|||||||
|
|
||||||
This is a *Inno Setup* script `Monero.iss` plus some related files
|
This is a *Inno Setup* script `Monero.iss` plus some related files
|
||||||
that allows you to build a standalone Windows installer (.exe) for
|
that allows you to build a standalone Windows installer (.exe) for
|
||||||
the GUI wallet that comes with the Boron Butterfly release of Monero.
|
the GUI wallet that comes with the Carbon Chamaeleon release of Monero.
|
||||||
|
|
||||||
This turns the GUI wallet into a more or less standard Windows program,
|
This turns the GUI wallet into a more or less standard Windows program,
|
||||||
by default installed into a subdirectory of `C:\Program Files`, a
|
by default installed into a subdirectory of `C:\Program Files`, a
|
||||||
@@ -18,7 +18,7 @@ Monero.
|
|||||||
As the setup script in file [Monero.iss](Monero.iss) has to list many
|
As the setup script in file [Monero.iss](Monero.iss) has to list many
|
||||||
files and directories of the GUI wallet package to install by name,
|
files and directories of the GUI wallet package to install by name,
|
||||||
this version of the script only works with exactly the GUI wallet
|
this version of the script only works with exactly the GUI wallet
|
||||||
for Monero release *Boron Butterfly* that you find on
|
for Monero release *Carbon Chamaeleon* that you find on
|
||||||
[the official download page](https://getmonero.org/downloads/).
|
[the official download page](https://getmonero.org/downloads/).
|
||||||
|
|
||||||
It should however be easy to modify the script for future
|
It should however be easy to modify the script for future
|
||||||
@@ -32,15 +32,15 @@ See [LICENSE](LICENSE).
|
|||||||
|
|
||||||
You can only build on Windows, and the result is always a
|
You can only build on Windows, and the result is always a
|
||||||
Windows .exe file that can act as a standalone installer for the
|
Windows .exe file that can act as a standalone installer for the
|
||||||
Boron Butterfly GUI wallet.
|
Carbon Chamaeleon GUI wallet.
|
||||||
|
|
||||||
Note that the installer build process is now reproducible / deterministic. For details check the file [Deterministic.md](Deterministic.md).
|
Note that the installer build process is now reproducible / deterministic. For details check the file [Deterministic.md](Deterministic.md).
|
||||||
|
|
||||||
The build steps in detail:
|
The build steps in detail:
|
||||||
|
|
||||||
1. Install *Inno Setup*. You can get it from [here](http://www.jrsoftware.org/isdl.php)
|
1. Install *Inno Setup*. You can get it from [here](http://www.jrsoftware.org/isdl.php)
|
||||||
2. Get the Inno Setup script plus related files by cloning the whole [monero-gui GitHub repository](https://github.com/monero-project/monero-gui); you will only need the files in the installer directory `installers\windows` however. Depending on development state, additionally you may have to checkout a specific branch, like `release-v0.14`.
|
2. Get the Inno Setup script plus related files by cloning the whole [monero-gui GitHub repository](https://github.com/monero-project/monero-gui); you will only need the files in the installer directory `installers\windows` however. Depending on development state, additionally instead of simply using `master` you may have to checkout a specific branch, like `release-v0.15`.
|
||||||
3. The setup script is written to take the GUI wallet files from a subdirectory named `bin`; so create `installers\windows\bin`, get the zip file of the GUI wallet from [here](https://getmonero.org/downloads/), unpack it somewhere, and copy all the files and subdirectories in the single subdirectory there (currently named `monero-gui-0.14.1.2`) to this `bin` subdirectory
|
3. The setup script is written to take the GUI wallet files from a subdirectory named `bin`; so create `installers\windows\bin`, get the zip file of the GUI wallet from [here](https://getmonero.org/downloads/), unpack it somewhere, and copy all the files and subdirectories in the single subdirectory there (currently named `monero-gui-0.15.0.0`) to this `bin` subdirectory
|
||||||
4. Start Inno Setup, load `Monero.iss` and compile it
|
4. Start Inno Setup, load `Monero.iss` and compile it
|
||||||
5. The result i.e. the finished installer will be the file `mysetup.exe` in the `installers\windows\Output` subdirectory
|
5. The result i.e. the finished installer will be the file `mysetup.exe` in the `installers\windows\Output` subdirectory
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Monero Boron Butterfly GUI Wallet</title>
|
<title>Monero Carbon Chamaeleon GUI Wallet</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body style="font-family: Arial, Helvetica, sans-serif">
|
<body style="font-family: Arial, Helvetica, sans-serif">
|
||||||
<h1>Monero Boron Butterfly GUI Wallet</h1>
|
<h1>Monero Carbon Chamaeleon GUI Wallet</h1>
|
||||||
|
|
||||||
<p>Copyright (c) 2014-2019, The Monero Project<br>
|
<p>Copyright (c) 2014-2019, The Monero Project</p>
|
||||||
Date: July 20, 2019</p>
|
|
||||||
|
|
||||||
<h2>Preface</h2>
|
<h2>Preface</h2>
|
||||||
|
|
||||||
@@ -23,7 +22,7 @@
|
|||||||
|
|
||||||
<h2>Content of the Package</h2>
|
<h2>Content of the Package</h2>
|
||||||
|
|
||||||
<p>You just installed the <i>Monero GUI wallet</i> for Windows, release Boron Butterfly, version 0.14.1.2.
|
<p>You just installed the <i>Monero GUI wallet</i> for Windows, release Carbon Chamaeleon, version {#GuiVersion}.
|
||||||
The wallet enables you to send and receive Moneroj in a secure and very private way.
|
The wallet enables you to send and receive Moneroj in a secure and very private way.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -61,7 +60,7 @@
|
|||||||
provides the most security and privacy possible for you.</p>
|
provides the most security and privacy possible for you.</p>
|
||||||
|
|
||||||
<p>However if your Internet access makes it difficult to run a full node, or if you have simply no room to store
|
<p>However if your Internet access makes it difficult to run a full node, or if you have simply no room to store
|
||||||
the blockchain locally (somewhat over 70 GB in July 2019, and of course growing), you can compromise and try to connect
|
the blockchain locally (somewhat over 74 GB in November 2019, and of course growing), you can compromise and try to connect
|
||||||
to a remote node. One way of finding such a node is checking
|
to a remote node. One way of finding such a node is checking
|
||||||
<a href="https://moneroworld.com/#nodes">this page</a>.
|
<a href="https://moneroworld.com/#nodes">this page</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 440 KiB After Width: | Height: | Size: 440 KiB |
23
js/Utils.js
@@ -46,7 +46,6 @@ function showSeedPage() {
|
|||||||
leftPanel.selectItem(middlePanel.state);
|
leftPanel.selectItem(middlePanel.state);
|
||||||
}
|
}
|
||||||
passwordDialog.open();
|
passwordDialog.open();
|
||||||
if(isMobile) hideMenu();
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,16 +93,6 @@ function netTypeToString(){
|
|||||||
return nettype == 1 ? qsTr("Testnet") : nettype == 2 ? qsTr("Stagenet") : qsTr("Mainnet");
|
return nettype == 1 ? qsTr("Testnet") : nettype == 2 ? qsTr("Stagenet") : qsTr("Mainnet");
|
||||||
}
|
}
|
||||||
|
|
||||||
function randomChoice(arr){
|
|
||||||
return arr[Math.floor(Math.random() * arr.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterNodes(nodes, port) {
|
|
||||||
if(typeof data === 'number')
|
|
||||||
port = port.toString();
|
|
||||||
return nodes.filter(function(_){return _.indexOf(port) !== -1});
|
|
||||||
}
|
|
||||||
|
|
||||||
function epoch(){
|
function epoch(){
|
||||||
return Math.floor((new Date).getTime()/1000);
|
return Math.floor((new Date).getTime()/1000);
|
||||||
}
|
}
|
||||||
@@ -144,15 +133,3 @@ function capitalize(s){
|
|||||||
if (typeof s !== 'string') return ''
|
if (typeof s !== 'string') return ''
|
||||||
return s.charAt(0).toUpperCase() + s.slice(1)
|
return s.charAt(0).toUpperCase() + s.slice(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatMoney(n, c, d, t) {
|
|
||||||
// https://stackoverflow.com/a/149099
|
|
||||||
var c = isNaN(c = Math.abs(c)) ? 2 : c,
|
|
||||||
d = d == undefined ? "." : d,
|
|
||||||
t = t == undefined ? "," : t,
|
|
||||||
s = n < 0 ? "-" : "",
|
|
||||||
i = String(parseInt(n = Math.abs(Number(n) || 0).toFixed(c))),
|
|
||||||
j = (j = i.length) > 3 ? j % 3 : 0;
|
|
||||||
|
|
||||||
return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -39,10 +39,8 @@ function switchPage(next) {
|
|||||||
console.log("switchpage: currentPage: ", currentPage);
|
console.log("switchpage: currentPage: ", currentPage);
|
||||||
|
|
||||||
// Update prev/next button positions for mobile/desktop
|
// Update prev/next button positions for mobile/desktop
|
||||||
prevButton.anchors.verticalCenter = (!isMobile) ? wizard.verticalCenter : undefined
|
prevButton.anchors.verticalCenter = wizard.verticalCenter
|
||||||
prevButton.anchors.bottom = (isMobile) ? wizard.bottom : undefined
|
nextButton.anchors.verticalCenter = wizard.verticalCenter
|
||||||
nextButton.anchors.verticalCenter = (!isMobile) ? wizard.verticalCenter : undefined
|
|
||||||
nextButton.anchors.bottom = (isMobile) ? wizard.bottom : undefined
|
|
||||||
|
|
||||||
if (currentPage > 0 || currentPage < pages.length - 1) {
|
if (currentPage > 0 || currentPage < pages.length - 1) {
|
||||||
pages[currentPage].opacity = 0
|
pages[currentPage].opacity = 0
|
||||||
|
|||||||
12
main.cpp
@@ -125,6 +125,9 @@ int main(int argc, char *argv[])
|
|||||||
// qDebug() << "High DPI auto scaling - enabled";
|
// qDebug() << "High DPI auto scaling - enabled";
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
|
// Turn off colors in monerod log output.
|
||||||
|
qputenv("TERM", "goaway");
|
||||||
|
|
||||||
MainApp app(argc, argv);
|
MainApp app(argc, argv);
|
||||||
|
|
||||||
app.setApplicationName("monero-core");
|
app.setApplicationName("monero-core");
|
||||||
@@ -171,7 +174,10 @@ int main(int argc, char *argv[])
|
|||||||
QCoreApplication::translate("main", "Log to specified file"),
|
QCoreApplication::translate("main", "Log to specified file"),
|
||||||
QCoreApplication::translate("main", "file"));
|
QCoreApplication::translate("main", "file"));
|
||||||
|
|
||||||
|
QCommandLineOption testQmlOption("test-qml");
|
||||||
|
testQmlOption.setFlags(QCommandLineOption::HiddenFromHelp);
|
||||||
parser.addOption(logPathOption);
|
parser.addOption(logPathOption);
|
||||||
|
parser.addOption(testQmlOption);
|
||||||
parser.addHelpOption();
|
parser.addHelpOption();
|
||||||
parser.process(app);
|
parser.process(app);
|
||||||
|
|
||||||
@@ -192,7 +198,9 @@ int main(int argc, char *argv[])
|
|||||||
qWarning().noquote() << "app startd" << "(log: " + logPath + ")";
|
qWarning().noquote() << "app startd" << "(log: " + logPath + ")";
|
||||||
|
|
||||||
// Desktop entry
|
// Desktop entry
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
registerXdgMime(app);
|
registerXdgMime(app);
|
||||||
|
#endif
|
||||||
|
|
||||||
IPC *ipc = new IPC(&app);
|
IPC *ipc = new IPC(&app);
|
||||||
QStringList posArgs = parser.positionalArguments();
|
QStringList posArgs = parser.positionalArguments();
|
||||||
@@ -400,6 +408,10 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QML loaded successfully.
|
||||||
|
if (parser.isSet(testQmlOption))
|
||||||
|
return 0;
|
||||||
|
|
||||||
#ifdef WITH_SCANNER
|
#ifdef WITH_SCANNER
|
||||||
QObject *qmlCamera = rootObject->findChild<QObject*>("qrCameraQML");
|
QObject *qmlCamera = rootObject->findChild<QObject*>("qrCameraQML");
|
||||||
if (qmlCamera)
|
if (qmlCamera)
|
||||||
|
|||||||
515
main.qml
@@ -47,7 +47,7 @@ import "js/Windows.js" as Windows
|
|||||||
|
|
||||||
ApplicationWindow {
|
ApplicationWindow {
|
||||||
id: appWindow
|
id: appWindow
|
||||||
title: "Monero"
|
title: "Monero" + (walletName ? " - " + walletName : "")
|
||||||
|
|
||||||
property var currentItem
|
property var currentItem
|
||||||
property bool hideBalanceForced: false
|
property bool hideBalanceForced: false
|
||||||
@@ -69,7 +69,6 @@ ApplicationWindow {
|
|||||||
property bool foundNewBlock: false
|
property bool foundNewBlock: false
|
||||||
property bool qrScannerEnabled: (typeof builtWithScanner != "undefined") && builtWithScanner
|
property bool qrScannerEnabled: (typeof builtWithScanner != "undefined") && builtWithScanner
|
||||||
property int blocksToSync: 1
|
property int blocksToSync: 1
|
||||||
property var isMobile: (appWindow.width > 700 && !isAndroid) ? false : true
|
|
||||||
property bool isMining: false
|
property bool isMining: false
|
||||||
property int walletMode: persistentSettings.walletMode
|
property int walletMode: persistentSettings.walletMode
|
||||||
property var cameraUi
|
property var cameraUi
|
||||||
@@ -87,8 +86,8 @@ ApplicationWindow {
|
|||||||
property bool themeTransition: false
|
property bool themeTransition: false
|
||||||
|
|
||||||
// fiat price conversion
|
// fiat price conversion
|
||||||
property int fiatPriceXMRUSD: 0
|
property real fiatPriceXMRUSD: 0
|
||||||
property int fiatPriceXMREUR: 0
|
property real fiatPriceXMREUR: 0
|
||||||
property var fiatPriceAPIs: {
|
property var fiatPriceAPIs: {
|
||||||
return {
|
return {
|
||||||
"kraken": {
|
"kraken": {
|
||||||
@@ -106,19 +105,6 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property string remoteNodeService: {
|
|
||||||
// support user-defined remote node aggregators
|
|
||||||
if(persistentSettings.remoteNodeService){
|
|
||||||
var service = persistentSettings.remoteNodeService;
|
|
||||||
if(service.charAt(service.length-1) !== "/")
|
|
||||||
service += "/";
|
|
||||||
return service;
|
|
||||||
}
|
|
||||||
|
|
||||||
// monero-gui workgroup maintained
|
|
||||||
return "https://autonode.xmr.pm/"
|
|
||||||
}
|
|
||||||
|
|
||||||
// true if wallet ever synchronized
|
// true if wallet ever synchronized
|
||||||
property bool walletInitialized : false
|
property bool walletInitialized : false
|
||||||
|
|
||||||
@@ -126,7 +112,6 @@ ApplicationWindow {
|
|||||||
property var current_address
|
property var current_address
|
||||||
property var current_address_label: "Primary"
|
property var current_address_label: "Primary"
|
||||||
property int current_subaddress_table_index: 0
|
property int current_subaddress_table_index: 0
|
||||||
property int current_subaddress_account_table_index: 0
|
|
||||||
|
|
||||||
function altKeyReleased() { ctrlPressed = false; }
|
function altKeyReleased() { ctrlPressed = false; }
|
||||||
|
|
||||||
@@ -239,7 +224,6 @@ ApplicationWindow {
|
|||||||
if (typeof currentWallet !== "undefined" && currentWallet !== null) {
|
if (typeof currentWallet !== "undefined" && currentWallet !== null) {
|
||||||
console.log("Daemon change - closing " + currentWallet)
|
console.log("Daemon change - closing " + currentWallet)
|
||||||
closeWallet();
|
closeWallet();
|
||||||
currentWallet = undefined
|
|
||||||
} else if (!walletInitialized) {
|
} else if (!walletInitialized) {
|
||||||
// set page to transfer if not changing daemon
|
// set page to transfer if not changing daemon
|
||||||
middlePanel.state = "Transfer";
|
middlePanel.state = "Transfer";
|
||||||
@@ -286,25 +270,31 @@ ApplicationWindow {
|
|||||||
function closeWallet(callback) {
|
function closeWallet(callback) {
|
||||||
|
|
||||||
// Disconnect all listeners
|
// Disconnect all listeners
|
||||||
if (typeof currentWallet !== "undefined" && currentWallet !== null) {
|
if (typeof currentWallet === "undefined" || currentWallet === null) {
|
||||||
currentWallet.heightRefreshed.disconnect(onHeightRefreshed);
|
if (callback) {
|
||||||
currentWallet.refreshed.disconnect(onWalletRefresh)
|
callback();
|
||||||
currentWallet.updated.disconnect(onWalletUpdate)
|
}
|
||||||
currentWallet.newBlock.disconnect(onWalletNewBlock)
|
return;
|
||||||
currentWallet.moneySpent.disconnect(onWalletMoneySent)
|
|
||||||
currentWallet.moneyReceived.disconnect(onWalletMoneyReceived)
|
|
||||||
currentWallet.unconfirmedMoneyReceived.disconnect(onWalletUnconfirmedMoneyReceived)
|
|
||||||
currentWallet.transactionCreated.disconnect(onTransactionCreated)
|
|
||||||
currentWallet.connectionStatusChanged.disconnect(onWalletConnectionStatusChanged)
|
|
||||||
currentWallet.deviceButtonRequest.disconnect(onDeviceButtonRequest);
|
|
||||||
currentWallet.deviceButtonPressed.disconnect(onDeviceButtonPressed);
|
|
||||||
currentWallet.transactionCommitted.disconnect(onTransactionCommitted);
|
|
||||||
middlePanel.paymentClicked.disconnect(handlePayment);
|
|
||||||
middlePanel.sweepUnmixableClicked.disconnect(handleSweepUnmixable);
|
|
||||||
middlePanel.getProofClicked.disconnect(handleGetProof);
|
|
||||||
middlePanel.checkProofClicked.disconnect(handleCheckProof);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentWallet.heightRefreshed.disconnect(onHeightRefreshed);
|
||||||
|
currentWallet.refreshed.disconnect(onWalletRefresh)
|
||||||
|
currentWallet.updated.disconnect(onWalletUpdate)
|
||||||
|
currentWallet.newBlock.disconnect(onWalletNewBlock)
|
||||||
|
currentWallet.moneySpent.disconnect(onWalletMoneySent)
|
||||||
|
currentWallet.moneyReceived.disconnect(onWalletMoneyReceived)
|
||||||
|
currentWallet.unconfirmedMoneyReceived.disconnect(onWalletUnconfirmedMoneyReceived)
|
||||||
|
currentWallet.transactionCreated.disconnect(onTransactionCreated)
|
||||||
|
currentWallet.connectionStatusChanged.disconnect(onWalletConnectionStatusChanged)
|
||||||
|
currentWallet.deviceButtonRequest.disconnect(onDeviceButtonRequest);
|
||||||
|
currentWallet.deviceButtonPressed.disconnect(onDeviceButtonPressed);
|
||||||
|
currentWallet.transactionCommitted.disconnect(onTransactionCommitted);
|
||||||
|
middlePanel.paymentClicked.disconnect(handlePayment);
|
||||||
|
middlePanel.sweepUnmixableClicked.disconnect(handleSweepUnmixable);
|
||||||
|
middlePanel.getProofClicked.disconnect(handleGetProof);
|
||||||
|
middlePanel.checkProofClicked.disconnect(handleCheckProof);
|
||||||
|
|
||||||
|
appWindow.walletName = "";
|
||||||
currentWallet = undefined;
|
currentWallet = undefined;
|
||||||
|
|
||||||
appWindow.showProcessingSplash(qsTr("Closing wallet..."));
|
appWindow.showProcessingSplash(qsTr("Closing wallet..."));
|
||||||
@@ -344,7 +334,6 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
walletName = usefulName(wallet.path)
|
walletName = usefulName(wallet.path)
|
||||||
updateSyncing(false)
|
|
||||||
|
|
||||||
viewOnly = currentWallet.viewOnly;
|
viewOnly = currentWallet.viewOnly;
|
||||||
|
|
||||||
@@ -385,11 +374,21 @@ ApplicationWindow {
|
|||||||
currentDaemonAddress = localDaemonAddress
|
currentDaemonAddress = localDaemonAddress
|
||||||
|
|
||||||
console.log("initializing with daemon address: ", currentDaemonAddress)
|
console.log("initializing with daemon address: ", currentDaemonAddress)
|
||||||
currentWallet.initAsync(currentDaemonAddress, 0, persistentSettings.is_recovering, persistentSettings.is_recovering_from_device, persistentSettings.restore_height);
|
currentWallet.initAsync(
|
||||||
|
currentDaemonAddress,
|
||||||
|
isTrustedDaemon(),
|
||||||
|
0,
|
||||||
|
persistentSettings.is_recovering,
|
||||||
|
persistentSettings.is_recovering_from_device,
|
||||||
|
persistentSettings.restore_height);
|
||||||
// save wallet keys in case wallet settings have been changed in the init
|
// save wallet keys in case wallet settings have been changed in the init
|
||||||
currentWallet.setPassword(walletPassword);
|
currentWallet.setPassword(walletPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isTrustedDaemon() {
|
||||||
|
return !persistentSettings.useRemoteNode || persistentSettings.is_trusted_daemon;
|
||||||
|
}
|
||||||
|
|
||||||
function walletPath() {
|
function walletPath() {
|
||||||
var wallet_path = persistentSettings.wallet_path
|
var wallet_path = persistentSettings.wallet_path
|
||||||
return wallet_path;
|
return wallet_path;
|
||||||
@@ -406,24 +405,20 @@ ApplicationWindow {
|
|||||||
if (!currentWallet)
|
if (!currentWallet)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var balance_unlocked = qsTr("HIDDEN");
|
var balance = "?.??";
|
||||||
var balance = qsTr("HIDDEN");
|
var balanceU = "?.??";
|
||||||
if(!hideBalanceForced && !persistentSettings.hideBalance){
|
if(!hideBalanceForced && !persistentSettings.hideBalance){
|
||||||
balance_unlocked = walletManager.displayAmount(currentWallet.unlockedBalance(currentWallet.currentSubaddressAccount));
|
|
||||||
balance = walletManager.displayAmount(currentWallet.balance(currentWallet.currentSubaddressAccount));
|
balance = walletManager.displayAmount(currentWallet.balance(currentWallet.currentSubaddressAccount));
|
||||||
|
balanceU = walletManager.displayAmount(currentWallet.unlockedBalance(currentWallet.currentSubaddressAccount));
|
||||||
}
|
}
|
||||||
|
|
||||||
middlePanel.unlockedBalanceText = balance_unlocked;
|
|
||||||
leftPanel.unlockedBalanceText = balance_unlocked;
|
|
||||||
middlePanel.balanceText = balance;
|
|
||||||
leftPanel.balanceText = balance;
|
|
||||||
|
|
||||||
if (persistentSettings.fiatPriceEnabled) {
|
if (persistentSettings.fiatPriceEnabled) {
|
||||||
appWindow.fiatApiUpdateBalance(balance, balance_unlocked);
|
appWindow.fiatApiUpdateBalance(balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
var accountLabel = currentWallet.getSubaddressLabel(currentWallet.currentSubaddressAccount, 0);
|
leftPanel.minutesToUnlock = (balance !== balanceU) ? currentWallet.history.minutesToUnlock : "";
|
||||||
leftPanel.balanceLabelText = qsTr("Balance (#%1%2)").arg(currentWallet.currentSubaddressAccount).arg(accountLabel === "" ? "" : (" – " + accountLabel));
|
leftPanel.balanceString = balance
|
||||||
|
leftPanel.balanceUnlockedString = balanceU
|
||||||
}
|
}
|
||||||
|
|
||||||
function onUriHandler(uri){
|
function onUriHandler(uri){
|
||||||
@@ -462,10 +457,6 @@ ApplicationWindow {
|
|||||||
// Raise window
|
// Raise window
|
||||||
appWindow.raise();
|
appWindow.raise();
|
||||||
appWindow.show();
|
appWindow.show();
|
||||||
|
|
||||||
// @TODO: remove after paymentID deprecation
|
|
||||||
if(params.hasOwnProperty("tx_payment_id"))
|
|
||||||
persistentSettings.showPid = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,15 +466,23 @@ ApplicationWindow {
|
|||||||
leftPanel.networkStatus.connected = status
|
leftPanel.networkStatus.connected = status
|
||||||
|
|
||||||
// update local daemon status.
|
// update local daemon status.
|
||||||
if(!isMobile && walletManager.isDaemonLocal(currentDaemonAddress))
|
const isDisconnected = status === Wallet.ConnectionStatus_Disconnected;
|
||||||
daemonRunning = status;
|
if (walletManager.isDaemonLocal(currentDaemonAddress)) {
|
||||||
|
daemonRunning = !isDisconnected;
|
||||||
|
} else {
|
||||||
|
daemonRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Update fee multiplier dropdown on transfer page
|
// Update fee multiplier dropdown on transfer page
|
||||||
middlePanel.transferView.updatePriorityDropdown();
|
middlePanel.transferView.updatePriorityDropdown();
|
||||||
|
|
||||||
// If wallet isnt connected, advanced wallet mode and no daemon is running - Ask
|
// If wallet isnt connected, advanced wallet mode and no daemon is running - Ask
|
||||||
if(!isMobile && appWindow.walletMode >= 2 && walletManager.isDaemonLocal(currentDaemonAddress) && !walletInitialized && status === Wallet.ConnectionStatus_Disconnected && !daemonManager.running(persistentSettings.nettype)){
|
if (appWindow.walletMode >= 2 && walletManager.isDaemonLocal(currentDaemonAddress) && !walletInitialized && isDisconnected) {
|
||||||
daemonManagerDialog.open();
|
daemonManager.runningAsync(persistentSettings.nettype, function(running) {
|
||||||
|
if (!running) {
|
||||||
|
daemonManagerDialog.open();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// initialize transaction history once wallet is initialized first time;
|
// initialize transaction history once wallet is initialized first time;
|
||||||
if (!walletInitialized) {
|
if (!walletInitialized) {
|
||||||
@@ -592,8 +591,6 @@ ApplicationWindow {
|
|||||||
foundNewBlock = false;
|
foundNewBlock = false;
|
||||||
console.log("New block found - updating history")
|
console.log("New block found - updating history")
|
||||||
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
|
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
|
||||||
var timeToUnlock = currentWallet.history.minutesToUnlock
|
|
||||||
leftPanel.minutesToUnlockTxt = (timeToUnlock > 0)? (timeToUnlock == 20)? qsTr("Unlocked balance (waiting for block)") : qsTr("Unlocked balance (~%1 min)").arg(timeToUnlock) : qsTr("Unlocked balance");
|
|
||||||
|
|
||||||
if(middlePanel.state == "History")
|
if(middlePanel.state == "History")
|
||||||
middlePanel.historyView.update();
|
middlePanel.historyView.update();
|
||||||
@@ -602,10 +599,19 @@ ApplicationWindow {
|
|||||||
|
|
||||||
function connectRemoteNode() {
|
function connectRemoteNode() {
|
||||||
console.log("connecting remote node");
|
console.log("connecting remote node");
|
||||||
persistentSettings.useRemoteNode = true;
|
|
||||||
currentDaemonAddress = persistentSettings.remoteNodeAddress;
|
const callback = function() {
|
||||||
currentWallet.initAsync(currentDaemonAddress);
|
persistentSettings.useRemoteNode = true;
|
||||||
walletManager.setDaemonAddressAsync(currentDaemonAddress);
|
currentDaemonAddress = persistentSettings.remoteNodeAddress;
|
||||||
|
currentWallet.initAsync(currentDaemonAddress, isTrustedDaemon());
|
||||||
|
walletManager.setDaemonAddressAsync(currentDaemonAddress);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof daemonManager != "undefined" && daemonRunning) {
|
||||||
|
showDaemonIsRunningDialog(callback);
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function disconnectRemoteNode() {
|
function disconnectRemoteNode() {
|
||||||
@@ -615,7 +621,7 @@ ApplicationWindow {
|
|||||||
console.log("disconnecting remote node");
|
console.log("disconnecting remote node");
|
||||||
persistentSettings.useRemoteNode = false;
|
persistentSettings.useRemoteNode = false;
|
||||||
currentDaemonAddress = localDaemonAddress
|
currentDaemonAddress = localDaemonAddress
|
||||||
currentWallet.initAsync(currentDaemonAddress);
|
currentWallet.initAsync(currentDaemonAddress, isTrustedDaemon());
|
||||||
walletManager.setDaemonAddressAsync(currentDaemonAddress);
|
walletManager.setDaemonAddressAsync(currentDaemonAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,7 +643,7 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update wallet sync progress
|
// Update wallet sync progress
|
||||||
updateSyncing((currentWallet.connected() !== Wallet.ConnectionStatus_Disconnected) && !daemonSynced)
|
leftPanel.isSyncing = (currentWallet.connected() !== Wallet.ConnectionStatus_Disconnected) && !daemonSynced
|
||||||
// Update transfer page status
|
// Update transfer page status
|
||||||
middlePanel.updateStatus();
|
middlePanel.updateStatus();
|
||||||
|
|
||||||
@@ -687,8 +693,8 @@ ApplicationWindow {
|
|||||||
simpleModeConnectionTimer.stop();
|
simpleModeConnectionTimer.stop();
|
||||||
|
|
||||||
appWindow.showProcessingSplash(qsTr("Waiting for daemon to start..."))
|
appWindow.showProcessingSplash(qsTr("Waiting for daemon to start..."))
|
||||||
daemonManager.start(flags, persistentSettings.nettype, persistentSettings.blockchainDataDir, persistentSettings.bootstrapNodeAddress);
|
const noSync = appWindow.walletMode === 0;
|
||||||
persistentSettings.daemonFlags = flags
|
daemonManager.start(flags, persistentSettings.nettype, persistentSettings.blockchainDataDir, persistentSettings.bootstrapNodeAddress, noSync);
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopDaemon(){
|
function stopDaemon(){
|
||||||
@@ -704,6 +710,7 @@ ApplicationWindow {
|
|||||||
// resume refresh
|
// resume refresh
|
||||||
currentWallet.startRefresh();
|
currentWallet.startRefresh();
|
||||||
// resume simplemode connection timer
|
// resume simplemode connection timer
|
||||||
|
appWindow.disconnectedEpoch = Utils.epoch();
|
||||||
simpleModeConnectionTimer.start();
|
simpleModeConnectionTimer.start();
|
||||||
}
|
}
|
||||||
function onDaemonStopped(){
|
function onDaemonStopped(){
|
||||||
@@ -841,7 +848,9 @@ ApplicationWindow {
|
|||||||
", priority: ", priority,
|
", priority: ", priority,
|
||||||
", description: ", description);
|
", description: ", description);
|
||||||
|
|
||||||
showProcessingSplash("Creating transaction");
|
var splashMsg = qsTr("Creating transaction...");
|
||||||
|
splashMsg += appWindow.currentWallet.isLedger() ? qsTr("\n\nPlease check your hardware wallet –\nyour input may be required.") : "";
|
||||||
|
showProcessingSplash(splashMsg);
|
||||||
|
|
||||||
transactionDescription = description;
|
transactionDescription = description;
|
||||||
|
|
||||||
@@ -1079,12 +1088,6 @@ ApplicationWindow {
|
|||||||
informationPopup.open()
|
informationPopup.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSyncing(syncing) {
|
|
||||||
var text = (syncing ? qsTr("Balance (syncing)") : qsTr("Balance")) + translationManager.emptyString
|
|
||||||
leftPanel.balanceLabelText = text
|
|
||||||
middlePanel.balanceLabelText = text
|
|
||||||
}
|
|
||||||
|
|
||||||
// blocks UI if wallet can't be opened or no connection to the daemon
|
// blocks UI if wallet can't be opened or no connection to the daemon
|
||||||
function enableUI(enable) {
|
function enableUI(enable) {
|
||||||
middlePanel.enabled = enable;
|
middlePanel.enabled = enable;
|
||||||
@@ -1119,32 +1122,19 @@ ApplicationWindow {
|
|||||||
|
|
||||||
// close wallet and show wizard
|
// close wallet and show wizard
|
||||||
function showWizard(){
|
function showWizard(){
|
||||||
clearMoneroCardLabelText();
|
|
||||||
walletInitialized = false;
|
walletInitialized = false;
|
||||||
closeWallet(function() {
|
closeWallet(function() {
|
||||||
currentWallet = undefined;
|
|
||||||
wizard.restart();
|
wizard.restart();
|
||||||
wizard.wizardState = "wizardHome";
|
wizard.wizardState = "wizardHome";
|
||||||
rootItem.state = "wizard"
|
rootItem.state = "wizard"
|
||||||
// reset balance
|
// reset balance
|
||||||
leftPanel.balanceText = leftPanel.unlockedBalanceText = walletManager.displayAmount(0);
|
clearMoneroCardLabelText();
|
||||||
fiatApiUpdateBalance(0, 0);
|
|
||||||
// disable timers
|
// disable timers
|
||||||
userInActivityTimer.running = false;
|
userInActivityTimer.running = false;
|
||||||
simpleModeConnectionTimer.running = false;
|
simpleModeConnectionTimer.running = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideMenu() {
|
|
||||||
goToBasicAnimation.start();
|
|
||||||
console.log(appWindow.width)
|
|
||||||
}
|
|
||||||
|
|
||||||
function showMenu() {
|
|
||||||
goToProAnimation.start();
|
|
||||||
console.log(appWindow.width)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
objectName: "appWindow"
|
objectName: "appWindow"
|
||||||
visible: true
|
visible: true
|
||||||
@@ -1261,22 +1251,34 @@ ApplicationWindow {
|
|||||||
Prices.getJSON(url);
|
Prices.getJSON(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fiatApiUpdateBalance(balance, unlocked_balance){
|
function fiatApiCurrencySymbol() {
|
||||||
// update balance card
|
switch (persistentSettings.fiatPriceCurrency) {
|
||||||
var ticker = persistentSettings.fiatPriceCurrency === "xmrusd" ? appWindow.fiatPriceXMRUSD : appWindow.fiatPriceXMREUR;
|
case "xmrusd":
|
||||||
var symbol = persistentSettings.fiatPriceCurrency === "xmrusd" ? "$" : "€"
|
return "USD";
|
||||||
if(ticker <= 0){
|
case "xmreur":
|
||||||
console.log(fiatApiError("Could not update balance card; invalid ticker value"));
|
return "EUR";
|
||||||
leftPanel.unlockedBalanceTextFiat = "N/A";
|
default:
|
||||||
leftPanel.balanceTextFiat = "N/A";
|
console.error("unsupported currency", persistentSettings.fiatPriceCurrency);
|
||||||
return;
|
return "UNSUPPORTED";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var uFiat = Utils.formatMoney(unlocked_balance * ticker);
|
function fiatApiConvertToFiat(amount) {
|
||||||
var bFiat = Utils.formatMoney(balance * ticker);
|
var ticker = persistentSettings.fiatPriceCurrency === "xmrusd" ? appWindow.fiatPriceXMRUSD : appWindow.fiatPriceXMREUR;
|
||||||
|
if(ticker <= 0){
|
||||||
|
console.log(fiatApiError("Invalid ticker value: " + ticker));
|
||||||
|
return "?.??";
|
||||||
|
}
|
||||||
|
return (amount * ticker).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
leftPanel.unlockedBalanceTextFiat = symbol + uFiat;
|
function fiatApiUpdateBalance(balance){
|
||||||
leftPanel.balanceTextFiat = symbol + bFiat;
|
// update balance card
|
||||||
|
var bFiat = "?.??"
|
||||||
|
if (!hideBalanceForced && !persistentSettings.hideBalance) {
|
||||||
|
bFiat = fiatApiConvertToFiat(balance);
|
||||||
|
}
|
||||||
|
leftPanel.balanceFiatString = bFiat;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fiatTimerStart(){
|
function fiatTimerStart(){
|
||||||
@@ -1294,6 +1296,9 @@ ApplicationWindow {
|
|||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
x = (Screen.width - width) / 2
|
x = (Screen.width - width) / 2
|
||||||
y = (Screen.height - maxWindowHeight) / 2
|
y = (Screen.height - maxWindowHeight) / 2
|
||||||
|
|
||||||
|
applyWalletMode(persistentSettings.walletMode);
|
||||||
|
|
||||||
//
|
//
|
||||||
walletManager.walletOpened.connect(onWalletOpened);
|
walletManager.walletOpened.connect(onWalletOpened);
|
||||||
walletManager.deviceButtonRequest.connect(onDeviceButtonRequest);
|
walletManager.deviceButtonRequest.connect(onDeviceButtonRequest);
|
||||||
@@ -1383,7 +1388,6 @@ ApplicationWindow {
|
|||||||
property bool useRemoteNode: false
|
property bool useRemoteNode: false
|
||||||
property string remoteNodeAddress: ""
|
property string remoteNodeAddress: ""
|
||||||
property string bootstrapNodeAddress: ""
|
property string bootstrapNodeAddress: ""
|
||||||
property string remoteNodeRegion: ""
|
|
||||||
property bool segregatePreForkOutputs: true
|
property bool segregatePreForkOutputs: true
|
||||||
property bool keyReuseMitigation2: true
|
property bool keyReuseMitigation2: true
|
||||||
property int segregationHeight: 0
|
property int segregationHeight: 0
|
||||||
@@ -1391,9 +1395,7 @@ ApplicationWindow {
|
|||||||
property bool hideBalance: false
|
property bool hideBalance: false
|
||||||
property bool lockOnUserInActivity: true
|
property bool lockOnUserInActivity: true
|
||||||
property int walletMode: 2
|
property int walletMode: 2
|
||||||
property string remoteNodeService: ""
|
|
||||||
property int lockOnUserInActivityInterval: 10 // minutes
|
property int lockOnUserInActivityInterval: 10 // minutes
|
||||||
property bool showPid: false
|
|
||||||
property bool blackTheme: true
|
property bool blackTheme: true
|
||||||
|
|
||||||
property bool fiatPriceEnabled: false
|
property bool fiatPriceEnabled: false
|
||||||
@@ -1592,153 +1594,96 @@ ApplicationWindow {
|
|||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
name: "wizard"
|
name: "wizard"
|
||||||
PropertyChanges { target: leftPanel; visible: false }
|
|
||||||
PropertyChanges { target: middlePanel; visible: false }
|
PropertyChanges { target: middlePanel; visible: false }
|
||||||
PropertyChanges { target: wizard; visible: true }
|
PropertyChanges { target: wizard; visible: true }
|
||||||
PropertyChanges { target: resizeArea; visible: true }
|
PropertyChanges { target: resizeArea; visible: true }
|
||||||
PropertyChanges { target: mobileHeader; visible: false }
|
|
||||||
PropertyChanges { target: titleBar; state: "essentials" }
|
PropertyChanges { target: titleBar; state: "essentials" }
|
||||||
}, State {
|
}, State {
|
||||||
name: "normal"
|
name: "normal"
|
||||||
PropertyChanges { target: leftPanel; visible: (isMobile)? false : true }
|
|
||||||
PropertyChanges { target: middlePanel; visible: true }
|
PropertyChanges { target: middlePanel; visible: true }
|
||||||
PropertyChanges { target: titleBar; basicButtonVisible: true }
|
|
||||||
PropertyChanges { target: wizard; visible: false }
|
PropertyChanges { target: wizard; visible: false }
|
||||||
PropertyChanges { target: resizeArea; visible: true }
|
PropertyChanges { target: resizeArea; visible: true }
|
||||||
PropertyChanges { target: titleBar; state: "default" }
|
PropertyChanges { target: titleBar; state: "default" }
|
||||||
PropertyChanges { target: mobileHeader; visible: isMobile ? true : false }
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
MobileHeader {
|
|
||||||
id: mobileHeader
|
|
||||||
visible: isMobile
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
height: visible? 65 : 0
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
enabled: persistentSettings.customDecorations
|
|
||||||
property var previousPosition
|
|
||||||
anchors.fill: parent
|
|
||||||
propagateComposedEvents: true
|
|
||||||
onPressed: previousPosition = globalCursor.getPosition()
|
|
||||||
onPositionChanged: {
|
|
||||||
if (pressedButtons == Qt.LeftButton) {
|
|
||||||
var pos = globalCursor.getPosition()
|
|
||||||
var dx = pos.x - previousPosition.x
|
|
||||||
var dy = pos.y - previousPosition.y
|
|
||||||
|
|
||||||
appWindow.x += dx
|
|
||||||
appWindow.y += dy
|
|
||||||
previousPosition = pos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LeftPanel {
|
LeftPanel {
|
||||||
id: leftPanel
|
id: leftPanel
|
||||||
anchors.top: mobileHeader.bottom
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
visible: rootItem.state == "normal" && middlePanel.state != "Merchant"
|
||||||
|
currentAccountIndex: currentWallet ? currentWallet.currentSubaddressAccount : 0
|
||||||
|
currentAccountLabel: {
|
||||||
|
if (currentWallet) {
|
||||||
|
return currentWallet.getSubaddressLabel(currentWallet.currentSubaddressAccount, 0);
|
||||||
|
}
|
||||||
|
return qsTr("Primary account") + translationManager.emptyString;
|
||||||
|
}
|
||||||
|
|
||||||
onTransferClicked: {
|
onTransferClicked: {
|
||||||
middlePanel.state = "Transfer";
|
middlePanel.state = "Transfer";
|
||||||
middlePanel.flickable.contentY = 0;
|
middlePanel.flickable.contentY = 0;
|
||||||
if(isMobile) {
|
|
||||||
hideMenu();
|
|
||||||
}
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
onReceiveClicked: {
|
onReceiveClicked: {
|
||||||
middlePanel.state = "Receive";
|
middlePanel.state = "Receive";
|
||||||
middlePanel.flickable.contentY = 0;
|
middlePanel.flickable.contentY = 0;
|
||||||
if(isMobile) {
|
|
||||||
hideMenu();
|
|
||||||
}
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMerchantClicked: {
|
onMerchantClicked: {
|
||||||
middlePanel.state = "Merchant";
|
middlePanel.state = "Merchant";
|
||||||
middlePanel.flickable.contentY = 0;
|
middlePanel.flickable.contentY = 0;
|
||||||
if(isMobile) {
|
|
||||||
hideMenu();
|
|
||||||
}
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
onTxkeyClicked: {
|
onTxkeyClicked: {
|
||||||
middlePanel.state = "TxKey";
|
middlePanel.state = "TxKey";
|
||||||
middlePanel.flickable.contentY = 0;
|
middlePanel.flickable.contentY = 0;
|
||||||
if(isMobile) {
|
|
||||||
hideMenu();
|
|
||||||
}
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
onSharedringdbClicked: {
|
onSharedringdbClicked: {
|
||||||
middlePanel.state = "SharedRingDB";
|
middlePanel.state = "SharedRingDB";
|
||||||
middlePanel.flickable.contentY = 0;
|
middlePanel.flickable.contentY = 0;
|
||||||
if(isMobile) {
|
|
||||||
hideMenu();
|
|
||||||
}
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
onHistoryClicked: {
|
onHistoryClicked: {
|
||||||
middlePanel.state = "History";
|
middlePanel.state = "History";
|
||||||
middlePanel.flickable.contentY = 0;
|
middlePanel.flickable.contentY = 0;
|
||||||
if(isMobile) {
|
|
||||||
hideMenu();
|
|
||||||
}
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
onAddressBookClicked: {
|
onAddressBookClicked: {
|
||||||
middlePanel.state = "AddressBook";
|
middlePanel.state = "AddressBook";
|
||||||
middlePanel.flickable.contentY = 0;
|
middlePanel.flickable.contentY = 0;
|
||||||
if(isMobile) {
|
|
||||||
hideMenu();
|
|
||||||
}
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMiningClicked: {
|
onMiningClicked: {
|
||||||
middlePanel.state = "Mining";
|
middlePanel.state = "Mining";
|
||||||
middlePanel.flickable.contentY = 0;
|
middlePanel.flickable.contentY = 0;
|
||||||
if(isMobile) {
|
|
||||||
hideMenu();
|
|
||||||
}
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
onSignClicked: {
|
onSignClicked: {
|
||||||
middlePanel.state = "Sign";
|
middlePanel.state = "Sign";
|
||||||
middlePanel.flickable.contentY = 0;
|
middlePanel.flickable.contentY = 0;
|
||||||
if(isMobile) {
|
|
||||||
hideMenu();
|
|
||||||
}
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
onSettingsClicked: {
|
onSettingsClicked: {
|
||||||
middlePanel.state = "Settings";
|
middlePanel.state = "Settings";
|
||||||
middlePanel.flickable.contentY = 0;
|
middlePanel.flickable.contentY = 0;
|
||||||
if(isMobile) {
|
|
||||||
hideMenu();
|
|
||||||
}
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
onAccountClicked: {
|
onAccountClicked: {
|
||||||
middlePanel.state = "Account";
|
middlePanel.state = "Account";
|
||||||
middlePanel.flickable.contentY = 0;
|
middlePanel.flickable.contentY = 0;
|
||||||
if(isMobile) {
|
|
||||||
hideMenu();
|
|
||||||
}
|
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1746,102 +1691,14 @@ ApplicationWindow {
|
|||||||
|
|
||||||
MiddlePanel {
|
MiddlePanel {
|
||||||
id: middlePanel
|
id: middlePanel
|
||||||
anchors.top: mobileHeader.bottom
|
accountView.currentAccountIndex: currentWallet ? currentWallet.currentSubaddressAccount : 0
|
||||||
|
anchors.top: parent.top
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: leftPanel.visible ? leftPanel.right : parent.left
|
anchors.left: leftPanel.visible ? leftPanel.right : parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
state: "Transfer"
|
state: "Transfer"
|
||||||
}
|
}
|
||||||
|
|
||||||
SequentialAnimation {
|
|
||||||
id: goToBasicAnimation
|
|
||||||
// PropertyAction {
|
|
||||||
// target: appWindow
|
|
||||||
// properties: "visibility"
|
|
||||||
// value: Window.Windowed
|
|
||||||
// }
|
|
||||||
// PropertyAction {
|
|
||||||
// target: titleBar
|
|
||||||
// properties: "maximizeButtonVisible"
|
|
||||||
// value: false
|
|
||||||
// }
|
|
||||||
// PropertyAction {
|
|
||||||
// target: frameArea
|
|
||||||
// properties: "blocked"
|
|
||||||
// value: true
|
|
||||||
// }
|
|
||||||
PropertyAction {
|
|
||||||
target: resizeArea
|
|
||||||
properties: "visible"
|
|
||||||
value: true
|
|
||||||
}
|
|
||||||
// PropertyAction {
|
|
||||||
// target: appWindow
|
|
||||||
// properties: "height"
|
|
||||||
// value: 30
|
|
||||||
// }
|
|
||||||
// PropertyAction {
|
|
||||||
// target: appWindow
|
|
||||||
// properties: "width"
|
|
||||||
// value: 326
|
|
||||||
// }
|
|
||||||
PropertyAction {
|
|
||||||
target: leftPanel
|
|
||||||
properties: "visible"
|
|
||||||
value: false
|
|
||||||
}
|
|
||||||
PropertyAction {
|
|
||||||
target: middlePanel
|
|
||||||
properties: "basicMode"
|
|
||||||
value: true
|
|
||||||
}
|
|
||||||
|
|
||||||
// PropertyAction {
|
|
||||||
// target: appWindow
|
|
||||||
// properties: "height"
|
|
||||||
// value: middlePanel.height
|
|
||||||
// }
|
|
||||||
|
|
||||||
onStopped: {
|
|
||||||
// middlePanel.visible = false
|
|
||||||
leftPanel.visible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SequentialAnimation {
|
|
||||||
id: goToProAnimation
|
|
||||||
// PropertyAction {
|
|
||||||
// target: appWindow
|
|
||||||
// properties: "height"
|
|
||||||
// value: 30
|
|
||||||
// }
|
|
||||||
PropertyAction {
|
|
||||||
target: middlePanel
|
|
||||||
properties: "basicMode"
|
|
||||||
value: false
|
|
||||||
}
|
|
||||||
PropertyAction {
|
|
||||||
targets: [leftPanel, middlePanel, resizeArea]
|
|
||||||
properties: "visible"
|
|
||||||
value: true
|
|
||||||
}
|
|
||||||
// PropertyAction {
|
|
||||||
// target: appWindow
|
|
||||||
// properties: "height"
|
|
||||||
// value: maxWindowHeight
|
|
||||||
// }
|
|
||||||
// PropertyAction {
|
|
||||||
// target: frameArea
|
|
||||||
// properties: "blocked"
|
|
||||||
// value: false
|
|
||||||
// }
|
|
||||||
// PropertyAction {
|
|
||||||
// target: titleBar
|
|
||||||
// properties: "maximizeButtonVisible"
|
|
||||||
// value: true
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardController {
|
WizardController {
|
||||||
id: wizard
|
id: wizard
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -1906,21 +1763,14 @@ ApplicationWindow {
|
|||||||
TitleBar {
|
TitleBar {
|
||||||
id: titleBar
|
id: titleBar
|
||||||
visible: persistentSettings.customDecorations && middlePanel.state !== "Merchant"
|
visible: persistentSettings.customDecorations && middlePanel.state !== "Merchant"
|
||||||
|
walletName: appWindow.walletName
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
onCloseClicked: appWindow.close();
|
onCloseClicked: appWindow.close();
|
||||||
onLanguageClicked: appWindow.toggleLanguageView();
|
onLanguageClicked: appWindow.toggleLanguageView();
|
||||||
|
onCloseWalletClicked: appWindow.showWizard();
|
||||||
onMaximizeClicked: appWindow.visibility = appWindow.visibility !== Window.Maximized ? Window.Maximized : Window.Windowed
|
onMaximizeClicked: appWindow.visibility = appWindow.visibility !== Window.Maximized ? Window.Maximized : Window.Windowed
|
||||||
onMinimizeClicked: appWindow.visibility = Window.Minimized
|
onMinimizeClicked: appWindow.visibility = Window.Minimized
|
||||||
onGoToBasicVersion: {
|
|
||||||
if (yes) {
|
|
||||||
// basicPanel.currentView = middlePanel.currentView
|
|
||||||
goToBasicAnimation.start()
|
|
||||||
} else {
|
|
||||||
// middlePanel.currentView = basicPanel.currentView
|
|
||||||
goToProAnimation.start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroMerchant.MerchantTitlebar {
|
MoneroMerchant.MerchantTitlebar {
|
||||||
@@ -2004,41 +1854,43 @@ ApplicationWindow {
|
|||||||
onTriggered: appWindow.themeTransition = true;
|
onTriggered: appWindow.themeTransition = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkNoSyncFlag() {
|
||||||
|
if (!appWindow.daemonRunning) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (appWindow.walletMode == 0 && !daemonManager.noSync()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (appWindow.walletMode == 1 && daemonManager.noSync()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function checkSimpleModeConnection(){
|
function checkSimpleModeConnection(){
|
||||||
// auto-connection mechanism for simple mode
|
// auto-connection mechanism for simple mode
|
||||||
if(persistentSettings.nettype != NetworkType.MAINNET) return;
|
|
||||||
if(appWindow.walletMode >= 2) return;
|
if(appWindow.walletMode >= 2) return;
|
||||||
|
|
||||||
var disconnected = leftPanel.networkStatus.connected === Wallet.ConnectionStatus_Disconnected;
|
const disconnectedTimeoutSec = 30;
|
||||||
var disconnectedEpoch = appWindow.disconnectedEpoch;
|
const firstCheckDelaySec = 2;
|
||||||
if(disconnectedEpoch === 0){
|
|
||||||
|
const connected = leftPanel.networkStatus.connected !== Wallet.ConnectionStatus_Disconnected;
|
||||||
|
const firstRun = appWindow.disconnectedEpoch == 0;
|
||||||
|
if (firstRun) {
|
||||||
|
appWindow.disconnectedEpoch = Utils.epoch() + firstCheckDelaySec - disconnectedTimeoutSec;
|
||||||
|
} else if (connected) {
|
||||||
appWindow.disconnectedEpoch = Utils.epoch();
|
appWindow.disconnectedEpoch = Utils.epoch();
|
||||||
}
|
}
|
||||||
|
|
||||||
// disconnected longer than 5 seconds?
|
const sinceLastConnect = Utils.epoch() - appWindow.disconnectedEpoch;
|
||||||
if(disconnected && disconnectedEpoch > 0 && (Utils.epoch() - disconnectedEpoch) >= 5){
|
if (sinceLastConnect < disconnectedTimeoutSec && checkNoSyncFlag()) {
|
||||||
// for bootstrap mode, first wait until daemon is killed
|
return;
|
||||||
if(appWindow.walletMode === 1 && appWindow.daemonRunning) {
|
|
||||||
appWindow.stopDaemon();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetch new node list
|
|
||||||
wizard.fetchRemoteNodes(function() {
|
|
||||||
// fetched node, connect
|
|
||||||
if(appWindow.walletMode === 0){
|
|
||||||
appWindow.connectRemoteNode();
|
|
||||||
} else if(appWindow.walletMode === 1){
|
|
||||||
appWindow.startDaemon(persistentSettings.daemonFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset state
|
|
||||||
appWindow.disconnectedEpoch = 0;
|
|
||||||
return;
|
|
||||||
}, function(){
|
|
||||||
appWindow.showStatusMessage(qsTr("Failed to fetch remote nodes from third-party server."), simpleModeConnectionTimer.interval / 1000);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (appWindow.daemonRunning) {
|
||||||
|
appWindow.stopDaemon();
|
||||||
|
}
|
||||||
|
appWindow.startDaemon("");
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
@@ -2082,6 +1934,23 @@ ApplicationWindow {
|
|||||||
statusMessage.visible = true
|
statusMessage.visible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showDaemonIsRunningDialog(onClose) {
|
||||||
|
// Show confirmation dialog
|
||||||
|
confirmationDialog.title = qsTr("Local node is running") + translationManager.emptyString;
|
||||||
|
confirmationDialog.text = qsTr("Do you want to stop local node or keep it running in the background?") + translationManager.emptyString;
|
||||||
|
confirmationDialog.icon = StandardIcon.Question;
|
||||||
|
confirmationDialog.cancelText = qsTr("Force stop") + translationManager.emptyString;
|
||||||
|
confirmationDialog.okText = qsTr("Keep it running") + translationManager.emptyString;
|
||||||
|
confirmationDialog.onAcceptedCallback = function() {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
confirmationDialog.onRejectedCallback = function() {
|
||||||
|
daemonManager.stop(persistentSettings.nettype);
|
||||||
|
onClose();
|
||||||
|
};
|
||||||
|
confirmationDialog.open();
|
||||||
|
}
|
||||||
|
|
||||||
onClosing: {
|
onClosing: {
|
||||||
close.accepted = false;
|
close.accepted = false;
|
||||||
console.log("blocking close event");
|
console.log("blocking close event");
|
||||||
@@ -2103,22 +1972,12 @@ ApplicationWindow {
|
|||||||
|
|
||||||
// If daemon is running - prompt user before exiting
|
// If daemon is running - prompt user before exiting
|
||||||
if(typeof daemonManager != "undefined" && daemonRunning) {
|
if(typeof daemonManager != "undefined" && daemonRunning) {
|
||||||
// Show confirmation dialog
|
if (appWindow.walletMode == 0) {
|
||||||
confirmationDialog.title = qsTr("Daemon is running") + translationManager.emptyString;
|
stopDaemon();
|
||||||
confirmationDialog.text = qsTr("Daemon will still be running in background when GUI is closed.");
|
|
||||||
confirmationDialog.icon = StandardIcon.Question
|
|
||||||
confirmationDialog.cancelText = qsTr("Stop daemon")
|
|
||||||
confirmationDialog.onAcceptedCallback = function() {
|
|
||||||
closeAccepted();
|
closeAccepted();
|
||||||
|
} else {
|
||||||
|
showDaemonIsRunningDialog(closeAccepted);
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmationDialog.onRejectedCallback = function() {
|
|
||||||
daemonManager.stop(persistentSettings.nettype);
|
|
||||||
closeAccepted();
|
|
||||||
};
|
|
||||||
|
|
||||||
confirmationDialog.open()
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
closeAccepted();
|
closeAccepted();
|
||||||
}
|
}
|
||||||
@@ -2140,17 +1999,12 @@ ApplicationWindow {
|
|||||||
if (parts.length == 4) {
|
if (parts.length == 4) {
|
||||||
var version = parts[0]
|
var version = parts[0]
|
||||||
var hash = parts[1]
|
var hash = parts[1]
|
||||||
//var user_url = parts[2]
|
var user_url = parts[2]
|
||||||
//var auto_url = parts[3]
|
|
||||||
var osBuildTag = isMac ? "mac-x64" : isWindows ? "win-x64" : isLinux ? "linux-x64" : "unknownBuildTag"
|
|
||||||
var extension = isMac || isLinux ? ".tar.bz2" : isWindows ? ".zip" : ".unknownExtension"
|
|
||||||
var base_url = "https://downloads.getmonero.org/gui/monero-gui-"
|
|
||||||
var download_url = base_url + osBuildTag + "-v" + version + extension
|
|
||||||
var msg = ""
|
var msg = ""
|
||||||
if (osBuildTag !== "unknownBuildTag") {
|
if (isMac || isWindows || isLinux) {
|
||||||
msg = qsTr("New version of Monero v.%1 is available.<br><br>Download:<br>%2<br><br>SHA256 Hash:<br>%3").arg(version).arg(download_url).arg(hash) + translationManager.emptyString
|
msg = qsTr("New version of Monero v%1 is available.<br><br>Download:<br>%2<br><br>SHA256 Hash:<br>%3").arg(version).arg(user_url).arg(hash) + translationManager.emptyString
|
||||||
} else {
|
} else {
|
||||||
msg = qsTr("New version of Monero is available. Check out getmonero.org") + translationManager.emptyString
|
msg = qsTr("New version of Monero v%1 is available. Check out getmonero.org").arg(version) + translationManager.emptyString
|
||||||
}
|
}
|
||||||
notifier.show(msg)
|
notifier.show(msg)
|
||||||
} else {
|
} else {
|
||||||
@@ -2179,14 +2033,16 @@ ApplicationWindow {
|
|||||||
|
|
||||||
// reset label text. othewise potential privacy leak showing unlock time when switching wallets
|
// reset label text. othewise potential privacy leak showing unlock time when switching wallets
|
||||||
function clearMoneroCardLabelText(){
|
function clearMoneroCardLabelText(){
|
||||||
leftPanel.minutesToUnlockTxt = qsTr("Unlocked balance")
|
leftPanel.balanceString = "?.??"
|
||||||
leftPanel.balanceLabelText = qsTr("Balance")
|
leftPanel.balanceFiatString = "?.??"
|
||||||
}
|
}
|
||||||
|
|
||||||
// some fields need an extra nudge when changing languages
|
// some fields need an extra nudge when changing languages
|
||||||
function resetLanguageFields(){
|
function resetLanguageFields(){
|
||||||
clearMoneroCardLabelText()
|
clearMoneroCardLabelText()
|
||||||
onWalletRefresh()
|
if (currentWallet) {
|
||||||
|
onWalletRefresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function userActivity() {
|
function userActivity() {
|
||||||
@@ -2229,11 +2085,22 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function changeWalletMode(mode){
|
function changeWalletMode(mode){
|
||||||
|
appWindow.disconnectedEpoch = 0;
|
||||||
appWindow.walletMode = mode;
|
appWindow.walletMode = mode;
|
||||||
persistentSettings.walletMode = mode;
|
persistentSettings.walletMode = mode;
|
||||||
persistentSettings.useRemoteNode = mode === 0 ? true : false;
|
applyWalletMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
console.log("walletMode changed: " + (mode === 0 ? "simple": mode === 1 ? "simple (bootstrap)" : "Advanced"));
|
function applyWalletMode(mode){
|
||||||
|
if (mode < 2) {
|
||||||
|
persistentSettings.useRemoteNode = false;
|
||||||
|
persistentSettings.bootstrapNodeAddress = "auto";
|
||||||
|
|
||||||
|
if (middlePanel.settingsView.settingsStateViewState === "Node" || middlePanel.settingsView.settingsStateViewState === "Log") {
|
||||||
|
middlePanel.settingsView.settingsStateViewState = "Wallet"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("walletMode: " + (mode === 0 ? "simple": mode === 1 ? "simple (bootstrap)" : "Advanced"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Daemon console
|
// Daemon console
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# qml components require at least QT 5.9.0
|
# qml components require at least QT 5.9.7
|
||||||
lessThan (QT_MAJOR_VERSION, 5) | lessThan (QT_MINOR_VERSION, 9) {
|
lessThan (QT_MAJOR_VERSION, 5) | lessThan (QT_MINOR_VERSION, 9) {
|
||||||
error("Can't build with Qt $${QT_VERSION}. Use at least Qt 5.9.0")
|
error("Can't build with Qt $${QT_VERSION}. Use at least Qt 5.9.7")
|
||||||
}
|
}
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
@@ -16,10 +16,21 @@ packagesExist(libusb-1.0) {
|
|||||||
packagesExist(hidapi-libusb) {
|
packagesExist(hidapi-libusb) {
|
||||||
PKGCONFIG += hidapi-libusb
|
PKGCONFIG += hidapi-libusb
|
||||||
}
|
}
|
||||||
!win32 {
|
|
||||||
|
GCC_VERSION = $$system("g++ -dumpversion")
|
||||||
|
GCC_VERSION = $$split(GCC_VERSION, .)
|
||||||
|
GCC_VERSION_MAJOR = $$member(GCC_VERSION, 0)
|
||||||
|
GCC_VERSION_MINOR = $$member(GCC_VERSION, 1)
|
||||||
|
greaterThan(GCC_VERSION_MAJOR, 9) | if(equals(GCC_VERSION_MAJOR, 9) : greaterThan(GCC_VERSION_MINOR, 0)) {
|
||||||
|
GCC_9_1_OR_GREATER = TRUE
|
||||||
|
}
|
||||||
|
|
||||||
|
!win32 | !isEmpty(GCC_9_1_OR_GREATER) {
|
||||||
QMAKE_CXXFLAGS += -fPIC -fstack-protector -fstack-protector-strong
|
QMAKE_CXXFLAGS += -fPIC -fstack-protector -fstack-protector-strong
|
||||||
QMAKE_LFLAGS += -fstack-protector -fstack-protector-strong
|
QMAKE_LFLAGS += -fstack-protector -fstack-protector-strong
|
||||||
|
}
|
||||||
|
|
||||||
|
!win32 {
|
||||||
packagesExist(protobuf) {
|
packagesExist(protobuf) {
|
||||||
PKGCONFIG += protobuf
|
PKGCONFIG += protobuf
|
||||||
}
|
}
|
||||||
@@ -142,25 +153,25 @@ ios:arm64 {
|
|||||||
LIBS += \
|
LIBS += \
|
||||||
-L$$PWD/../ofxiOSBoost/build/libs/boost/lib/arm64 \
|
-L$$PWD/../ofxiOSBoost/build/libs/boost/lib/arm64 \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIBS_COMMON = \
|
||||||
|
-lwallet_merged \
|
||||||
|
-llmdb \
|
||||||
|
-lepee \
|
||||||
|
-lunbound \
|
||||||
|
-lsodium \
|
||||||
|
-leasylogging \
|
||||||
|
-lrandomx
|
||||||
|
|
||||||
!ios:!android {
|
!ios:!android {
|
||||||
LIBS += -L$$WALLET_ROOT/lib \
|
LIBS += -L$$WALLET_ROOT/lib \
|
||||||
-lwallet_merged \
|
$$LIBS_COMMON
|
||||||
-llmdb \
|
|
||||||
-lepee \
|
|
||||||
-lunbound \
|
|
||||||
-lsodium \
|
|
||||||
-leasylogging
|
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
message("Host is Android")
|
message("Host is Android")
|
||||||
LIBS += -L$$WALLET_ROOT/lib \
|
LIBS += -L$$WALLET_ROOT/lib \
|
||||||
-lwallet_merged \
|
$$LIBS_COMMON
|
||||||
-llmdb \
|
|
||||||
-lepee \
|
|
||||||
-lunbound \
|
|
||||||
-lsodium \
|
|
||||||
-leasylogging
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -175,12 +186,7 @@ ios {
|
|||||||
QMAKE_IOS_DEVICE_ARCHS = arm64
|
QMAKE_IOS_DEVICE_ARCHS = arm64
|
||||||
CONFIG += arm64
|
CONFIG += arm64
|
||||||
LIBS += -L$$WALLET_ROOT/lib-ios \
|
LIBS += -L$$WALLET_ROOT/lib-ios \
|
||||||
-lwallet_merged \
|
$$LIBS_COMMON
|
||||||
-llmdb \
|
|
||||||
-lepee \
|
|
||||||
-lunbound \
|
|
||||||
-lsodium \
|
|
||||||
-leasylogging
|
|
||||||
|
|
||||||
LIBS+= \
|
LIBS+= \
|
||||||
-L$$PWD/../OpenSSL-for-iPhone/lib \
|
-L$$PWD/../OpenSSL-for-iPhone/lib \
|
||||||
@@ -287,6 +293,7 @@ win32 {
|
|||||||
-licudt \
|
-licudt \
|
||||||
-licutu \
|
-licutu \
|
||||||
-liconv \
|
-liconv \
|
||||||
|
-lstdc++ \
|
||||||
-lpthread \
|
-lpthread \
|
||||||
-lsetupapi \
|
-lsetupapi \
|
||||||
-lssl \
|
-lssl \
|
||||||
@@ -337,13 +344,13 @@ linux {
|
|||||||
-llmdb \
|
-llmdb \
|
||||||
-lsodium \
|
-lsodium \
|
||||||
-lhidapi-libusb \
|
-lhidapi-libusb \
|
||||||
-lcrypto $$TREZOR_LINKER \
|
-lcrypto $$TREZOR_LINKER
|
||||||
-lX11
|
|
||||||
|
|
||||||
if(!android) {
|
if(!android) {
|
||||||
LIBS+= \
|
LIBS+= \
|
||||||
-Wl,-Bdynamic \
|
-Wl,-Bdynamic \
|
||||||
-lGL
|
-lGL \
|
||||||
|
-lX11
|
||||||
}
|
}
|
||||||
# currently monero has an issue with "static" build and linunwind-dev,
|
# currently monero has an issue with "static" build and linunwind-dev,
|
||||||
# so we link libunwind-dev only for non-Ubuntu distros
|
# so we link libunwind-dev only for non-Ubuntu distros
|
||||||
@@ -363,11 +370,19 @@ macx {
|
|||||||
# message("using static libraries")
|
# message("using static libraries")
|
||||||
# LIBS+= -Wl,-Bstatic
|
# LIBS+= -Wl,-Bstatic
|
||||||
# }
|
# }
|
||||||
|
|
||||||
|
OPENSSL_LIBRARY_DIRS = $$system(brew --prefix openssl, lines, EXIT_CODE)
|
||||||
|
equals(EXIT_CODE, 0) {
|
||||||
|
OPENSSL_LIBRARY_DIRS = $$OPENSSL_LIBRARY_DIRS/lib
|
||||||
|
} else {
|
||||||
|
OPENSSL_LIBRARY_DIRS = /usr/local/ssl/lib
|
||||||
|
}
|
||||||
|
|
||||||
QT += macextras
|
QT += macextras
|
||||||
OBJECTIVE_SOURCES += src/qt/macoshelper.mm
|
OBJECTIVE_SOURCES += src/qt/macoshelper.mm
|
||||||
LIBS+= \
|
LIBS+= \
|
||||||
-L/usr/local/lib \
|
-L/usr/local/lib \
|
||||||
-L/usr/local/opt/openssl/lib \
|
-L$$OPENSSL_LIBRARY_DIRS \
|
||||||
-L/usr/local/opt/boost/lib \
|
-L/usr/local/opt/boost/lib \
|
||||||
-lboost_serialization \
|
-lboost_serialization \
|
||||||
-lboost_thread-mt \
|
-lboost_thread-mt \
|
||||||
@@ -497,6 +512,9 @@ DISTFILES += \
|
|||||||
notes.txt \
|
notes.txt \
|
||||||
monero/src/wallet/CMakeLists.txt
|
monero/src/wallet/CMakeLists.txt
|
||||||
|
|
||||||
|
VERSION = $$cat('version.js', lines)
|
||||||
|
VERSION = $$find(VERSION, 'GUI_VERSION')
|
||||||
|
VERSION = $$replace(VERSION, '.*(\d+\.\d+\.\d+\.\d+).*', '\1')
|
||||||
|
|
||||||
# windows application icon
|
# windows application icon
|
||||||
RC_ICONS = images/appicon.ico
|
RC_ICONS = images/appicon.ico
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
#ifdef Q_OS_WIN32
|
#ifdef Q_OS_WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef Q_OS_LINUX
|
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
|
||||||
#include <X11/XKBlib.h>
|
#include <X11/XKBlib.h>
|
||||||
#undef KeyPress
|
#undef KeyPress
|
||||||
#undef KeyRelease
|
#undef KeyRelease
|
||||||
@@ -78,7 +78,7 @@ bool OSHelper::isCapsLock() const
|
|||||||
// platform dependent method of determining if CAPS LOCK is on
|
// platform dependent method of determining if CAPS LOCK is on
|
||||||
#if defined(Q_OS_WIN32) // MS Windows version
|
#if defined(Q_OS_WIN32) // MS Windows version
|
||||||
return GetKeyState(VK_CAPITAL) == 1;
|
return GetKeyState(VK_CAPITAL) == 1;
|
||||||
#elif defined(Q_OS_LINUX) // X11 version
|
#elif defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) // X11 version
|
||||||
Display * d = XOpenDisplay((char*)0);
|
Display * d = XOpenDisplay((char*)0);
|
||||||
bool caps_state = false;
|
bool caps_state = false;
|
||||||
if (d) {
|
if (d) {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import QtQuick.Controls 2.0
|
|||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls.Styles 1.4
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
import QtQuick.Dialogs 1.2
|
import QtQuick.Dialogs 1.2
|
||||||
|
import FontAwesome 1.0
|
||||||
|
|
||||||
import "../components" as MoneroComponents
|
import "../components" as MoneroComponents
|
||||||
import "../components/effects/" as MoneroEffects
|
import "../components/effects/" as MoneroEffects
|
||||||
@@ -48,6 +49,7 @@ Rectangle {
|
|||||||
property var model
|
property var model
|
||||||
property alias accountHeight: mainLayout.height
|
property alias accountHeight: mainLayout.height
|
||||||
property bool selectAndSend: false
|
property bool selectAndSend: false
|
||||||
|
property int currentAccountIndex
|
||||||
|
|
||||||
function renameSubaddressAccountLabel(_index){
|
function renameSubaddressAccountLabel(_index){
|
||||||
inputDialog.labelText = qsTr("Set the label of the selected account:") + translationManager.emptyString;
|
inputDialog.labelText = qsTr("Set the label of the selected account:") + translationManager.emptyString;
|
||||||
@@ -64,7 +66,7 @@ Rectangle {
|
|||||||
/* main layout */
|
/* main layout */
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -179,6 +181,7 @@ Rectangle {
|
|||||||
clip: true
|
clip: true
|
||||||
boundsBehavior: ListView.StopAtBounds
|
boundsBehavior: ListView.StopAtBounds
|
||||||
interactive: false
|
interactive: false
|
||||||
|
currentIndex: currentAccountIndex
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
id: tableItem2
|
id: tableItem2
|
||||||
@@ -210,7 +213,7 @@ Rectangle {
|
|||||||
|
|
||||||
MoneroComponents.Label {
|
MoneroComponents.Label {
|
||||||
id: idLabel
|
id: idLabel
|
||||||
color: index === appWindow.current_subaddress_account_table_index ? MoneroComponents.Style.defaultFontColor : "#757575"
|
color: index === currentAccountIndex ? MoneroComponents.Style.defaultFontColor : "#757575"
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 6
|
anchors.leftMargin: 6
|
||||||
@@ -277,9 +280,9 @@ Rectangle {
|
|||||||
onEntered: tableItem2.color = MoneroComponents.Style.titleBarButtonHoverColor
|
onEntered: tableItem2.color = MoneroComponents.Style.titleBarButtonHoverColor
|
||||||
onExited: tableItem2.color = "transparent"
|
onExited: tableItem2.color = "transparent"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (index == subaddressAccountListView.currentIndex && selectAndSend)
|
appWindow.currentWallet.switchSubaddressAccount(index);
|
||||||
|
if (selectAndSend)
|
||||||
appWindow.showPageRequest("Transfer");
|
appWindow.showPageRequest("Transfer");
|
||||||
subaddressAccountListView.currentIndex = index;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,17 +321,9 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onCurrentItemChanged: {
|
|
||||||
// reset global vars
|
|
||||||
appWindow.current_subaddress_account_table_index = subaddressAccountListView.currentIndex;
|
|
||||||
appWindow.currentWallet.switchSubaddressAccount(appWindow.current_subaddress_account_table_index);
|
|
||||||
appWindow.onWalletUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
if (selectAndSend) {
|
appWindow.onWalletUpdate();
|
||||||
appWindow.showPageRequest("Transfer");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -349,8 +344,9 @@ Rectangle {
|
|||||||
id: addNewAccountCheckbox
|
id: addNewAccountCheckbox
|
||||||
visible: !selectAndSend
|
visible: !selectAndSend
|
||||||
border: false
|
border: false
|
||||||
checkedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
uncheckedIcon: FontAwesome.plusCircle
|
||||||
uncheckedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
toggleOnClick: false
|
||||||
|
fontAwesomeIcons: true
|
||||||
fontSize: 16
|
fontSize: 16
|
||||||
iconOnTheLeft: true
|
iconOnTheLeft: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -362,8 +358,6 @@ Rectangle {
|
|||||||
inputDialog.onAcceptedCallback = function() {
|
inputDialog.onAcceptedCallback = function() {
|
||||||
appWindow.currentWallet.subaddressAccount.addRow(inputDialog.inputText)
|
appWindow.currentWallet.subaddressAccount.addRow(inputDialog.inputText)
|
||||||
appWindow.currentWallet.switchSubaddressAccount(appWindow.currentWallet.numSubaddressAccounts() - 1)
|
appWindow.currentWallet.switchSubaddressAccount(appWindow.currentWallet.numSubaddressAccounts() - 1)
|
||||||
current_subaddress_account_table_index = appWindow.currentWallet.numSubaddressAccounts() - 1
|
|
||||||
subaddressAccountListView.currentIndex = current_subaddress_account_table_index
|
|
||||||
appWindow.onWalletUpdate();
|
appWindow.onWalletUpdate();
|
||||||
}
|
}
|
||||||
inputDialog.onRejectedCallback = null;
|
inputDialog.onRejectedCallback = null;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ Rectangle {
|
|||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -67,21 +67,18 @@ Rectangle {
|
|||||||
spacing: 0
|
spacing: 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
TextArea {
|
Text {
|
||||||
id: titleLabel
|
id: titleLabel
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
font.pixelSize: 32
|
font.pixelSize: 32
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
selectByMouse: false
|
|
||||||
wrapMode: Text.WordWrap;
|
wrapMode: Text.WordWrap;
|
||||||
textMargin: 0
|
|
||||||
leftPadding: 0
|
leftPadding: 0
|
||||||
topPadding: 0
|
topPadding: 0
|
||||||
text: qsTr("Save your most used addresses here") + translationManager.emptyString
|
text: qsTr("Save your most used addresses here") + translationManager.emptyString
|
||||||
width: parent.width
|
width: parent.width
|
||||||
readOnly: true
|
|
||||||
|
|
||||||
// @TODO: Legacy. Remove after Qt 5.8.
|
// @TODO: Legacy. Remove after Qt 5.8.
|
||||||
// https://stackoverflow.com/questions/41990013
|
// https://stackoverflow.com/questions/41990013
|
||||||
@@ -91,20 +88,17 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextArea {
|
Text {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
color: MoneroComponents.Style.dimmedFontColor
|
color: MoneroComponents.Style.dimmedFontColor
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
selectByMouse: false
|
|
||||||
wrapMode: Text.WordWrap;
|
wrapMode: Text.WordWrap;
|
||||||
textMargin: 0
|
|
||||||
leftPadding: 0
|
leftPadding: 0
|
||||||
topPadding: 0
|
topPadding: 0
|
||||||
text: qsTr("This makes it easier to send or receive Monero and reduces errors when typing in addresses manually.") + translationManager.emptyString
|
text: qsTr("This makes it easier to send or receive Monero and reduces errors when typing in addresses manually.") + translationManager.emptyString
|
||||||
width: parent.width
|
width: parent.width
|
||||||
readOnly: true
|
|
||||||
|
|
||||||
// @TODO: Legacy. Remove after Qt 5.8.
|
// @TODO: Legacy. Remove after Qt 5.8.
|
||||||
// https://stackoverflow.com/questions/41990013
|
// https://stackoverflow.com/questions/41990013
|
||||||
@@ -284,8 +278,9 @@ Rectangle {
|
|||||||
MoneroComponents.CheckBox {
|
MoneroComponents.CheckBox {
|
||||||
id: addNewEntryCheckbox
|
id: addNewEntryCheckbox
|
||||||
border: false
|
border: false
|
||||||
checkedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
uncheckedIcon: FontAwesome.plusCircle
|
||||||
uncheckedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
toggleOnClick: false
|
||||||
|
fontAwesomeIcons: true
|
||||||
fontSize: 16
|
fontSize: 16
|
||||||
iconOnTheLeft: true
|
iconOnTheLeft: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -325,8 +320,8 @@ Rectangle {
|
|||||||
wrapMode: Text.WrapAnywhere
|
wrapMode: Text.WrapAnywhere
|
||||||
addressValidation: true
|
addressValidation: true
|
||||||
pasteButton: true
|
pasteButton: true
|
||||||
onPaste: function(clipboardText) {
|
onTextChanged: {
|
||||||
const parsed = walletManager.parse_uri_to_object(clipboardText);
|
const parsed = walletManager.parse_uri_to_object(addressLine.text);
|
||||||
if (!parsed.error) {
|
if (!parsed.error) {
|
||||||
addressLine.text = parsed.address;
|
addressLine.text = parsed.address;
|
||||||
descriptionLine.text = parsed.tx_description;
|
descriptionLine.text = parsed.tx_description;
|
||||||
|
|||||||
@@ -181,7 +181,6 @@ Rectangle {
|
|||||||
Layout.rightMargin: sideMargin
|
Layout.rightMargin: sideMargin
|
||||||
columns: 2
|
columns: 2
|
||||||
columnSpacing: 20
|
columnSpacing: 20
|
||||||
z: 6
|
|
||||||
|
|
||||||
MoneroComponents.DatePicker {
|
MoneroComponents.DatePicker {
|
||||||
id: fromDatePicker
|
id: fromDatePicker
|
||||||
@@ -228,7 +227,7 @@ Rectangle {
|
|||||||
MoneroComponents.TextPlain {
|
MoneroComponents.TextPlain {
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
text: qsTr("Sort by") + ":"
|
text: qsTr("Sort by") + ":" + translationManager.emptyString
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
@@ -447,7 +446,7 @@ Rectangle {
|
|||||||
MoneroComponents.TextPlain {
|
MoneroComponents.TextPlain {
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
text: qsTr("Page") + ":"
|
text: qsTr("Page") + ":" + translationManager.emptyString
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
@@ -651,7 +650,7 @@ Rectangle {
|
|||||||
MoneroComponents.TextPlain {
|
MoneroComponents.TextPlain {
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
text: _amount + " XMR"
|
text: displayAmount
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
@@ -870,7 +869,7 @@ Rectangle {
|
|||||||
MoneroComponents.TextPlain {
|
MoneroComponents.TextPlain {
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
text: persistentSettings.historyHumanDates ? dateHuman : date + " " + time
|
text: persistentSettings.historyHumanDates ? dateHuman : dateTime
|
||||||
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -882,7 +881,7 @@ Rectangle {
|
|||||||
onEntered: {
|
onEntered: {
|
||||||
parent.color = MoneroComponents.Style.orange
|
parent.color = MoneroComponents.Style.orange
|
||||||
if (persistentSettings.historyHumanDates) {
|
if (persistentSettings.historyHumanDates) {
|
||||||
parent.text = date + " " + time;
|
parent.text = dateTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onExited: {
|
onExited: {
|
||||||
@@ -939,7 +938,7 @@ Rectangle {
|
|||||||
anchors.leftMargin: 10
|
anchors.leftMargin: 10
|
||||||
text: FontAwesome.productHunt
|
text: FontAwesome.productHunt
|
||||||
small: true
|
small: true
|
||||||
label.font.family: FontAwesome.fontFamily
|
label.font.family: FontAwesome.fontFamilyBrands
|
||||||
fontSize: 18
|
fontSize: 18
|
||||||
width: 36
|
width: 36
|
||||||
|
|
||||||
@@ -1197,7 +1196,7 @@ Rectangle {
|
|||||||
if(res[i].state === 'copyable_address') root.toClipboard(address);
|
if(res[i].state === 'copyable_address') root.toClipboard(address);
|
||||||
if(res[i].state === 'copyable_txkey') root.getTxKey(hash, res[i]);
|
if(res[i].state === 'copyable_txkey') root.getTxKey(hash, res[i]);
|
||||||
if(res[i].state === 'set_tx_note') root.editDescription(hash);
|
if(res[i].state === 'set_tx_note') root.editDescription(hash);
|
||||||
if(res[i].state === 'details') root.showTxDetails(hash, paymentId, destinations, subaddrAccount, subaddrIndex);
|
if(res[i].state === 'details') root.showTxDetails(hash, paymentId, destinations, subaddrAccount, subaddrIndex, dateTime, displayAmount, isout);
|
||||||
if(res[i].state === 'proof') root.showTxProof(hash, paymentId, destinations, subaddrAccount, subaddrIndex);
|
if(res[i].state === 'proof') root.showTxProof(hash, paymentId, destinations, subaddrAccount, subaddrIndex);
|
||||||
doCollapse = false;
|
doCollapse = false;
|
||||||
break;
|
break;
|
||||||
@@ -1361,8 +1360,9 @@ Rectangle {
|
|||||||
// applying filters
|
// applying filters
|
||||||
root.txData = JSON.parse(JSON.stringify(root.txModelData)); // deepcopy
|
root.txData = JSON.parse(JSON.stringify(root.txModelData)); // deepcopy
|
||||||
|
|
||||||
var fromDate = fromDatePicker.currentDate.getTime() / 1000;
|
const timezoneOffset = new Date().getTimezoneOffset() * 60;
|
||||||
var toDate = toDatePicker.currentDate.getTime() / 1000;
|
var fromDate = Math.floor(fromDatePicker.currentDate.getTime() / 86400000) * 86400 + timezoneOffset;
|
||||||
|
var toDate = (Math.floor(toDatePicker.currentDate.getTime() / 86400000) + 1) * 86400 + timezoneOffset;
|
||||||
|
|
||||||
var txs = [];
|
var txs = [];
|
||||||
for (var i = 0; i < root.txData.length; i++){
|
for (var i = 0; i < root.txData.length; i++){
|
||||||
@@ -1479,12 +1479,12 @@ Rectangle {
|
|||||||
var timestamp = new Date(date + " " + time).getTime() / 1000;
|
var timestamp = new Date(date + " " + time).getTime() / 1000;
|
||||||
var dateHuman = Utils.ago(timestamp);
|
var dateHuman = Utils.ago(timestamp);
|
||||||
|
|
||||||
var _amount = amount;
|
var displayAmount = amount;
|
||||||
if(_amount === 0){
|
if(displayAmount === 0){
|
||||||
// *sometimes* amount is 0, while the 'destinations string'
|
// *sometimes* amount is 0, while the 'destinations string'
|
||||||
// has the correct amount, so we try to fetch it from that instead.
|
// has the correct amount, so we try to fetch it from that instead.
|
||||||
_amount = TxUtils.destinationsToAmount(destinations);
|
displayAmount = TxUtils.destinationsToAmount(destinations);
|
||||||
_amount = Number(_amount *1);
|
displayAmount = Number(displayAmount *1);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx_note = currentWallet.getUserNote(hash);
|
var tx_note = currentWallet.getUserNote(hash);
|
||||||
@@ -1502,15 +1502,14 @@ Rectangle {
|
|||||||
"i": i,
|
"i": i,
|
||||||
"isout": isout,
|
"isout": isout,
|
||||||
"amount": Number(amount),
|
"amount": Number(amount),
|
||||||
"_amount": _amount,
|
"displayAmount": displayAmount + " XMR",
|
||||||
"hash": hash,
|
"hash": hash,
|
||||||
"paymentId": paymentId,
|
"paymentId": paymentId,
|
||||||
"address": address,
|
"address": address,
|
||||||
"destinations": destinations,
|
"destinations": destinations,
|
||||||
"tx_note": tx_note,
|
"tx_note": tx_note,
|
||||||
"time": time,
|
|
||||||
"date": date,
|
|
||||||
"dateHuman": dateHuman,
|
"dateHuman": dateHuman,
|
||||||
|
"dateTime": date + " " + time,
|
||||||
"blockheight": blockheight,
|
"blockheight": blockheight,
|
||||||
"address": address,
|
"address": address,
|
||||||
"timestamp": timestamp,
|
"timestamp": timestamp,
|
||||||
@@ -1582,22 +1581,25 @@ Rectangle {
|
|||||||
elem.parent.text = txKey ? txKey : '-';
|
elem.parent.text = txKey ? txKey : '-';
|
||||||
elem.parent.state = 'ready';
|
elem.parent.state = 'ready';
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
toClipboard(elem.parent.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
toClipboard(elem.parent.text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showTxDetails(hash, paymentId, destinations, subaddrAccount, subaddrIndex){
|
function showTxDetails(hash, paymentId, destinations, subaddrAccount, subaddrIndex, dateTime, amount, isout) {
|
||||||
var tx_note = currentWallet.getUserNote(hash)
|
var tx_note = currentWallet.getUserNote(hash)
|
||||||
var rings = currentWallet.getRings(hash)
|
var rings = currentWallet.getRings(hash)
|
||||||
var address_label = subaddrIndex == 0 ? (qsTr("Primary address") + translationManager.emptyString) : currentWallet.getSubaddressLabel(subaddrAccount, subaddrIndex)
|
var address_label = subaddrIndex == 0 ? (qsTr("Primary address") + translationManager.emptyString) : currentWallet.getSubaddressLabel(subaddrAccount, subaddrIndex)
|
||||||
var address = currentWallet.address(subaddrAccount, subaddrIndex)
|
var address = currentWallet.address(subaddrAccount, subaddrIndex)
|
||||||
|
const hasPaymentId = parseInt(paymentId, 16);
|
||||||
|
const integratedAddress = !isout && hasPaymentId ? currentWallet.integratedAddress(paymentId) : null;
|
||||||
|
|
||||||
if (rings)
|
if (rings)
|
||||||
rings = rings.replace(/\|/g, '\n')
|
rings = rings.replace(/\|/g, '\n')
|
||||||
|
|
||||||
currentWallet.getTxKeyAsync(hash, function(hash, tx_key) {
|
currentWallet.getTxKeyAsync(hash, function(hash, tx_key) {
|
||||||
informationPopup.title = qsTr("Transaction details") + translationManager.emptyString;
|
informationPopup.title = qsTr("Transaction details") + translationManager.emptyString;
|
||||||
informationPopup.content = buildTxDetailsString(hash, paymentId, tx_key, tx_note, destinations, rings, address, address_label);
|
informationPopup.content = buildTxDetailsString(hash, paymentId, tx_key, tx_note, destinations, rings, address, address_label, integratedAddress, dateTime, amount);
|
||||||
informationPopup.onCloseCallback = null
|
informationPopup.onCloseCallback = null
|
||||||
informationPopup.open();
|
informationPopup.open();
|
||||||
});
|
});
|
||||||
@@ -1625,16 +1627,18 @@ Rectangle {
|
|||||||
appWindow.showStatusMessage(qsTr("Copied to clipboard"),3);
|
appWindow.showStatusMessage(qsTr("Copied to clipboard"),3);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildTxDetailsString(tx_id, paymentId, tx_key,tx_note, destinations, rings, address, address_label) {
|
function buildTxDetailsString(tx_id, paymentId, tx_key,tx_note, destinations, rings, address, address_label, integratedAddress, dateTime, amount) {
|
||||||
var trStart = '<tr><td width="85" style="padding-top:5px"><b>',
|
var trStart = '<tr><td style="white-space: nowrap; padding-top:5px"><b>',
|
||||||
trMiddle = '</b></td><td style="padding-left:10px;padding-top:5px;">',
|
trMiddle = '</b></td><td style="padding-left:10px;padding-top:5px;">',
|
||||||
trEnd = "</td></tr>";
|
trEnd = "</td></tr>";
|
||||||
|
|
||||||
return '<table border="0">'
|
return '<table border="0">'
|
||||||
+ (tx_id ? trStart + qsTr("Tx ID:") + trMiddle + tx_id + trEnd : "")
|
+ (tx_id ? trStart + qsTr("Tx ID:") + trMiddle + tx_id + trEnd : "")
|
||||||
+ (address_label ? trStart + qsTr("Address label:") + trMiddle + address_label + trEnd : "")
|
+ (dateTime ? trStart + qsTr("Date") + ":" + trMiddle + dateTime + trEnd : "")
|
||||||
|
+ (amount ? trStart + qsTr("Amount") + ":" + trMiddle + amount + trEnd : "")
|
||||||
+ (address ? trStart + qsTr("Address:") + trMiddle + address + trEnd : "")
|
+ (address ? trStart + qsTr("Address:") + trMiddle + address + trEnd : "")
|
||||||
+ (paymentId ? trStart + qsTr("Payment ID:") + trMiddle + paymentId + trEnd : "")
|
+ (paymentId ? trStart + qsTr("Payment ID:") + trMiddle + paymentId + trEnd : "")
|
||||||
|
+ (integratedAddress ? trStart + qsTr("Integrated address") + ":" + trMiddle + integratedAddress + trEnd : "")
|
||||||
+ (tx_key ? trStart + qsTr("Tx key:") + trMiddle + tx_key + trEnd : "")
|
+ (tx_key ? trStart + qsTr("Tx key:") + trMiddle + tx_key + trEnd : "")
|
||||||
+ (tx_note ? trStart + qsTr("Tx note:") + trMiddle + tx_note + trEnd : "")
|
+ (tx_note ? trStart + qsTr("Tx note:") + trMiddle + tx_note + trEnd : "")
|
||||||
+ (destinations ? trStart + qsTr("Destinations:") + trMiddle + destinations + trEnd : "")
|
+ (destinations ? trStart + qsTr("Destinations:") + trMiddle + destinations + trEnd : "")
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ Rectangle {
|
|||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
|
|
||||||
spacing: 30
|
spacing: 30
|
||||||
@@ -251,7 +251,7 @@ Rectangle {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
loadPage("Settings")
|
loadPage("Settings")
|
||||||
}
|
}
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
width: 135
|
width: 135
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ Rectangle {
|
|||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import QtQuick.Controls 2.0
|
|||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls.Styles 1.4
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
import QtQuick.Dialogs 1.2
|
import QtQuick.Dialogs 1.2
|
||||||
|
import FontAwesome 1.0
|
||||||
|
|
||||||
import "../components" as MoneroComponents
|
import "../components" as MoneroComponents
|
||||||
import "../components/effects/" as MoneroEffects
|
import "../components/effects/" as MoneroEffects
|
||||||
@@ -65,7 +66,7 @@ Rectangle {
|
|||||||
/* main layout */
|
/* main layout */
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -243,8 +244,9 @@ Rectangle {
|
|||||||
MoneroComponents.CheckBox {
|
MoneroComponents.CheckBox {
|
||||||
id: addNewAddressCheckbox
|
id: addNewAddressCheckbox
|
||||||
border: false
|
border: false
|
||||||
checkedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
uncheckedIcon: FontAwesome.plusCircle
|
||||||
uncheckedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
toggleOnClick: false
|
||||||
|
fontAwesomeIcons: true
|
||||||
fontSize: 16
|
fontSize: 16
|
||||||
iconOnTheLeft: true
|
iconOnTheLeft: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -309,6 +311,20 @@ Rectangle {
|
|||||||
appWindow.showStatusMessage(qsTr("Copied to clipboard") + translationManager.emptyString, 3);
|
appWindow.showStatusMessage(qsTr("Copied to clipboard") + translationManager.emptyString, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
text: FontAwesome.eye
|
||||||
|
label.font.family: FontAwesome.fontFamily
|
||||||
|
fontSize: 24
|
||||||
|
width: 36
|
||||||
|
visible: appWindow.currentWallet ? appWindow.currentWallet.isHwBacked() : false
|
||||||
|
onClicked: {
|
||||||
|
appWindow.currentWallet.deviceShowAddressAsync(
|
||||||
|
appWindow.currentWallet.currentSubaddressAccount,
|
||||||
|
appWindow.current_subaddress_table_index,
|
||||||
|
'');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ Rectangle {
|
|||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -296,7 +296,7 @@ Rectangle {
|
|||||||
|
|
||||||
GridLayout{
|
GridLayout{
|
||||||
Layout.topMargin: 12
|
Layout.topMargin: 12
|
||||||
columns: (isMobile) ? 1 : 2
|
columns: 2
|
||||||
columnSpacing: 32
|
columnSpacing: 32
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
@@ -368,7 +368,7 @@ Rectangle {
|
|||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
columnSpacing: 20
|
columnSpacing: 20
|
||||||
columns: (isMobile) ? 1 : 2
|
columns: 2
|
||||||
|
|
||||||
MoneroComponents.CheckBox {
|
MoneroComponents.CheckBox {
|
||||||
id: segregatePreForkOutputs
|
id: segregatePreForkOutputs
|
||||||
@@ -405,7 +405,7 @@ Rectangle {
|
|||||||
id: segregationHeightRow
|
id: segregationHeightRow
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 17
|
Layout.topMargin: 17
|
||||||
columns: (isMobile) ? 1 : 2
|
columns: 2
|
||||||
columnSpacing: 32
|
columnSpacing: 32
|
||||||
|
|
||||||
MoneroComponents.LineEdit {
|
MoneroComponents.LineEdit {
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ Rectangle {
|
|||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ Rectangle {
|
|||||||
property bool showAdvanced: false
|
property bool showAdvanced: false
|
||||||
// @TODO: remove after pid removal hardfork
|
// @TODO: remove after pid removal hardfork
|
||||||
property bool warningLongPidTransfer: false
|
property bool warningLongPidTransfer: false
|
||||||
property bool warningLongPidDescription: false
|
property bool warningLongPidDescription: descriptionLine.text.match(/^[0-9a-f]{64}$/i)
|
||||||
|
|
||||||
Clipboard { id: clipboard }
|
Clipboard { id: clipboard }
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ Rectangle {
|
|||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: pageRoot
|
id: pageRoot
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -143,8 +143,16 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
visible: leftPanel.minutesToUnlock !== ""
|
||||||
|
|
||||||
|
MoneroComponents.WarningBox {
|
||||||
|
text: qsTr("Spendable funds: %1 XMR. Please wait ~%2 minutes for your whole balance to become spendable.").arg(leftPanel.balanceUnlockedString).arg(leftPanel.minutesToUnlock)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
columns: (isMobile || !(appWindow.walletMode >= 2)) ? 1 : 2
|
columns: appWindow.walletMode < 2 ? 1 : 2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
columnSpacing: 32
|
columnSpacing: 32
|
||||||
|
|
||||||
@@ -160,6 +168,10 @@ Rectangle {
|
|||||||
labelText: qsTr("<style type='text/css'>a {text-decoration: none; color: #858585; font-size: 14px;}</style>\
|
labelText: qsTr("<style type='text/css'>a {text-decoration: none; color: #858585; font-size: 14px;}</style>\
|
||||||
Amount <font size='2'> ( </font> <a href='#'>Change account</a><font size='2'> )</font>")
|
Amount <font size='2'> ( </font> <a href='#'>Change account</a><font size='2'> )</font>")
|
||||||
+ translationManager.emptyString
|
+ translationManager.emptyString
|
||||||
|
copyButton: !isNaN(amountLine.text) && persistentSettings.fiatPriceEnabled
|
||||||
|
copyButtonText: fiatApiCurrencySymbol() + " ~" + fiatApiConvertToFiat(amountLine.text)
|
||||||
|
copyButtonEnabled: false
|
||||||
|
|
||||||
onLabelLinkActivated: {
|
onLabelLinkActivated: {
|
||||||
middlePanel.accountView.selectAndSend = true;
|
middlePanel.accountView.selectAndSend = true;
|
||||||
appWindow.showPageRequest("Account")
|
appWindow.showPageRequest("Account")
|
||||||
@@ -170,9 +182,17 @@ Rectangle {
|
|||||||
inlineButtonText: qsTr("All") + translationManager.emptyString
|
inlineButtonText: qsTr("All") + translationManager.emptyString
|
||||||
inlineButton.onClicked: amountLine.text = "(all)"
|
inlineButton.onClicked: amountLine.text = "(all)"
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
if(amountLine.text.indexOf('.') === 0){
|
const match = amountLine.text.match(/^0+(\d.*)/);
|
||||||
amountLine.text = '0' + amountLine.text;
|
if (match) {
|
||||||
}
|
const cursorPosition = amountLine.cursorPosition;
|
||||||
|
amountLine.text = match[1];
|
||||||
|
amountLine.cursorPosition = Math.max(cursorPosition, 1) - 1;
|
||||||
|
} else if(amountLine.text.indexOf('.') === 0){
|
||||||
|
amountLine.text = '0' + amountLine.text;
|
||||||
|
if (amountLine.text.length > 2) {
|
||||||
|
amountLine.cursorPosition = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validator: RegExpValidator {
|
validator: RegExpValidator {
|
||||||
@@ -203,10 +223,10 @@ Rectangle {
|
|||||||
id: priorityModelV5
|
id: priorityModelV5
|
||||||
|
|
||||||
ListElement { column1: qsTr("Automatic") ; column2: ""; priority: 0}
|
ListElement { column1: qsTr("Automatic") ; column2: ""; priority: 0}
|
||||||
ListElement { column1: qsTr("Slow (x0.25 fee)") ; column2: ""; priority: 1}
|
ListElement { column1: qsTr("Slow (x0.2 fee)") ; column2: ""; priority: 1}
|
||||||
ListElement { column1: qsTr("Normal (x1 fee)") ; column2: ""; priority: 2 }
|
ListElement { column1: qsTr("Normal (x1 fee)") ; column2: ""; priority: 2 }
|
||||||
ListElement { column1: qsTr("Fast (x5 fee)") ; column2: ""; priority: 3 }
|
ListElement { column1: qsTr("Fast (x5 fee)") ; column2: ""; priority: 3 }
|
||||||
ListElement { column1: qsTr("Fastest (x41.5 fee)") ; column2: ""; priority: 4 }
|
ListElement { column1: qsTr("Fastest (x200 fee)") ; column2: ""; priority: 4 }
|
||||||
}
|
}
|
||||||
|
|
||||||
StandardDropdown {
|
StandardDropdown {
|
||||||
@@ -249,20 +269,15 @@ Rectangle {
|
|||||||
appWindow.showPageRequest("AddressBook");
|
appWindow.showPageRequest("AddressBook");
|
||||||
}
|
}
|
||||||
pasteButton: true
|
pasteButton: true
|
||||||
onPaste: function(clipboardText) {
|
onTextChanged: {
|
||||||
const parsed = walletManager.parse_uri_to_object(clipboardText);
|
const parsed = walletManager.parse_uri_to_object(text);
|
||||||
if (!parsed.error) {
|
if (!parsed.error) {
|
||||||
addressLine.text = parsed.address;
|
addressLine.text = parsed.address;
|
||||||
setPaymentId(parsed.payment_id);
|
setPaymentId(parsed.payment_id);
|
||||||
amountLine.text = parsed.amount;
|
amountLine.text = parsed.amount;
|
||||||
setDescription(parsed.tx_description);
|
setDescription(parsed.tx_description);
|
||||||
} else {
|
|
||||||
addressLine.text = clipboardText;
|
|
||||||
}
|
}
|
||||||
}
|
warningLongPidTransfer = isLongPidService(text);
|
||||||
onTextChanged: {
|
|
||||||
// @TODO: remove after pid removal hardfork
|
|
||||||
warningLongPidTransfer = !persistentSettings.showPid && isLongPidService(text)
|
|
||||||
}
|
}
|
||||||
inlineButton.text: FontAwesome.qrcode
|
inlineButton.text: FontAwesome.qrcode
|
||||||
inlineButton.fontPixelSize: 22
|
inlineButton.fontPixelSize: 22
|
||||||
@@ -323,6 +338,12 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoneroComponents.WarningBox {
|
||||||
|
text: qsTr("Description field contents match long payment ID format. \
|
||||||
|
Please don't paste long payment ID into description field, your funds might be lost.") + translationManager.emptyString;
|
||||||
|
visible: warningLongPidDescription
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 15
|
spacing: 15
|
||||||
|
|
||||||
@@ -330,8 +351,9 @@ Rectangle {
|
|||||||
CheckBox {
|
CheckBox {
|
||||||
id: descriptionCheckbox
|
id: descriptionCheckbox
|
||||||
border: false
|
border: false
|
||||||
checkedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
checkedIcon: FontAwesome.minusCircle
|
||||||
uncheckedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
uncheckedIcon: FontAwesome.plusCircle
|
||||||
|
fontAwesomeIcons: true
|
||||||
fontSize: descriptionLine.labelFontSize
|
fontSize: descriptionLine.labelFontSize
|
||||||
iconOnTheLeft: true
|
iconOnTheLeft: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -352,13 +374,14 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
visible: appWindow.persistentSettings.showPid || paymentIdCheckbox.checked
|
visible: paymentIdCheckbox.checked
|
||||||
// @TODO: remove after pid removal hardfork
|
// @TODO: remove after pid removal hardfork
|
||||||
CheckBox {
|
CheckBox {
|
||||||
id: paymentIdCheckbox
|
id: paymentIdCheckbox
|
||||||
border: false
|
border: false
|
||||||
checkedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
checkedIcon: FontAwesome.minusCircle
|
||||||
uncheckedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
uncheckedIcon: FontAwesome.plusCircle
|
||||||
|
fontAwesomeIcons: true
|
||||||
fontSize: paymentIdLine.labelFontSize
|
fontSize: paymentIdLine.labelFontSize
|
||||||
iconOnTheLeft: true
|
iconOnTheLeft: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -375,6 +398,7 @@ Rectangle {
|
|||||||
id: paymentIdLine
|
id: paymentIdLine
|
||||||
fontBold: true
|
fontBold: true
|
||||||
placeholderText: qsTr("64 hexadecimal characters") + translationManager.emptyString
|
placeholderText: qsTr("64 hexadecimal characters") + translationManager.emptyString
|
||||||
|
readOnly: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
wrapMode: Text.WrapAnywhere
|
wrapMode: Text.WrapAnywhere
|
||||||
addressValidation: false
|
addressValidation: false
|
||||||
@@ -386,8 +410,10 @@ Rectangle {
|
|||||||
MoneroComponents.WarningBox {
|
MoneroComponents.WarningBox {
|
||||||
// @TODO: remove after pid removal hardfork
|
// @TODO: remove after pid removal hardfork
|
||||||
id: paymentIdWarningBox
|
id: paymentIdWarningBox
|
||||||
text: qsTr("You can enable transfers with payment ID on the settings page.") + translationManager.emptyString;
|
text: qsTr("Long payment IDs are obsolete. \
|
||||||
visible: !persistentSettings.showPid && (warningLongPidTransfer || warningLongPidDescription)
|
Long payment IDs were not encrypted on the blockchain and would harm your privacy. \
|
||||||
|
If the party you're sending to still requires a long payment ID, please notify them.") + translationManager.emptyString;
|
||||||
|
visible: warningLongPidTransfer || paymentIdCheckbox.checked
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.WarningBox {
|
MoneroComponents.WarningBox {
|
||||||
@@ -443,7 +469,7 @@ Rectangle {
|
|||||||
anchors.top: pageRoot.bottom
|
anchors.top: pageRoot.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 32
|
anchors.topMargin: 32
|
||||||
spacing: 26
|
spacing: 26
|
||||||
enabled: !viewOnly || pageRoot.enabled
|
enabled: !viewOnly || pageRoot.enabled
|
||||||
@@ -462,7 +488,7 @@ Rectangle {
|
|||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
visible: persistentSettings.transferShowAdvanced && appWindow.walletMode >= 2
|
visible: persistentSettings.transferShowAdvanced && appWindow.walletMode >= 2
|
||||||
columns: (isMobile) ? 2 : 6
|
columns: 6
|
||||||
|
|
||||||
StandardButton {
|
StandardButton {
|
||||||
id: sweepUnmixableButton
|
id: sweepUnmixableButton
|
||||||
@@ -740,7 +766,8 @@ Rectangle {
|
|||||||
|
|
||||||
// Currently opened wallet is not view-only
|
// Currently opened wallet is not view-only
|
||||||
if(appWindow.viewOnly){
|
if(appWindow.viewOnly){
|
||||||
root.sendButtonWarning = qsTr("Wallet is view-only and sends are not possible.") + translationManager.emptyString;
|
root.sendButtonWarning = qsTr("Wallet is view-only and sends are not possible. Unless key images are imported, " +
|
||||||
|
"the balance reflects only incoming but not outgoing transactions.") + translationManager.emptyString;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -761,6 +788,11 @@ Rectangle {
|
|||||||
root.sendButtonWarning = qsTr("Transaction information is incorrect.") + translationManager.emptyString;
|
root.sendButtonWarning = qsTr("Transaction information is incorrect.") + translationManager.emptyString;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (paymentIdWarningBox.visible) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ Rectangle {
|
|||||||
/* main layout */
|
/* main layout */
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ Item {
|
|||||||
property var hiddenAmounts: []
|
property var hiddenAmounts: []
|
||||||
|
|
||||||
function onPageCompleted() {
|
function onPageCompleted() {
|
||||||
appWindow.hideMenu();
|
|
||||||
|
|
||||||
// prepare tracking
|
// prepare tracking
|
||||||
trackingCheckbox.checked = root.enableTracking
|
trackingCheckbox.checked = root.enableTracking
|
||||||
root.update();
|
root.update();
|
||||||
@@ -56,8 +54,6 @@ Item {
|
|||||||
timer.running = false
|
timer.running = false
|
||||||
root.enableTracking = false
|
root.enableTracking = false
|
||||||
trackingModel.clear()
|
trackingModel.clear()
|
||||||
|
|
||||||
appWindow.showMenu();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
@@ -162,7 +158,7 @@ Item {
|
|||||||
"<p>It's up to you whether to accept unconfirmed transactions or not. It is likely they'll be " +
|
"<p>It's up to you whether to accept unconfirmed transactions or not. It is likely they'll be " +
|
||||||
"confirmed in short order, but there is still a possibility they might not, so for larger " +
|
"confirmed in short order, but there is still a possibility they might not, so for larger " +
|
||||||
"values you may want to wait for one or more confirmation(s).</p>"
|
"values you may want to wait for one or more confirmation(s).</p>"
|
||||||
);
|
) + translationManager.emptyString;
|
||||||
} else if(root.trackingError !== ""){
|
} else if(root.trackingError !== ""){
|
||||||
return root.trackingError;
|
return root.trackingError;
|
||||||
} else if(trackingModel.count < 1){
|
} else if(trackingModel.count < 1){
|
||||||
@@ -269,7 +265,7 @@ Item {
|
|||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.bold: false
|
font.bold: false
|
||||||
color: "white"
|
color: "white"
|
||||||
text: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 12px;}</style>Currently selected address: " + addressLabel + " <a href='#'>(Change)</a>"
|
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 12px;}</style>Currently selected address: ") + addressLabel + qsTr(" <a href='#'>(Change)</a>") + translationManager.emptyString
|
||||||
textFormat: Text.RichText
|
textFormat: Text.RichText
|
||||||
themeTransition: false
|
themeTransition: false
|
||||||
|
|
||||||
@@ -450,7 +446,7 @@ Item {
|
|||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
font.bold: false
|
font.bold: false
|
||||||
color: "white"
|
color: "white"
|
||||||
text: qsTr("Amount to receive") + " (XMR)"
|
text: qsTr("Amount to receive") + " (XMR)" + translationManager.emptyString
|
||||||
themeTransition: false
|
themeTransition: false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,7 +455,7 @@ Item {
|
|||||||
width: 220
|
width: 220
|
||||||
source: "qrc:///images/merchant/input_box.png"
|
source: "qrc:///images/merchant/input_box.png"
|
||||||
|
|
||||||
TextField {
|
MoneroComponents.Input {
|
||||||
id: amountToReceive
|
id: amountToReceive
|
||||||
topPadding: 0
|
topPadding: 0
|
||||||
leftPadding: 10
|
leftPadding: 10
|
||||||
|
|||||||
@@ -4,38 +4,55 @@ import QtGraphicalEffects 1.0
|
|||||||
|
|
||||||
import "../../components" as MoneroComponents
|
import "../../components" as MoneroComponents
|
||||||
|
|
||||||
RowLayout {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
spacing: 10
|
|
||||||
property bool checked: false;
|
property bool checked: false;
|
||||||
property alias text: content.text
|
property alias text: content.text
|
||||||
signal changed;
|
signal changed;
|
||||||
|
|
||||||
Rectangle {
|
width: checkBoxLayout.width
|
||||||
id: checkbox
|
height: 22
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.top: parent.top
|
|
||||||
implicitHeight: 22
|
|
||||||
width: 22
|
|
||||||
radius: 5
|
|
||||||
|
|
||||||
Image {
|
RowLayout {
|
||||||
id: imageChecked
|
id: checkBoxLayout
|
||||||
visible: root.checked
|
spacing: 10
|
||||||
anchors.centerIn: parent
|
|
||||||
source: "qrc:///images/uncheckedIcon.png"
|
Item {
|
||||||
|
height: root.height
|
||||||
|
width: root.height
|
||||||
|
Rectangle {
|
||||||
|
id: checkbox
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: 5
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: imageChecked
|
||||||
|
visible: root.checked
|
||||||
|
anchors.centerIn: parent
|
||||||
|
source: "qrc:///images/uncheckedIcon.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DropShadow {
|
||||||
|
anchors.fill: source
|
||||||
|
cached: true
|
||||||
|
horizontalOffset: 3
|
||||||
|
verticalOffset: 3
|
||||||
|
radius: 8.0
|
||||||
|
samples: 16
|
||||||
|
color: "#20000000"
|
||||||
|
smooth: true
|
||||||
|
source: checkbox
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MoneroComponents.TextPlain {
|
||||||
|
id: content
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.bold: false
|
||||||
|
color: "white"
|
||||||
|
text: ""
|
||||||
|
themeTransition: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
id: content
|
|
||||||
font.pixelSize: 14
|
|
||||||
font.bold: false
|
|
||||||
color: "white"
|
|
||||||
text: ""
|
|
||||||
themeTransition: false
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
@@ -46,16 +63,4 @@ RowLayout {
|
|||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DropShadow {
|
|
||||||
anchors.fill: source
|
|
||||||
cached: true
|
|
||||||
horizontalOffset: 3
|
|
||||||
verticalOffset: 3
|
|
||||||
radius: 8.0
|
|
||||||
samples: 16
|
|
||||||
color: "#20000000"
|
|
||||||
smooth: true
|
|
||||||
source: checkbox
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ Rectangle {
|
|||||||
property bool showCloseButton: true
|
property bool showCloseButton: true
|
||||||
|
|
||||||
height: {
|
height: {
|
||||||
if(!persistentSettings.customDecorations || isMobile) return 0;
|
if(!persistentSettings.customDecorations) return 0;
|
||||||
return 50;
|
return 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,9 +61,7 @@ Rectangle {
|
|||||||
property string borderColor: MoneroComponents.Style.blackTheme ? "#808080" : "#B9B9B9"
|
property string borderColor: MoneroComponents.Style.blackTheme ? "#808080" : "#B9B9B9"
|
||||||
property int textMargin: {
|
property int textMargin: {
|
||||||
// left-right margins for a given cell
|
// left-right margins for a given cell
|
||||||
if(isMobile){
|
if(appWindow.width < 890){
|
||||||
return 10;
|
|
||||||
} else if(appWindow.width < 890){
|
|
||||||
return 32;
|
return 32;
|
||||||
} else {
|
} else {
|
||||||
return 64;
|
return 64;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ Rectangle {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 0
|
anchors.topMargin: 0
|
||||||
spacing: 30
|
spacing: 30
|
||||||
|
|
||||||
|
|||||||
@@ -47,12 +47,11 @@ Rectangle {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 0
|
anchors.topMargin: 0
|
||||||
spacing: 6
|
spacing: 6
|
||||||
|
|
||||||
MoneroComponents.CheckBox {
|
MoneroComponents.CheckBox {
|
||||||
visible: !isMobile
|
|
||||||
id: customDecorationsCheckBox
|
id: customDecorationsCheckBox
|
||||||
checked: persistentSettings.customDecorations
|
checked: persistentSettings.customDecorations
|
||||||
onClicked: Windows.setCustomWindowDecorations(checked)
|
onClicked: Windows.setCustomWindowDecorations(checked)
|
||||||
@@ -60,7 +59,6 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.CheckBox {
|
MoneroComponents.CheckBox {
|
||||||
visible: !isMobile
|
|
||||||
id: hideBalanceCheckBox
|
id: hideBalanceCheckBox
|
||||||
checked: persistentSettings.hideBalance
|
checked: persistentSettings.hideBalance
|
||||||
onClicked: {
|
onClicked: {
|
||||||
@@ -70,20 +68,11 @@ Rectangle {
|
|||||||
text: qsTr("Hide balance") + translationManager.emptyString
|
text: qsTr("Hide balance") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.CheckBox {
|
|
||||||
visible: !isMobile
|
|
||||||
id: showPidCheckBox
|
|
||||||
checked: persistentSettings.showPid
|
|
||||||
onClicked: {
|
|
||||||
persistentSettings.showPid = !persistentSettings.showPid
|
|
||||||
}
|
|
||||||
text: qsTr("Enable transfer with payment ID (OBSOLETE)") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.CheckBox {
|
MoneroComponents.CheckBox {
|
||||||
id: themeCheckbox
|
id: themeCheckbox
|
||||||
checked: !MoneroComponents.Style.blackTheme
|
checked: !MoneroComponents.Style.blackTheme
|
||||||
text: qsTr("Light theme") + translationManager.emptyString
|
text: qsTr("Light theme") + translationManager.emptyString
|
||||||
|
toggleOnClick: false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
MoneroComponents.Style.blackTheme = !MoneroComponents.Style.blackTheme;
|
MoneroComponents.Style.blackTheme = !MoneroComponents.Style.blackTheme;
|
||||||
persistentSettings.blackTheme = MoneroComponents.Style.blackTheme;
|
persistentSettings.blackTheme = MoneroComponents.Style.blackTheme;
|
||||||
@@ -91,7 +80,6 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.CheckBox {
|
MoneroComponents.CheckBox {
|
||||||
visible: !isMobile
|
|
||||||
id: userInActivityCheckbox
|
id: userInActivityCheckbox
|
||||||
checked: persistentSettings.lockOnUserInActivity
|
checked: persistentSettings.lockOnUserInActivity
|
||||||
onClicked: persistentSettings.lockOnUserInActivity = !persistentSettings.lockOnUserInActivity
|
onClicked: persistentSettings.lockOnUserInActivity = !persistentSettings.lockOnUserInActivity
|
||||||
@@ -105,7 +93,8 @@ Rectangle {
|
|||||||
Layout.leftMargin: 42
|
Layout.leftMargin: 42
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
MoneroComponents.TextBlock {
|
Text {
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: {
|
text: {
|
||||||
@@ -154,6 +143,12 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMoved: persistentSettings.lockOnUserInActivityInterval = userInactivitySlider.value;
|
onMoved: persistentSettings.lockOnUserInActivityInterval = userInactivitySlider.value;
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,14 +262,6 @@ Rectangle {
|
|||||||
appWindow.toggleLanguageView();
|
appWindow.toggleLanguageView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.TextBlock {
|
|
||||||
visible: isMobile
|
|
||||||
font.pixelSize: 14
|
|
||||||
textFormat: Text.RichText
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("No Layout options exist yet in mobile mode.") + translationManager.emptyString;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ Rectangle {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 0
|
anchors.topMargin: 0
|
||||||
spacing: 10
|
spacing: 10
|
||||||
|
|
||||||
@@ -216,7 +216,11 @@ Rectangle {
|
|||||||
onAccepted: {
|
onAccepted: {
|
||||||
if(text.length > 0) {
|
if(text.length > 0) {
|
||||||
consoleArea.logCommand(">>> " + text)
|
consoleArea.logCommand(">>> " + text)
|
||||||
daemonManager.sendCommand(text, currentWallet.nettype);
|
daemonManager.sendCommandAsync(text.split(" "), currentWallet.nettype, function(result) {
|
||||||
|
if (!result) {
|
||||||
|
appWindow.showStatusMessage(qsTr("Failed to send command"), 3);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
text = ""
|
text = ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Rectangle{
|
|||||||
/* main layout */
|
/* main layout */
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: root
|
id: root
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 0
|
anchors.topMargin: 0
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -96,17 +96,13 @@ Rectangle{
|
|||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
MoneroEffects.ImageMask {
|
MoneroComponents.Label {
|
||||||
height: 27
|
fontSize: 32
|
||||||
width: 27
|
text: FontAwesome.home
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
fontFamily: FontAwesome.fontFamilySolid
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.centerIn: parent
|
||||||
fontAwesomeFallbackIcon: FontAwesome.shield
|
fontColor: MoneroComponents.Style.defaultFontColor
|
||||||
fontAwesomeFallbackSize: 26
|
styleName: "Solid"
|
||||||
image: "qrc:///images/settings_local.svg"
|
|
||||||
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
opacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.8
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +119,7 @@ Rectangle{
|
|||||||
text: qsTr("Local node") + translationManager.emptyString
|
text: qsTr("Local node") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
TextArea {
|
Text {
|
||||||
id: localNodeArea
|
id: localNodeArea
|
||||||
anchors.top: localNodeHeader.bottom
|
anchors.top: localNodeHeader.bottom
|
||||||
anchors.topMargin: 4
|
anchors.topMargin: 4
|
||||||
@@ -133,14 +129,11 @@ Rectangle{
|
|||||||
font.family: MoneroComponents.Style.fontRegular.name
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
selectByMouse: false
|
|
||||||
wrapMode: Text.WordWrap;
|
wrapMode: Text.WordWrap;
|
||||||
textMargin: 0
|
|
||||||
leftPadding: 0
|
leftPadding: 0
|
||||||
topPadding: 0
|
topPadding: 0
|
||||||
text: qsTr("The blockchain is downloaded to your computer. Provides higher security and requires more local storage.") + translationManager.emptyString
|
text: qsTr("The blockchain is downloaded to your computer. Provides higher security and requires more local storage.") + translationManager.emptyString
|
||||||
width: parent.width - (localNodeIcon.width + localNodeIcon.anchors.leftMargin + anchors.leftMargin)
|
width: parent.width - (localNodeIcon.width + localNodeIcon.anchors.leftMargin + anchors.leftMargin)
|
||||||
readOnly: true
|
|
||||||
|
|
||||||
// @TODO: Legacy. Remove after Qt 5.8.
|
// @TODO: Legacy. Remove after Qt 5.8.
|
||||||
// https://stackoverflow.com/questions/41990013
|
// https://stackoverflow.com/questions/41990013
|
||||||
@@ -202,16 +195,13 @@ Rectangle{
|
|||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
MoneroEffects.ImageMask {
|
MoneroComponents.Label {
|
||||||
height: 29
|
fontSize: 28
|
||||||
width: 22
|
text: FontAwesome.cloud
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
fontFamily: FontAwesome.fontFamilySolid
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
styleName: "Solid"
|
||||||
fontAwesomeFallbackIcon: FontAwesome.cloudDownload
|
anchors.centerIn: parent
|
||||||
fontAwesomeFallbackSize: 26
|
fontColor: MoneroComponents.Style.defaultFontColor
|
||||||
image: "qrc:///images/settings_remote.svg"
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
opacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.8
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +218,7 @@ Rectangle{
|
|||||||
text: qsTr("Remote node") + translationManager.emptyString
|
text: qsTr("Remote node") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
TextArea {
|
Text {
|
||||||
id: remoteNodeArea
|
id: remoteNodeArea
|
||||||
anchors.top: remoteNodeHeader.bottom
|
anchors.top: remoteNodeHeader.bottom
|
||||||
anchors.topMargin: 4
|
anchors.topMargin: 4
|
||||||
@@ -237,16 +227,12 @@ Rectangle{
|
|||||||
color: MoneroComponents.Style.dimmedFontColor
|
color: MoneroComponents.Style.dimmedFontColor
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
activeFocusOnPress: false
|
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
selectByMouse: false
|
|
||||||
wrapMode: Text.WordWrap;
|
wrapMode: Text.WordWrap;
|
||||||
textMargin: 0
|
|
||||||
leftPadding: 0
|
leftPadding: 0
|
||||||
topPadding: 0
|
topPadding: 0
|
||||||
text: qsTr("Uses a third-party server to connect to the Monero network. Less secure, but easier on your computer.") + translationManager.emptyString
|
text: qsTr("Uses a third-party server to connect to the Monero network. Less secure, but easier on your computer.") + translationManager.emptyString
|
||||||
width: parent.width - (remoteNodeIcon.width + remoteNodeIcon.anchors.leftMargin + anchors.leftMargin)
|
width: parent.width - (remoteNodeIcon.width + remoteNodeIcon.anchors.leftMargin + anchors.leftMargin)
|
||||||
readOnly: true
|
|
||||||
|
|
||||||
// @TODO: Legacy. Remove after Qt 5.8.
|
// @TODO: Legacy. Remove after Qt 5.8.
|
||||||
// https://stackoverflow.com/questions/41990013
|
// https://stackoverflow.com/questions/41990013
|
||||||
@@ -260,7 +246,6 @@ Rectangle{
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
persistentSettings.useRemoteNode = true;
|
|
||||||
appWindow.connectRemoteNode();
|
appWindow.connectRemoteNode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -285,7 +270,7 @@ Rectangle{
|
|||||||
spacing: 20
|
spacing: 20
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
visible: !isMobile && persistentSettings.useRemoteNode
|
visible: persistentSettings.useRemoteNode
|
||||||
|
|
||||||
MoneroComponents.WarningBox {
|
MoneroComponents.WarningBox {
|
||||||
Layout.topMargin: 26
|
Layout.topMargin: 26
|
||||||
@@ -317,7 +302,7 @@ Rectangle{
|
|||||||
}
|
}
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
columns: (isMobile) ? 1 : 2
|
columns: 2
|
||||||
columnSpacing: 32
|
columnSpacing: 32
|
||||||
|
|
||||||
MoneroComponents.LineEdit {
|
MoneroComponents.LineEdit {
|
||||||
@@ -377,11 +362,11 @@ Rectangle{
|
|||||||
id: localNodeLayout
|
id: localNodeLayout
|
||||||
spacing: 20
|
spacing: 20
|
||||||
Layout.topMargin: 40
|
Layout.topMargin: 40
|
||||||
visible: !isMobile && !persistentSettings.useRemoteNode
|
visible: !persistentSettings.useRemoteNode
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
MoneroComponents.StandardButton {
|
||||||
small: true
|
small: true
|
||||||
text: (appWindow.daemonRunning ? qsTr("Stop local node") : qsTr("Start daemon")) + translationManager.emptyString
|
text: (appWindow.daemonRunning ? qsTr("Stop daemon") : qsTr("Start daemon")) + translationManager.emptyString
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (appWindow.daemonRunning) {
|
if (appWindow.daemonRunning) {
|
||||||
appWindow.stopDaemon();
|
appWindow.stopDaemon();
|
||||||
@@ -403,6 +388,7 @@ Rectangle{
|
|||||||
labelText: qsTr("Blockchain location") + style + qsTr(" <a href='#'> (change)</a>") + translationManager.emptyString
|
labelText: qsTr("Blockchain location") + style + qsTr(" <a href='#'> (change)</a>") + translationManager.emptyString
|
||||||
placeholderText: qsTr("(default)") + translationManager.emptyString
|
placeholderText: qsTr("(default)") + translationManager.emptyString
|
||||||
placeholderFontSize: 15
|
placeholderFontSize: 15
|
||||||
|
readOnly: true
|
||||||
text: {
|
text: {
|
||||||
if(persistentSettings.blockchainDataDir.length > 0){
|
if(persistentSettings.blockchainDataDir.length > 0){
|
||||||
return persistentSettings.blockchainDataDir;
|
return persistentSettings.blockchainDataDir;
|
||||||
@@ -435,7 +421,7 @@ Rectangle{
|
|||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
visible: !isMobile && !persistentSettings.useRemoteNode
|
visible: !persistentSettings.useRemoteNode
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -457,7 +443,11 @@ Rectangle{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
persistentSettings.bootstrapNodeAddress = daemonAddrText ? bootstrapNodeEdit.getAddress() : "";
|
if (daemonAddrText == "auto") {
|
||||||
|
persistentSettings.bootstrapNodeAddress = daemonAddrText;
|
||||||
|
} else {
|
||||||
|
persistentSettings.bootstrapNodeAddress = daemonAddrText ? bootstrapNodeEdit.getAddress() : "";
|
||||||
|
}
|
||||||
console.log("setting bootstrap node to " + persistentSettings.bootstrapNodeAddress)
|
console.log("setting bootstrap node to " + persistentSettings.bootstrapNodeAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,314 +45,99 @@ Rectangle {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: (isMobile)? 17 : 20
|
anchors.margins: 20
|
||||||
anchors.topMargin: 0
|
anchors.topMargin: 0
|
||||||
spacing: 0
|
spacing: 8
|
||||||
|
|
||||||
Rectangle {
|
MoneroComponents.SettingsListItem {
|
||||||
// divider
|
buttonText: qsTr("Close wallet") + translationManager.emptyString
|
||||||
Layout.preferredHeight: 1
|
description: qsTr("Logs out of this wallet.") + translationManager.emptyString
|
||||||
Layout.fillWidth: true
|
title: qsTr("Close this wallet") + translationManager.emptyString
|
||||||
Layout.bottomMargin: 8
|
|
||||||
color: MoneroComponents.Style.dividerColor
|
|
||||||
opacity: MoneroComponents.Style.dividerOpacity
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout {
|
onClicked: {
|
||||||
Layout.fillWidth: true
|
middlePanel.addressBookView.clearFields();
|
||||||
Layout.preferredHeight: childrenRect.height
|
middlePanel.transferView.clearFields();
|
||||||
columnSpacing: 0
|
middlePanel.receiveView.clearFields();
|
||||||
|
appWindow.showWizard();
|
||||||
ColumnLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 20
|
|
||||||
Layout.topMargin: 8
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
opacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.8
|
|
||||||
font.bold: true
|
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
|
||||||
font.pixelSize: 16
|
|
||||||
text: qsTr("Close this wallet") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlainArea {
|
|
||||||
color: MoneroComponents.Style.dimmedFontColor
|
|
||||||
colorBlackTheme: MoneroComponents.Style._b_dimmedFontColor
|
|
||||||
colorWhiteTheme: MoneroComponents.Style._w_dimmedFontColor
|
|
||||||
width: parent.width
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
|
||||||
text: qsTr("Logs out of this wallet.") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
|
||||||
small: true
|
|
||||||
text: qsTr("Close wallet") + translationManager.emptyString
|
|
||||||
onClicked: {
|
|
||||||
middlePanel.addressBookView.clearFields();
|
|
||||||
middlePanel.transferView.clearFields();
|
|
||||||
middlePanel.receiveView.clearFields();
|
|
||||||
appWindow.showWizard();
|
|
||||||
}
|
|
||||||
width: 135
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
MoneroComponents.SettingsListItem {
|
||||||
// divider
|
buttonText: qsTr("Create wallet") + translationManager.emptyString
|
||||||
Layout.preferredHeight: 1
|
description: qsTr("Creates a new wallet that can only view and initiate transactions, but requires a spendable wallet to sign transactions before sending.") + translationManager.emptyString
|
||||||
Layout.fillWidth: true
|
title: qsTr("Create a view-only wallet") + translationManager.emptyString
|
||||||
Layout.topMargin: 8
|
|
||||||
Layout.bottomMargin: 8
|
|
||||||
color: MoneroComponents.Style.dividerColor
|
|
||||||
opacity: MoneroComponents.Style.dividerOpacity
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: childrenRect.height
|
|
||||||
columnSpacing: 0
|
|
||||||
visible: !appWindow.viewOnly
|
visible: !appWindow.viewOnly
|
||||||
|
|
||||||
ColumnLayout {
|
onClicked: {
|
||||||
Layout.fillWidth: true
|
var newPath = currentWallet.path + "_viewonly";
|
||||||
Layout.alignment: Qt.AlignVCenter
|
if (currentWallet.createViewOnly(newPath, appWindow.walletPassword)) {
|
||||||
spacing: 0
|
console.log("view only wallet created in " + newPath);
|
||||||
|
informationPopup.title = qsTr("Success") + translationManager.emptyString;
|
||||||
MoneroComponents.TextPlain {
|
informationPopup.text = qsTr('The view only wallet has been created with the same password as the current wallet. You can open it by closing this current wallet, clicking the "Open wallet from file" option, and selecting the view wallet in: \n%1\nYou can change the password in the wallet settings.').arg(newPath);
|
||||||
Layout.fillWidth: true
|
informationPopup.open()
|
||||||
Layout.preferredHeight: 20
|
informationPopup.onCloseCallback = null
|
||||||
Layout.topMargin: 8
|
} else {
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
opacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.8
|
informationPopup.text = currentWallet.errorString;
|
||||||
font.bold: true
|
informationPopup.open()
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
|
||||||
font.pixelSize: 16
|
|
||||||
text: qsTr("Create a view-only wallet") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlainArea {
|
|
||||||
color: MoneroComponents.Style.dimmedFontColor
|
|
||||||
colorBlackTheme: MoneroComponents.Style._b_dimmedFontColor
|
|
||||||
colorWhiteTheme: MoneroComponents.Style._w_dimmedFontColor
|
|
||||||
width: parent.width
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
|
||||||
text: qsTr("Creates a new wallet that can only view and initiate transactions, but requires a spendable wallet to sign transactions before sending.") + translationManager.emptyString
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
MoneroComponents.SettingsListItem {
|
||||||
small: true
|
buttonText: qsTr("Show seed") + translationManager.emptyString
|
||||||
text: qsTr("Create wallet") + translationManager.emptyString
|
description: qsTr("Store this information safely to recover your wallet in the future.") + translationManager.emptyString
|
||||||
onClicked: {
|
title: qsTr("Show seed & keys") + translationManager.emptyString
|
||||||
var newPath = currentWallet.path + "_viewonly";
|
|
||||||
if (currentWallet.createViewOnly(newPath, appWindow.walletPassword)) {
|
onClicked: {
|
||||||
console.log("view only wallet created in " + newPath);
|
Utils.showSeedPage();
|
||||||
informationPopup.title = qsTr("Success") + translationManager.emptyString;
|
}
|
||||||
informationPopup.text = qsTr('The view only wallet has been created with the same password as the current wallet. You can open it by closing this current wallet, clicking the "Open wallet from file" option, and selecting the view wallet in: \n%1\nYou can change the password in the wallet settings.').arg(newPath);
|
}
|
||||||
informationPopup.open()
|
|
||||||
informationPopup.onCloseCallback = null
|
MoneroComponents.SettingsListItem {
|
||||||
|
buttonText: qsTr("Rescan") + translationManager.emptyString
|
||||||
|
description: qsTr("Use this feature if you think the shown balance is not accurate.") + translationManager.emptyString
|
||||||
|
title: qsTr("Rescan wallet balance") + translationManager.emptyString
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (!currentWallet.rescanSpent()) {
|
||||||
|
console.error("Error: ", currentWallet.errorString);
|
||||||
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
|
informationPopup.text = qsTr("Error: ") + currentWallet.errorString
|
||||||
|
informationPopup.icon = StandardIcon.Critical
|
||||||
|
informationPopup.onCloseCallback = null
|
||||||
|
informationPopup.open();
|
||||||
|
} else {
|
||||||
|
informationPopup.title = qsTr("Information") + translationManager.emptyString
|
||||||
|
informationPopup.text = qsTr("Successfully rescanned spent outputs.") + translationManager.emptyString
|
||||||
|
informationPopup.icon = StandardIcon.Information
|
||||||
|
informationPopup.onCloseCallback = null
|
||||||
|
informationPopup.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.SettingsListItem {
|
||||||
|
buttonText: qsTr("Change password") + translationManager.emptyString
|
||||||
|
description: qsTr("Change the password of your wallet.") + translationManager.emptyString
|
||||||
|
title: qsTr("Change wallet password") + translationManager.emptyString
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
passwordDialog.onAcceptedCallback = function() {
|
||||||
|
if(appWindow.walletPassword === passwordDialog.password){
|
||||||
|
passwordDialog.openNewPasswordDialog()
|
||||||
} else {
|
} else {
|
||||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
||||||
informationPopup.text = currentWallet.errorString;
|
informationPopup.text = qsTr("Wrong password") + translationManager.emptyString;
|
||||||
informationPopup.open()
|
informationPopup.open()
|
||||||
|
informationPopup.onCloseCallback = function() {
|
||||||
|
passwordDialog.open()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
width: 135
|
passwordDialog.onRejectedCallback = null;
|
||||||
}
|
passwordDialog.open()
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
// divider
|
|
||||||
visible: !appWindow.viewOnly
|
|
||||||
Layout.preferredHeight: 1
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 8
|
|
||||||
Layout.bottomMargin: 8
|
|
||||||
color: MoneroComponents.Style.dividerColor
|
|
||||||
opacity: MoneroComponents.Style.dividerOpacity
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: childrenRect.height
|
|
||||||
columnSpacing: 0
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 20
|
|
||||||
Layout.topMargin: 8
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
opacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.8
|
|
||||||
font.bold: true
|
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
|
||||||
font.pixelSize: 16
|
|
||||||
text: qsTr("Show seed & keys") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlainArea {
|
|
||||||
color: MoneroComponents.Style.dimmedFontColor
|
|
||||||
colorBlackTheme: MoneroComponents.Style._b_dimmedFontColor
|
|
||||||
colorWhiteTheme: MoneroComponents.Style._w_dimmedFontColor
|
|
||||||
width: parent.width
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
|
||||||
text: qsTr("Store this information safely to recover your wallet in the future.") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
|
||||||
small: true
|
|
||||||
text: qsTr("Show seed") + translationManager.emptyString
|
|
||||||
onClicked: {
|
|
||||||
Utils.showSeedPage();
|
|
||||||
}
|
|
||||||
width: 135
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
// divider
|
|
||||||
Layout.preferredHeight: 1
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 8
|
|
||||||
Layout.bottomMargin: 8
|
|
||||||
color: MoneroComponents.Style.dividerColor
|
|
||||||
opacity: MoneroComponents.Style.dividerOpacity
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
visible: appWindow.walletMode >= 2
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: childrenRect.height
|
|
||||||
columnSpacing: 0
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 20
|
|
||||||
Layout.topMargin: 8
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
opacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.8
|
|
||||||
font.bold: true
|
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
|
||||||
font.pixelSize: 16
|
|
||||||
text: qsTr("Rescan wallet balance") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlainArea {
|
|
||||||
color: MoneroComponents.Style.dimmedFontColor
|
|
||||||
colorBlackTheme: MoneroComponents.Style._b_dimmedFontColor
|
|
||||||
colorWhiteTheme: MoneroComponents.Style._w_dimmedFontColor
|
|
||||||
width: parent.width
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
|
||||||
text: qsTr("Use this feature if you think the shown balance is not accurate.") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
|
||||||
small: true
|
|
||||||
text: qsTr("Rescan") + translationManager.emptyString
|
|
||||||
onClicked: {
|
|
||||||
if (!currentWallet.rescanSpent()) {
|
|
||||||
console.error("Error: ", currentWallet.errorString);
|
|
||||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
|
||||||
informationPopup.text = qsTr("Error: ") + currentWallet.errorString
|
|
||||||
informationPopup.icon = StandardIcon.Critical
|
|
||||||
informationPopup.onCloseCallback = null
|
|
||||||
informationPopup.open();
|
|
||||||
} else {
|
|
||||||
informationPopup.title = qsTr("Information") + translationManager.emptyString
|
|
||||||
informationPopup.text = qsTr("Successfully rescanned spent outputs.") + translationManager.emptyString
|
|
||||||
informationPopup.icon = StandardIcon.Information
|
|
||||||
informationPopup.onCloseCallback = null
|
|
||||||
informationPopup.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
width: 135
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
// divider
|
|
||||||
visible: appWindow.walletMode >= 2
|
|
||||||
Layout.preferredHeight: 1
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 8
|
|
||||||
Layout.bottomMargin: 8
|
|
||||||
color: MoneroComponents.Style.dividerColor
|
|
||||||
opacity: MoneroComponents.Style.dividerOpacity
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: childrenRect.height
|
|
||||||
columnSpacing: 0
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 20
|
|
||||||
Layout.topMargin: 8
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
opacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.8
|
|
||||||
font.bold: true
|
|
||||||
font.family: MoneroComponents.Style.fontRegular.name
|
|
||||||
font.pixelSize: 16
|
|
||||||
text: qsTr("Change wallet password") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlainArea {
|
|
||||||
color: MoneroComponents.Style.dimmedFontColor
|
|
||||||
colorBlackTheme: MoneroComponents.Style._b_dimmedFontColor
|
|
||||||
colorWhiteTheme: MoneroComponents.Style._w_dimmedFontColor
|
|
||||||
width: parent.width
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
|
||||||
text: qsTr("Change the password of your wallet.") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
|
||||||
small: true
|
|
||||||
text: qsTr("Change password") + translationManager.emptyString
|
|
||||||
onClicked: {
|
|
||||||
passwordDialog.onAcceptedCallback = function() {
|
|
||||||
if(appWindow.walletPassword === passwordDialog.password){
|
|
||||||
passwordDialog.openNewPasswordDialog()
|
|
||||||
} else {
|
|
||||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
|
||||||
informationPopup.text = qsTr("Wrong password") + translationManager.emptyString;
|
|
||||||
informationPopup.open()
|
|
||||||
informationPopup.onCloseCallback = function() {
|
|
||||||
passwordDialog.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
passwordDialog.onRejectedCallback = null;
|
|
||||||
passwordDialog.open()
|
|
||||||
}
|
|
||||||
width: 135
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
qml.qrc
@@ -7,11 +7,8 @@
|
|||||||
<file>images/download-white@2x.png</file>
|
<file>images/download-white@2x.png</file>
|
||||||
<file>images/external-link-white.png</file>
|
<file>images/external-link-white.png</file>
|
||||||
<file>images/external-link-white@2x.png</file>
|
<file>images/external-link-white@2x.png</file>
|
||||||
<file>images/minus-white.png</file>
|
|
||||||
<file>images/minus-white@2x.png</file>
|
|
||||||
<file>images/plus-white.png</file>
|
|
||||||
<file>images/plus-white@2x.png</file>
|
|
||||||
<file>components/Label.qml</file>
|
<file>components/Label.qml</file>
|
||||||
|
<file>components/SettingsListItem.qml</file>
|
||||||
<file>images/whatIsIcon.png</file>
|
<file>images/whatIsIcon.png</file>
|
||||||
<file>images/whatIsIcon@2x.png</file>
|
<file>images/whatIsIcon@2x.png</file>
|
||||||
<file>images/lockIcon.png</file>
|
<file>images/lockIcon.png</file>
|
||||||
@@ -21,6 +18,8 @@
|
|||||||
<file>pages/History.qml</file>
|
<file>pages/History.qml</file>
|
||||||
<file>pages/AddressBook.qml</file>
|
<file>pages/AddressBook.qml</file>
|
||||||
<file>pages/Mining.qml</file>
|
<file>pages/Mining.qml</file>
|
||||||
|
<file>components/ContextMenu.qml</file>
|
||||||
|
<file>components/ContextMenuItem.qml</file>
|
||||||
<file>components/NetworkStatusItem.qml</file>
|
<file>components/NetworkStatusItem.qml</file>
|
||||||
<file>components/Input.qml</file>
|
<file>components/Input.qml</file>
|
||||||
<file>components/StandardButton.qml</file>
|
<file>components/StandardButton.qml</file>
|
||||||
@@ -107,13 +106,14 @@
|
|||||||
<file>components/DaemonConsole.qml</file>
|
<file>components/DaemonConsole.qml</file>
|
||||||
<file>components/QRCodeScanner.qml</file>
|
<file>components/QRCodeScanner.qml</file>
|
||||||
<file>components/Notifier.qml</file>
|
<file>components/Notifier.qml</file>
|
||||||
<file>components/MobileHeader.qml</file>
|
|
||||||
<file>components/TextBlock.qml</file>
|
<file>components/TextBlock.qml</file>
|
||||||
<file>components/RemoteNodeEdit.qml</file>
|
<file>components/RemoteNodeEdit.qml</file>
|
||||||
<file>pages/Keys.qml</file>
|
<file>pages/Keys.qml</file>
|
||||||
<file>images/appicon.ico</file>
|
<file>images/appicon.ico</file>
|
||||||
<file>images/card-background.png</file>
|
<file>images/card-background-black.png</file>
|
||||||
<file>images/card-background@2x.png</file>
|
<file>images/card-background-black@2x.png</file>
|
||||||
|
<file>images/card-background-white.png</file>
|
||||||
|
<file>images/card-background-white@2x.png</file>
|
||||||
<file>images/moneroLogo_white.png</file>
|
<file>images/moneroLogo_white.png</file>
|
||||||
<file>images/question.png</file>
|
<file>images/question.png</file>
|
||||||
<file>images/question@2x.png</file>
|
<file>images/question@2x.png</file>
|
||||||
@@ -167,20 +167,18 @@
|
|||||||
<file>pages/settings/SettingsLayout.qml</file>
|
<file>pages/settings/SettingsLayout.qml</file>
|
||||||
<file>pages/settings/SettingsInfo.qml</file>
|
<file>pages/settings/SettingsInfo.qml</file>
|
||||||
<file>pages/settings/Navbar.qml</file>
|
<file>pages/settings/Navbar.qml</file>
|
||||||
<file>images/settings_local.svg</file>
|
|
||||||
<file>images/settings_remote.svg</file>
|
|
||||||
<file>components/WarningBox.qml</file>
|
<file>components/WarningBox.qml</file>
|
||||||
<file>images/miningxmr.png</file>
|
<file>images/miningxmr.png</file>
|
||||||
<file>images/miningxmr@2x.png</file>
|
<file>images/miningxmr@2x.png</file>
|
||||||
<file>images/plus-in-circle-medium-white.png</file>
|
|
||||||
<file>images/plus-in-circle-medium-white@2x.png</file>
|
|
||||||
<file>pages/merchant/Merchant.qml</file>
|
<file>pages/merchant/Merchant.qml</file>
|
||||||
<file>pages/merchant/MerchantCheckbox.qml</file>
|
<file>pages/merchant/MerchantCheckbox.qml</file>
|
||||||
<file>pages/merchant/MerchantTrackingList.qml</file>
|
<file>pages/merchant/MerchantTrackingList.qml</file>
|
||||||
<file>images/merchant/arrow_right.png</file>
|
<file>images/merchant/arrow_right.png</file>
|
||||||
<file>images/merchant/bg.png</file>
|
<file>images/merchant/bg.png</file>
|
||||||
<file>images/merchant/input_box.png</file>
|
<file>images/merchant/input_box.png</file>
|
||||||
<file>fonts/FontAwesome/fontawesome-webfont.ttf</file>
|
<file>fonts/FontAwesome/fa-brands-400.ttf</file>
|
||||||
|
<file>fonts/FontAwesome/fa-regular-400.ttf</file>
|
||||||
|
<file>fonts/FontAwesome/fa-solid-900.ttf</file>
|
||||||
<file>fonts/FontAwesome/FontAwesome.qml</file>
|
<file>fonts/FontAwesome/FontAwesome.qml</file>
|
||||||
<file>fonts/FontAwesome/Object.qml</file>
|
<file>fonts/FontAwesome/Object.qml</file>
|
||||||
<file>fonts/FontAwesome/qmldir</file>
|
<file>fonts/FontAwesome/qmldir</file>
|
||||||
@@ -236,7 +234,6 @@
|
|||||||
<file>images/middlePanelShadow.png</file>
|
<file>images/middlePanelShadow.png</file>
|
||||||
<file>images/themes/white/titlebarLogo@2x.png</file>
|
<file>images/themes/white/titlebarLogo@2x.png</file>
|
||||||
<file>images/themes/white/titlebarLogo.png</file>
|
<file>images/themes/white/titlebarLogo.png</file>
|
||||||
<file>images/sidebar.svg</file>
|
|
||||||
<file>images/fullscreen.svg</file>
|
<file>images/fullscreen.svg</file>
|
||||||
<file>images/close.svg</file>
|
<file>images/close.svg</file>
|
||||||
<file>images/minimize.svg</file>
|
<file>images/minimize.svg</file>
|
||||||
@@ -244,7 +241,6 @@
|
|||||||
<file>images/themes/white/fullscreen.svg</file>
|
<file>images/themes/white/fullscreen.svg</file>
|
||||||
<file>images/themes/white/minimize.svg</file>
|
<file>images/themes/white/minimize.svg</file>
|
||||||
<file>images/themes/white/question.svg</file>
|
<file>images/themes/white/question.svg</file>
|
||||||
<file>images/themes/white/expand.svg</file>
|
|
||||||
<file>components/effects/ColorTransition.qml</file>
|
<file>components/effects/ColorTransition.qml</file>
|
||||||
<file>components/effects/GradientBackground.qml</file>
|
<file>components/effects/GradientBackground.qml</file>
|
||||||
<file>images/check-white.svg</file>
|
<file>images/check-white.svg</file>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
static const int DAEMON_START_TIMEOUT_SECONDS = 30;
|
static const int DAEMON_START_TIMEOUT_SECONDS = 120;
|
||||||
}
|
}
|
||||||
|
|
||||||
DaemonManager * DaemonManager::m_instance = nullptr;
|
DaemonManager * DaemonManager::m_instance = nullptr;
|
||||||
@@ -61,7 +61,7 @@ DaemonManager *DaemonManager::instance(const QStringList *args)
|
|||||||
return m_instance;
|
return m_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DaemonManager::start(const QString &flags, NetworkType::Type nettype, const QString &dataDir, const QString &bootstrapNodeAddress)
|
bool DaemonManager::start(const QString &flags, NetworkType::Type nettype, const QString &dataDir, const QString &bootstrapNodeAddress, bool noSync /* = false*/)
|
||||||
{
|
{
|
||||||
// prepare command line arguments and pass to monerod
|
// prepare command line arguments and pass to monerod
|
||||||
QStringList arguments;
|
QStringList arguments;
|
||||||
@@ -99,6 +99,10 @@ bool DaemonManager::start(const QString &flags, NetworkType::Type nettype, const
|
|||||||
arguments << "--bootstrap-daemon-address" << bootstrapNodeAddress;
|
arguments << "--bootstrap-daemon-address" << bootstrapNodeAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (noSync) {
|
||||||
|
arguments << "--no-sync";
|
||||||
|
}
|
||||||
|
|
||||||
arguments << "--check-updates" << "disabled";
|
arguments << "--check-updates" << "disabled";
|
||||||
|
|
||||||
// --max-concurrency based on threads available. max: 6
|
// --max-concurrency based on threads available. max: 6
|
||||||
@@ -131,11 +135,13 @@ bool DaemonManager::start(const QString &flags, NetworkType::Type nettype, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start start watcher
|
// Start start watcher
|
||||||
m_scheduler.run([this, nettype] {
|
m_scheduler.run([this, nettype, noSync] {
|
||||||
if (startWatcher(nettype))
|
if (startWatcher(nettype)) {
|
||||||
emit daemonStarted();
|
emit daemonStarted();
|
||||||
else
|
m_noSync = noSync;
|
||||||
|
} else {
|
||||||
emit daemonStartFailure();
|
emit daemonStartFailure();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -144,7 +150,7 @@ bool DaemonManager::start(const QString &flags, NetworkType::Type nettype, const
|
|||||||
bool DaemonManager::stop(NetworkType::Type nettype)
|
bool DaemonManager::stop(NetworkType::Type nettype)
|
||||||
{
|
{
|
||||||
QString message;
|
QString message;
|
||||||
sendCommand("exit", nettype, message);
|
sendCommand({"exit"}, nettype, message);
|
||||||
qDebug() << message;
|
qDebug() << message;
|
||||||
|
|
||||||
// Start stop watcher - Will kill if not shutting down
|
// Start stop watcher - Will kill if not shutting down
|
||||||
@@ -234,26 +240,27 @@ void DaemonManager::printError()
|
|||||||
bool DaemonManager::running(NetworkType::Type nettype) const
|
bool DaemonManager::running(NetworkType::Type nettype) const
|
||||||
{
|
{
|
||||||
QString status;
|
QString status;
|
||||||
sendCommand("status", nettype, status);
|
sendCommand({"sync_info"}, nettype, status);
|
||||||
qDebug() << status;
|
qDebug() << status;
|
||||||
// `./monerod status` returns BUSY when syncing.
|
return status.contains("Height:");
|
||||||
// Treat busy as connected, until fixed upstream.
|
|
||||||
if (status.contains("Height:") || status.contains("BUSY") ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool DaemonManager::sendCommand(const QString &cmd, NetworkType::Type nettype) const
|
|
||||||
{
|
|
||||||
QString message;
|
|
||||||
return sendCommand(cmd, nettype, message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DaemonManager::sendCommand(const QString &cmd, NetworkType::Type nettype, QString &message) const
|
bool DaemonManager::noSync() const noexcept
|
||||||
|
{
|
||||||
|
return m_noSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DaemonManager::runningAsync(NetworkType::Type nettype, const QJSValue& callback) const
|
||||||
|
{
|
||||||
|
m_scheduler.run([this, nettype] {
|
||||||
|
return QJSValueList({running(nettype)});
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DaemonManager::sendCommand(const QStringList &cmd, NetworkType::Type nettype, QString &message) const
|
||||||
{
|
{
|
||||||
QProcess p;
|
QProcess p;
|
||||||
QStringList external_cmd;
|
QStringList external_cmd(cmd);
|
||||||
external_cmd << cmd;
|
|
||||||
|
|
||||||
// Add network type flag if needed
|
// Add network type flag if needed
|
||||||
if (nettype == NetworkType::TESTNET)
|
if (nettype == NetworkType::TESTNET)
|
||||||
@@ -272,6 +279,14 @@ bool DaemonManager::sendCommand(const QString &cmd, NetworkType::Type nettype, Q
|
|||||||
return started;
|
return started;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DaemonManager::sendCommandAsync(const QStringList &cmd, NetworkType::Type nettype, const QJSValue& callback) const
|
||||||
|
{
|
||||||
|
m_scheduler.run([this, cmd, nettype] {
|
||||||
|
QString message;
|
||||||
|
return QJSValueList({sendCommand(cmd, nettype, message)});
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
|
||||||
void DaemonManager::exit()
|
void DaemonManager::exit()
|
||||||
{
|
{
|
||||||
qDebug("DaemonManager: exit()");
|
qDebug("DaemonManager: exit()");
|
||||||
|
|||||||
@@ -44,19 +44,21 @@ public:
|
|||||||
|
|
||||||
static DaemonManager * instance(const QStringList *args);
|
static DaemonManager * instance(const QStringList *args);
|
||||||
|
|
||||||
Q_INVOKABLE bool start(const QString &flags, NetworkType::Type nettype, const QString &dataDir = "", const QString &bootstrapNodeAddress = "");
|
Q_INVOKABLE bool start(const QString &flags, NetworkType::Type nettype, const QString &dataDir = "", const QString &bootstrapNodeAddress = "", bool noSync = false);
|
||||||
Q_INVOKABLE bool stop(NetworkType::Type nettype);
|
Q_INVOKABLE bool stop(NetworkType::Type nettype);
|
||||||
|
|
||||||
|
Q_INVOKABLE bool noSync() const noexcept;
|
||||||
// return true if daemon process is started
|
// return true if daemon process is started
|
||||||
Q_INVOKABLE bool running(NetworkType::Type nettype) const;
|
Q_INVOKABLE void runningAsync(NetworkType::Type nettype, const QJSValue& callback) const;
|
||||||
// Send daemon command from qml and prints output in console window.
|
// Send daemon command from qml and prints output in console window.
|
||||||
Q_INVOKABLE bool sendCommand(const QString &cmd, NetworkType::Type nettype) const;
|
Q_INVOKABLE void sendCommandAsync(const QStringList &cmd, NetworkType::Type nettype, const QJSValue& callback) const;
|
||||||
Q_INVOKABLE void exit();
|
Q_INVOKABLE void exit();
|
||||||
Q_INVOKABLE QVariantMap validateDataDir(const QString &dataDir) const;
|
Q_INVOKABLE QVariantMap validateDataDir(const QString &dataDir) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool sendCommand(const QString &cmd, NetworkType::Type nettype, QString &message) const;
|
bool running(NetworkType::Type nettype) const;
|
||||||
|
bool sendCommand(const QStringList &cmd, NetworkType::Type nettype, QString &message) const;
|
||||||
bool startWatcher(NetworkType::Type nettype) const;
|
bool startWatcher(NetworkType::Type nettype) const;
|
||||||
bool stopWatcher(NetworkType::Type nettype) const;
|
bool stopWatcher(NetworkType::Type nettype) const;
|
||||||
signals:
|
signals:
|
||||||
@@ -81,8 +83,9 @@ private:
|
|||||||
QString m_monerod;
|
QString m_monerod;
|
||||||
bool m_has_daemon = true;
|
bool m_has_daemon = true;
|
||||||
bool m_app_exit = false;
|
bool m_app_exit = false;
|
||||||
|
bool m_noSync = false;
|
||||||
|
|
||||||
FutureScheduler m_scheduler;
|
mutable FutureScheduler m_scheduler;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DAEMONMANAGER_H
|
#endif // DAEMONMANAGER_H
|
||||||
|
|||||||
@@ -32,10 +32,13 @@
|
|||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QReadLocker>
|
||||||
|
#include <QWriteLocker>
|
||||||
|
|
||||||
|
|
||||||
TransactionInfo *TransactionHistory::transaction(int index)
|
TransactionInfo *TransactionHistory::transaction(int index)
|
||||||
{
|
{
|
||||||
|
QReadLocker locker(&m_tinfoLock);
|
||||||
|
|
||||||
if (index < 0 || index >= m_tinfo.size()) {
|
if (index < 0 || index >= m_tinfo.size()) {
|
||||||
qCritical("%s: no transaction info for index %d", __FUNCTION__, index);
|
qCritical("%s: no transaction info for index %d", __FUNCTION__, index);
|
||||||
@@ -53,41 +56,48 @@ TransactionInfo *TransactionHistory::transaction(int index)
|
|||||||
|
|
||||||
QList<TransactionInfo *> TransactionHistory::getAll(quint32 accountIndex) const
|
QList<TransactionInfo *> TransactionHistory::getAll(quint32 accountIndex) const
|
||||||
{
|
{
|
||||||
// XXX this invalidates previously saved history that might be used by model
|
|
||||||
emit refreshStarted();
|
|
||||||
qDeleteAll(m_tinfo);
|
|
||||||
m_tinfo.clear();
|
|
||||||
|
|
||||||
QDateTime firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block
|
QDateTime firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block
|
||||||
QDateTime lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
|
QDateTime lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
|
||||||
quint64 lastTxHeight = 0;
|
|
||||||
m_locked = false;
|
|
||||||
m_minutesToUnlock = 0;
|
|
||||||
TransactionHistory * parent = const_cast<TransactionHistory*>(this);
|
|
||||||
for (const auto i : m_pimpl->getAll()) {
|
|
||||||
TransactionInfo * ti = new TransactionInfo(i, parent);
|
|
||||||
if (ti->subaddrAccount() != accountIndex) {
|
|
||||||
delete ti;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
m_tinfo.append(ti);
|
|
||||||
// looking for transactions timestamp scope
|
|
||||||
if (ti->timestamp() >= lastDateTime) {
|
|
||||||
lastDateTime = ti->timestamp();
|
|
||||||
}
|
|
||||||
if (ti->timestamp() <= firstDateTime) {
|
|
||||||
firstDateTime = ti->timestamp();
|
|
||||||
}
|
|
||||||
quint64 requiredConfirmations = (ti->blockHeight() < ti->unlockTime()) ? ti->unlockTime() - ti->blockHeight() : 10;
|
|
||||||
// store last tx height
|
|
||||||
if (ti->confirmations() < requiredConfirmations && ti->blockHeight() >= lastTxHeight) {
|
|
||||||
lastTxHeight = ti->blockHeight();
|
|
||||||
// TODO: Fetch block time and confirmations needed from wallet2?
|
|
||||||
m_minutesToUnlock = (requiredConfirmations - ti->confirmations()) * 2;
|
|
||||||
m_locked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
emit refreshStarted();
|
||||||
|
|
||||||
|
{
|
||||||
|
QWriteLocker locker(&m_tinfoLock);
|
||||||
|
|
||||||
|
// XXX this invalidates previously saved history that might be used by model
|
||||||
|
qDeleteAll(m_tinfo);
|
||||||
|
m_tinfo.clear();
|
||||||
|
|
||||||
|
quint64 lastTxHeight = 0;
|
||||||
|
m_locked = false;
|
||||||
|
m_minutesToUnlock = 0;
|
||||||
|
TransactionHistory * parent = const_cast<TransactionHistory*>(this);
|
||||||
|
for (const auto i : m_pimpl->getAll()) {
|
||||||
|
TransactionInfo * ti = new TransactionInfo(i, parent);
|
||||||
|
if (ti->subaddrAccount() != accountIndex) {
|
||||||
|
delete ti;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_tinfo.append(ti);
|
||||||
|
// looking for transactions timestamp scope
|
||||||
|
if (ti->timestamp() >= lastDateTime) {
|
||||||
|
lastDateTime = ti->timestamp();
|
||||||
|
}
|
||||||
|
if (ti->timestamp() <= firstDateTime) {
|
||||||
|
firstDateTime = ti->timestamp();
|
||||||
|
}
|
||||||
|
quint64 requiredConfirmations = (ti->blockHeight() < ti->unlockTime()) ? ti->unlockTime() - ti->blockHeight() : 10;
|
||||||
|
// store last tx height
|
||||||
|
if (ti->confirmations() < requiredConfirmations && ti->blockHeight() >= lastTxHeight) {
|
||||||
|
lastTxHeight = ti->blockHeight();
|
||||||
|
// TODO: Fetch block time and confirmations needed from wallet2?
|
||||||
|
m_minutesToUnlock = (requiredConfirmations - ti->confirmations()) * 2;
|
||||||
|
m_locked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit refreshFinished();
|
emit refreshFinished();
|
||||||
|
|
||||||
if (m_firstDateTime != firstDateTime) {
|
if (m_firstDateTime != firstDateTime) {
|
||||||
@@ -112,6 +122,8 @@ void TransactionHistory::refresh(quint32 accountIndex)
|
|||||||
|
|
||||||
quint64 TransactionHistory::count() const
|
quint64 TransactionHistory::count() const
|
||||||
{
|
{
|
||||||
|
QReadLocker locker(&m_tinfoLock);
|
||||||
|
|
||||||
return m_tinfo.count();
|
return m_tinfo.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QReadWriteLock>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
namespace Monero {
|
namespace Monero {
|
||||||
@@ -76,6 +77,7 @@ private:
|
|||||||
friend class Wallet;
|
friend class Wallet;
|
||||||
Monero::TransactionHistory * m_pimpl;
|
Monero::TransactionHistory * m_pimpl;
|
||||||
mutable QList<TransactionInfo*> m_tinfo;
|
mutable QList<TransactionInfo*> m_tinfo;
|
||||||
|
mutable QReadWriteLock m_tinfoLock;
|
||||||
mutable QDateTime m_firstDateTime;
|
mutable QDateTime m_firstDateTime;
|
||||||
mutable QDateTime m_lastDateTime;
|
mutable QDateTime m_lastDateTime;
|
||||||
mutable int m_minutesToUnlock;
|
mutable int m_minutesToUnlock;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ QString UnsignedTransaction::errorString() const
|
|||||||
return QString::fromStdString(m_pimpl->errorString());
|
return QString::fromStdString(m_pimpl->errorString());
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 UnsignedTransaction::amount(int index) const
|
quint64 UnsignedTransaction::amount(size_t index) const
|
||||||
{
|
{
|
||||||
std::vector<uint64_t> arr = m_pimpl->amount();
|
std::vector<uint64_t> arr = m_pimpl->amount();
|
||||||
if(index > arr.size() - 1)
|
if(index > arr.size() - 1)
|
||||||
@@ -48,7 +48,7 @@ quint64 UnsignedTransaction::amount(int index) const
|
|||||||
return arr[index];
|
return arr[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 UnsignedTransaction::fee(int index) const
|
quint64 UnsignedTransaction::fee(size_t index) const
|
||||||
{
|
{
|
||||||
std::vector<uint64_t> arr = m_pimpl->fee();
|
std::vector<uint64_t> arr = m_pimpl->fee();
|
||||||
if(index > arr.size() - 1)
|
if(index > arr.size() - 1)
|
||||||
@@ -56,7 +56,7 @@ quint64 UnsignedTransaction::fee(int index) const
|
|||||||
return arr[index];
|
return arr[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 UnsignedTransaction::mixin(int index) const
|
quint64 UnsignedTransaction::mixin(size_t index) const
|
||||||
{
|
{
|
||||||
std::vector<uint64_t> arr = m_pimpl->mixin();
|
std::vector<uint64_t> arr = m_pimpl->mixin();
|
||||||
if(index > arr.size() - 1)
|
if(index > arr.size() - 1)
|
||||||
|
|||||||
@@ -56,9 +56,9 @@ public:
|
|||||||
|
|
||||||
Status status() const;
|
Status status() const;
|
||||||
QString errorString() const;
|
QString errorString() const;
|
||||||
Q_INVOKABLE quint64 amount(int index) const;
|
Q_INVOKABLE quint64 amount(size_t index) const;
|
||||||
Q_INVOKABLE quint64 fee(int index) const;
|
Q_INVOKABLE quint64 fee(size_t index) const;
|
||||||
Q_INVOKABLE quint64 mixin(int index) const;
|
Q_INVOKABLE quint64 mixin(size_t index) const;
|
||||||
QStringList recipientAddress() const;
|
QStringList recipientAddress() const;
|
||||||
QStringList paymentId() const;
|
QStringList paymentId() const;
|
||||||
quint64 txCount() const;
|
quint64 txCount() const;
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ namespace {
|
|||||||
static const int DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS = 5;
|
static const int DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS = 5;
|
||||||
static const int DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS = 30;
|
static const int DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS = 30;
|
||||||
static const int WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS = 5;
|
static const int WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS = 5;
|
||||||
|
|
||||||
|
static constexpr char ATTRIBUTE_SUBADDRESS_ACCOUNT[] ="gui.subaddress_account";
|
||||||
}
|
}
|
||||||
|
|
||||||
class WalletListenerImpl : public Monero::WalletListener
|
class WalletListenerImpl : public Monero::WalletListener
|
||||||
@@ -206,7 +208,7 @@ bool Wallet::store(const QString &path)
|
|||||||
return m_walletImpl->store(path.toStdString());
|
return m_walletImpl->store(path.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Wallet::init(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering, bool isRecoveringFromDevice, quint64 restoreHeight)
|
bool Wallet::init(const QString &daemonAddress, bool trustedDaemon, quint64 upperTransactionLimit, bool isRecovering, bool isRecoveringFromDevice, quint64 restoreHeight)
|
||||||
{
|
{
|
||||||
qDebug() << "init non async";
|
qDebug() << "init non async";
|
||||||
if (isRecovering){
|
if (isRecovering){
|
||||||
@@ -221,6 +223,7 @@ bool Wallet::init(const QString &daemonAddress, quint64 upperTransactionLimit, b
|
|||||||
m_walletImpl->setRefreshFromBlockHeight(restoreHeight);
|
m_walletImpl->setRefreshFromBlockHeight(restoreHeight);
|
||||||
}
|
}
|
||||||
m_walletImpl->init(daemonAddress.toStdString(), upperTransactionLimit, m_daemonUsername.toStdString(), m_daemonPassword.toStdString());
|
m_walletImpl->init(daemonAddress.toStdString(), upperTransactionLimit, m_daemonUsername.toStdString(), m_daemonPassword.toStdString());
|
||||||
|
setTrustedDaemon(trustedDaemon);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +234,7 @@ void Wallet::setDaemonLogin(const QString &daemonUsername, const QString &daemon
|
|||||||
m_daemonPassword = daemonPassword;
|
m_daemonPassword = daemonPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wallet::initAsync(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering, bool isRecoveringFromDevice, quint64 restoreHeight)
|
void Wallet::initAsync(const QString &daemonAddress, bool trustedDaemon, quint64 upperTransactionLimit, bool isRecovering, bool isRecoveringFromDevice, quint64 restoreHeight)
|
||||||
{
|
{
|
||||||
qDebug() << "initAsync: " + daemonAddress;
|
qDebug() << "initAsync: " + daemonAddress;
|
||||||
// Change status to disconnected if connected
|
// Change status to disconnected if connected
|
||||||
@@ -240,19 +243,28 @@ void Wallet::initAsync(const QString &daemonAddress, quint64 upperTransactionLim
|
|||||||
emit connectionStatusChanged(m_connectionStatus);
|
emit connectionStatusChanged(m_connectionStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_scheduler.run([this, daemonAddress, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight] {
|
m_scheduler.run([this, daemonAddress, trustedDaemon, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight] {
|
||||||
bool success = init(daemonAddress, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight);
|
bool success = init(daemonAddress, trustedDaemon, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
emit walletCreationHeightChanged();
|
emit walletCreationHeightChanged();
|
||||||
qDebug() << "init async finished - starting refresh";
|
qDebug() << "init async finished - starting refresh";
|
||||||
connected(true);
|
connected(true);
|
||||||
m_walletImpl->startRefresh();
|
m_walletImpl->startRefresh();
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Wallet::isHwBacked() const
|
||||||
|
{
|
||||||
|
return m_walletImpl->getDeviceType() != Monero::Wallet::Device_Software;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Wallet::isLedger() const
|
||||||
|
{
|
||||||
|
return m_walletImpl->getDeviceType() == Monero::Wallet::Device_Ledger;
|
||||||
|
}
|
||||||
|
|
||||||
//! create a view only wallet
|
//! create a view only wallet
|
||||||
bool Wallet::createViewOnly(const QString &path, const QString &password) const
|
bool Wallet::createViewOnly(const QString &path, const QString &password) const
|
||||||
{
|
{
|
||||||
@@ -306,8 +318,13 @@ void Wallet::switchSubaddressAccount(quint32 accountIndex)
|
|||||||
if (accountIndex < numSubaddressAccounts())
|
if (accountIndex < numSubaddressAccounts())
|
||||||
{
|
{
|
||||||
m_currentSubaddressAccount = accountIndex;
|
m_currentSubaddressAccount = accountIndex;
|
||||||
|
if (!setCacheAttribute(ATTRIBUTE_SUBADDRESS_ACCOUNT, QString::number(m_currentSubaddressAccount)))
|
||||||
|
{
|
||||||
|
qWarning() << "failed to set " << ATTRIBUTE_SUBADDRESS_ACCOUNT << " cache attribute";
|
||||||
|
}
|
||||||
m_subaddress->refresh(m_currentSubaddressAccount);
|
m_subaddress->refresh(m_currentSubaddressAccount);
|
||||||
m_history->refresh(m_currentSubaddressAccount);
|
m_history->refresh(m_currentSubaddressAccount);
|
||||||
|
emit currentSubaddressAccountChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Wallet::addSubaddressAccount(const QString& label)
|
void Wallet::addSubaddressAccount(const QString& label)
|
||||||
@@ -335,6 +352,13 @@ void Wallet::setSubaddressLabel(quint32 accountIndex, quint32 addressIndex, cons
|
|||||||
{
|
{
|
||||||
m_walletImpl->setSubaddressLabel(accountIndex, addressIndex, label.toStdString());
|
m_walletImpl->setSubaddressLabel(accountIndex, addressIndex, label.toStdString());
|
||||||
}
|
}
|
||||||
|
void Wallet::deviceShowAddressAsync(quint32 accountIndex, quint32 addressIndex, const QString &paymentId)
|
||||||
|
{
|
||||||
|
m_scheduler.run([this, accountIndex, addressIndex, paymentId] {
|
||||||
|
m_walletImpl->deviceShowAddress(accountIndex, addressIndex, paymentId.toStdString());
|
||||||
|
emit deviceShowAddressShowed();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void Wallet::refreshHeightAsync()
|
void Wallet::refreshHeightAsync()
|
||||||
{
|
{
|
||||||
@@ -623,6 +647,15 @@ void Wallet::setPaymentId(const QString &paymentId)
|
|||||||
m_paymentId = paymentId;
|
m_paymentId = paymentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Wallet::getCacheAttribute(const QString &key) const {
|
||||||
|
return QString::fromStdString(m_walletImpl->getCacheAttribute(key.toStdString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Wallet::setCacheAttribute(const QString &key, const QString &val)
|
||||||
|
{
|
||||||
|
return m_walletImpl->setCacheAttribute(key.toStdString(), val.toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
bool Wallet::setUserNote(const QString &txid, const QString ¬e)
|
bool Wallet::setUserNote(const QString &txid, const QString ¬e)
|
||||||
{
|
{
|
||||||
return m_walletImpl->setUserNote(txid.toStdString(), note.toStdString());
|
return m_walletImpl->setUserNote(txid.toStdString(), note.toStdString());
|
||||||
@@ -937,16 +970,16 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
|
|||||||
, m_historyModel(nullptr)
|
, m_historyModel(nullptr)
|
||||||
, m_addressBook(nullptr)
|
, m_addressBook(nullptr)
|
||||||
, m_addressBookModel(nullptr)
|
, m_addressBookModel(nullptr)
|
||||||
, m_subaddress(nullptr)
|
|
||||||
, m_subaddressModel(nullptr)
|
|
||||||
, m_subaddressAccount(nullptr)
|
|
||||||
, m_subaddressAccountModel(nullptr)
|
|
||||||
, m_daemonBlockChainHeight(0)
|
, m_daemonBlockChainHeight(0)
|
||||||
, m_daemonBlockChainHeightTtl(DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS)
|
, m_daemonBlockChainHeightTtl(DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS)
|
||||||
, m_daemonBlockChainTargetHeight(0)
|
, m_daemonBlockChainTargetHeight(0)
|
||||||
, m_daemonBlockChainTargetHeightTtl(DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS)
|
, m_daemonBlockChainTargetHeightTtl(DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS)
|
||||||
, m_connectionStatusTtl(WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS)
|
, m_connectionStatusTtl(WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS)
|
||||||
, m_currentSubaddressAccount(0)
|
, m_currentSubaddressAccount(0)
|
||||||
|
, m_subaddress(nullptr)
|
||||||
|
, m_subaddressModel(nullptr)
|
||||||
|
, m_subaddressAccount(nullptr)
|
||||||
|
, m_subaddressAccountModel(nullptr)
|
||||||
, m_scheduler(this)
|
, m_scheduler(this)
|
||||||
{
|
{
|
||||||
m_history = new TransactionHistory(m_walletImpl->history(), this);
|
m_history = new TransactionHistory(m_walletImpl->history(), this);
|
||||||
@@ -956,6 +989,7 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
|
|||||||
m_walletListener = new WalletListenerImpl(this);
|
m_walletListener = new WalletListenerImpl(this);
|
||||||
m_walletImpl->setListener(m_walletListener);
|
m_walletImpl->setListener(m_walletListener);
|
||||||
m_connectionStatus = Wallet::ConnectionStatus_Disconnected;
|
m_connectionStatus = Wallet::ConnectionStatus_Disconnected;
|
||||||
|
m_currentSubaddressAccount = getCacheAttribute(ATTRIBUTE_SUBADDRESS_ACCOUNT).toUInt();
|
||||||
// start cache timers
|
// start cache timers
|
||||||
m_connectionStatusTime.restart();
|
m_connectionStatusTime.restart();
|
||||||
m_daemonBlockChainHeightTime.restart();
|
m_daemonBlockChainHeightTime.restart();
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class Wallet : public QObject
|
|||||||
Q_PROPERTY(Status status READ status)
|
Q_PROPERTY(Status status READ status)
|
||||||
Q_PROPERTY(NetworkType::Type nettype READ nettype)
|
Q_PROPERTY(NetworkType::Type nettype READ nettype)
|
||||||
// Q_PROPERTY(ConnectionStatus connected READ connected)
|
// Q_PROPERTY(ConnectionStatus connected READ connected)
|
||||||
Q_PROPERTY(quint32 currentSubaddressAccount READ currentSubaddressAccount)
|
Q_PROPERTY(quint32 currentSubaddressAccount READ currentSubaddressAccount NOTIFY currentSubaddressAccountChanged)
|
||||||
Q_PROPERTY(bool synchronized READ synchronized)
|
Q_PROPERTY(bool synchronized READ synchronized)
|
||||||
Q_PROPERTY(QString errorString READ errorString)
|
Q_PROPERTY(QString errorString READ errorString)
|
||||||
Q_PROPERTY(TransactionHistory * history READ history)
|
Q_PROPERTY(TransactionHistory * history READ history)
|
||||||
@@ -144,11 +144,8 @@ public:
|
|||||||
//! empty path stores in current location
|
//! empty path stores in current location
|
||||||
Q_INVOKABLE bool store(const QString &path = "");
|
Q_INVOKABLE bool store(const QString &path = "");
|
||||||
|
|
||||||
//! initializes wallet
|
|
||||||
Q_INVOKABLE bool init(const QString &daemonAddress, quint64 upperTransactionLimit = 0, bool isRecovering = false, bool isRecoveringFromDevice = false, quint64 restoreHeight = 0);
|
|
||||||
|
|
||||||
//! initializes wallet asynchronously
|
//! initializes wallet asynchronously
|
||||||
Q_INVOKABLE void initAsync(const QString &daemonAddress, quint64 upperTransactionLimit = 0, bool isRecovering = false, bool isRecoveringFromDevice = false, quint64 restoreHeight = 0);
|
Q_INVOKABLE void initAsync(const QString &daemonAddress, bool trustedDaemon = false, quint64 upperTransactionLimit = 0, bool isRecovering = false, bool isRecoveringFromDevice = false, quint64 restoreHeight = 0);
|
||||||
|
|
||||||
// Set daemon rpc user/pass
|
// Set daemon rpc user/pass
|
||||||
Q_INVOKABLE void setDaemonLogin(const QString &daemonUsername = "", const QString &daemonPassword = "");
|
Q_INVOKABLE void setDaemonLogin(const QString &daemonUsername = "", const QString &daemonPassword = "");
|
||||||
@@ -179,6 +176,11 @@ public:
|
|||||||
Q_INVOKABLE void addSubaddress(const QString& label);
|
Q_INVOKABLE void addSubaddress(const QString& label);
|
||||||
Q_INVOKABLE QString getSubaddressLabel(quint32 accountIndex, quint32 addressIndex) const;
|
Q_INVOKABLE QString getSubaddressLabel(quint32 accountIndex, quint32 addressIndex) const;
|
||||||
Q_INVOKABLE void setSubaddressLabel(quint32 accountIndex, quint32 addressIndex, const QString &label);
|
Q_INVOKABLE void setSubaddressLabel(quint32 accountIndex, quint32 addressIndex, const QString &label);
|
||||||
|
Q_INVOKABLE void deviceShowAddressAsync(quint32 accountIndex, quint32 addressIndex, const QString &paymentId);
|
||||||
|
|
||||||
|
//! hw-device backed wallets
|
||||||
|
Q_INVOKABLE bool isHwBacked() const;
|
||||||
|
Q_INVOKABLE bool isLedger() const;
|
||||||
|
|
||||||
//! returns if view only wallet
|
//! returns if view only wallet
|
||||||
Q_INVOKABLE bool viewOnly() const;
|
Q_INVOKABLE bool viewOnly() const;
|
||||||
@@ -288,6 +290,10 @@ public:
|
|||||||
|
|
||||||
void setPaymentId(const QString &paymentId);
|
void setPaymentId(const QString &paymentId);
|
||||||
|
|
||||||
|
//! Namespace your cacheAttribute keys to avoid collisions
|
||||||
|
Q_INVOKABLE bool setCacheAttribute(const QString &key, const QString &val);
|
||||||
|
Q_INVOKABLE QString getCacheAttribute(const QString &key) const;
|
||||||
|
|
||||||
Q_INVOKABLE bool setUserNote(const QString &txid, const QString ¬e);
|
Q_INVOKABLE bool setUserNote(const QString &txid, const QString ¬e);
|
||||||
Q_INVOKABLE QString getUserNote(const QString &txid) const;
|
Q_INVOKABLE QString getUserNote(const QString &txid) const;
|
||||||
Q_INVOKABLE QString getTxKey(const QString &txid) const;
|
Q_INVOKABLE QString getTxKey(const QString &txid) const;
|
||||||
@@ -353,11 +359,13 @@ signals:
|
|||||||
void deviceButtonPressed();
|
void deviceButtonPressed();
|
||||||
void transactionCommitted(bool status, PendingTransaction *t, const QStringList& txid);
|
void transactionCommitted(bool status, PendingTransaction *t, const QStringList& txid);
|
||||||
void heightRefreshed(quint64 walletHeight, quint64 daemonHeight, quint64 targetHeight) const;
|
void heightRefreshed(quint64 walletHeight, quint64 daemonHeight, quint64 targetHeight) const;
|
||||||
|
void deviceShowAddressShowed();
|
||||||
|
|
||||||
// emitted when transaction is created async
|
// emitted when transaction is created async
|
||||||
void transactionCreated(PendingTransaction * transaction, QString address, QString paymentId, quint32 mixinCount);
|
void transactionCreated(PendingTransaction * transaction, QString address, QString paymentId, quint32 mixinCount);
|
||||||
|
|
||||||
void connectionStatusChanged(int status) const;
|
void connectionStatusChanged(int status) const;
|
||||||
|
void currentSubaddressAccountChanged() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Wallet(QObject * parent = nullptr);
|
Wallet(QObject * parent = nullptr);
|
||||||
@@ -374,6 +382,9 @@ private:
|
|||||||
//! returns daemon's blockchain target height
|
//! returns daemon's blockchain target height
|
||||||
quint64 daemonBlockChainTargetHeight() const;
|
quint64 daemonBlockChainTargetHeight() const;
|
||||||
|
|
||||||
|
//! initializes wallet
|
||||||
|
bool init(const QString &daemonAddress, bool trustedDaemon, quint64 upperTransactionLimit, bool isRecovering, bool isRecoveringFromDevice, quint64 restoreHeight);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class WalletManager;
|
friend class WalletManager;
|
||||||
friend class WalletListenerImpl;
|
friend class WalletListenerImpl;
|
||||||
@@ -385,6 +396,8 @@ private:
|
|||||||
mutable TransactionHistoryModel * m_historyModel;
|
mutable TransactionHistoryModel * m_historyModel;
|
||||||
mutable TransactionHistorySortFilterModel * m_historySortFilterModel;
|
mutable TransactionHistorySortFilterModel * m_historySortFilterModel;
|
||||||
QString m_paymentId;
|
QString m_paymentId;
|
||||||
|
AddressBook * m_addressBook;
|
||||||
|
mutable AddressBookModel * m_addressBookModel;
|
||||||
mutable QTime m_daemonBlockChainHeightTime;
|
mutable QTime m_daemonBlockChainHeightTime;
|
||||||
mutable quint64 m_daemonBlockChainHeight;
|
mutable quint64 m_daemonBlockChainHeight;
|
||||||
int m_daemonBlockChainHeightTtl;
|
int m_daemonBlockChainHeightTtl;
|
||||||
@@ -396,8 +409,6 @@ private:
|
|||||||
mutable QTime m_connectionStatusTime;
|
mutable QTime m_connectionStatusTime;
|
||||||
mutable bool m_initialized;
|
mutable bool m_initialized;
|
||||||
uint32_t m_currentSubaddressAccount;
|
uint32_t m_currentSubaddressAccount;
|
||||||
AddressBook * m_addressBook;
|
|
||||||
mutable AddressBookModel * m_addressBookModel;
|
|
||||||
Subaddress * m_subaddress;
|
Subaddress * m_subaddress;
|
||||||
mutable SubaddressModel * m_subaddressModel;
|
mutable SubaddressModel * m_subaddressModel;
|
||||||
SubaddressAccount * m_subaddressAccount;
|
SubaddressAccount * m_subaddressAccount;
|
||||||
|
|||||||
@@ -376,7 +376,7 @@ bool WalletManager::localDaemonSynced() const
|
|||||||
|
|
||||||
bool WalletManager::isDaemonLocal(const QString &daemon_address) const
|
bool WalletManager::isDaemonLocal(const QString &daemon_address) const
|
||||||
{
|
{
|
||||||
return Monero::Utils::isAddressLocal(daemon_address.toStdString());
|
return daemon_address.isEmpty() ? false : Monero::Utils::isAddressLocal(daemon_address.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WalletManager::resolveOpenAlias(const QString &address) const
|
QString WalletManager::resolveOpenAlias(const QString &address) const
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ void AddressBookModel::endReset(){
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
int AddressBookModel::rowCount(const QModelIndex &parent) const
|
int AddressBookModel::rowCount(const QModelIndex &) const
|
||||||
{
|
{
|
||||||
return m_addressBook->count();
|
return m_addressBook->count();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ void SubaddressAccountModel::endReset(){
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SubaddressAccountModel::rowCount(const QModelIndex &parent) const
|
int SubaddressAccountModel::rowCount(const QModelIndex &) const
|
||||||
{
|
{
|
||||||
return m_subaddressAccount->count();
|
return m_subaddressAccount->count();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ void SubaddressModel::endReset(){
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SubaddressModel::rowCount(const QModelIndex &parent) const
|
int SubaddressModel::rowCount(const QModelIndex &) const
|
||||||
{
|
{
|
||||||
return m_subaddress->count();
|
return m_subaddress->count();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ QPair<bool, QFuture<void>> FutureScheduler::run(std::function<void()> function)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<bool, QFuture<QJSValueList>> FutureScheduler::run(std::function<QJSValueList() noexcept> function, const QJSValue &callback) noexcept
|
QPair<bool, QFuture<QJSValueList>> FutureScheduler::run(std::function<QJSValueList() noexcept> function, const QJSValue &callback)
|
||||||
{
|
{
|
||||||
if (!callback.isCallable())
|
if (!callback.isCallable())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public:
|
|||||||
void shutdownWaitForFinished() noexcept;
|
void shutdownWaitForFinished() noexcept;
|
||||||
|
|
||||||
QPair<bool, QFuture<void>> run(std::function<void()> function) noexcept;
|
QPair<bool, QFuture<void>> run(std::function<void()> function) noexcept;
|
||||||
QPair<bool, QFuture<QJSValueList>> run(std::function<QJSValueList() noexcept> function, const QJSValue &callback) noexcept;
|
QPair<bool, QFuture<QJSValueList>> run(std::function<QJSValueList() noexcept> function, const QJSValue &callback);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool add() noexcept;
|
bool add() noexcept;
|
||||||
|
|||||||
@@ -36,9 +36,9 @@
|
|||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include "src/libwalletqt/WalletManager.h"
|
#include "libwalletqt/WalletManager.h"
|
||||||
#include "src/NetworkType.h"
|
#include "NetworkType.h"
|
||||||
#include "src/qt/utils.h"
|
#include "qt/utils.h"
|
||||||
|
|
||||||
#include "KeysFiles.h"
|
#include "KeysFiles.h"
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
#define KEYSFILES_H
|
#define KEYSFILES_H
|
||||||
|
|
||||||
#include <qqmlcontext.h>
|
#include <qqmlcontext.h>
|
||||||
#include "src/libwalletqt/WalletManager.h"
|
#include "libwalletqt/WalletManager.h"
|
||||||
#include "src/NetworkType.h"
|
#include "NetworkType.h"
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
|
|
||||||
class WalletKeysFiles
|
class WalletKeysFiles
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QMetaProperty>
|
#include <QMetaProperty>
|
||||||
|
|
||||||
#include "src/qt/MoneroSettings.h"
|
#include "qt/MoneroSettings.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmlmodule moneroSettings 1.0
|
\qmlmodule moneroSettings 1.0
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
||||||
#include "src/qt/TailsOS.h"
|
#include "TailsOS.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
bool fileExists(QString path) {
|
bool fileExists(QString path) {
|
||||||
@@ -67,6 +67,7 @@ QString getAccountName(){
|
|||||||
return accountName;
|
return accountName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
QString xdgMime(QApplication &app){
|
QString xdgMime(QApplication &app){
|
||||||
return QString(
|
return QString(
|
||||||
"[Desktop Entry]\n"
|
"[Desktop Entry]\n"
|
||||||
@@ -88,7 +89,6 @@ QString xdgMime(QApplication &app){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void registerXdgMime(QApplication &app){
|
void registerXdgMime(QApplication &app){
|
||||||
#ifdef Q_OS_LINUX
|
|
||||||
// Register desktop entry
|
// Register desktop entry
|
||||||
// - MacOS handled via Info.plist
|
// - MacOS handled via Info.plist
|
||||||
// - Windows handled in the installer by rbrunner7
|
// - Windows handled in the installer by rbrunner7
|
||||||
@@ -111,8 +111,8 @@ void registerXdgMime(QApplication &app){
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
fileWrite(filePath, mime);
|
fileWrite(filePath, mime);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QString randomUserAgent(){
|
QString randomUserAgent(){
|
||||||
QStringList urand;
|
QStringList urand;
|
||||||
|
|||||||