Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
300a5afc21 | ||
|
|
758dd1df96 | ||
|
|
d83b400931 | ||
|
|
a77a5909cf | ||
|
|
bf785bb388 |
34
.github/workflows/build.yml
vendored
@@ -1,34 +0,0 @@
|
|||||||
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
|
|
||||||
337
LeftPanel.qml
@@ -40,17 +40,17 @@ import "components/effects/" as MoneroEffects
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
id: panel
|
id: panel
|
||||||
|
|
||||||
property int currentAccountIndex
|
property alias unlockedBalanceText: unlockedBalanceText.text
|
||||||
property alias currentAccountLabel: accountLabel.text
|
property alias unlockedBalanceVisible: unlockedBalanceText.visible
|
||||||
property string balanceString: "?.??"
|
property alias unlockedBalanceLabelVisible: unlockedBalanceLabel.visible
|
||||||
property string balanceUnlockedString: "?.??"
|
property alias balanceLabelText: balanceLabel.text
|
||||||
property string balanceFiatString: "?.??"
|
property alias balanceText: balanceText.text
|
||||||
property string minutesToUnlock: ""
|
property alias balanceTextFiat: balanceTextFiat.text
|
||||||
property bool isSyncing: false
|
property alias unlockedBalanceTextFiat: unlockedBalanceTextFiat.text
|
||||||
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: 300
|
width: (isMobile)? appWindow.width : 300
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
@@ -108,18 +108,19 @@ Rectangle {
|
|||||||
visible: true
|
visible: true
|
||||||
z: 2
|
z: 2
|
||||||
id: column1
|
id: column1
|
||||||
height: 175
|
height: 210
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: (persistentSettings.customDecorations)? 50 : 0
|
anchors.topMargin: (persistentSettings.customDecorations)? 50 : 0
|
||||||
|
|
||||||
Item {
|
RowLayout {
|
||||||
Item {
|
Item {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
anchors.leftMargin: 20
|
anchors.leftMargin: 20
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
height: 490
|
height: 490
|
||||||
width: 260
|
width: 260
|
||||||
|
|
||||||
@@ -127,9 +128,9 @@ Rectangle {
|
|||||||
id: card
|
id: card
|
||||||
visible: !isOpenGL || MoneroComponents.Style.blackTheme
|
visible: !isOpenGL || MoneroComponents.Style.blackTheme
|
||||||
width: 260
|
width: 260
|
||||||
height: 135
|
height: 170
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
source: MoneroComponents.Style.blackTheme ? "qrc:///images/card-background-black.png" : "qrc:///images/card-background-white.png"
|
source: "qrc:///images/card-background.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
DropShadow {
|
DropShadow {
|
||||||
@@ -171,6 +172,57 @@ 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 {
|
||||||
@@ -178,154 +230,181 @@ Rectangle {
|
|||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
anchors.leftMargin: 20
|
anchors.leftMargin: 20
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
height: 490
|
height: 490
|
||||||
width: 50
|
width: 50
|
||||||
|
|
||||||
MoneroComponents.Label {
|
|
||||||
fontSize: 12
|
|
||||||
id: accountIndex
|
|
||||||
text: qsTr("Account") + translationManager.emptyString + " #" + currentAccountIndex
|
|
||||||
color: MoneroComponents.Style.blackTheme ? "white" : "black"
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 60
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 23
|
|
||||||
themeTransition: false
|
|
||||||
|
|
||||||
MouseArea{
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: appWindow.showPageRequest("Account")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.Label {
|
|
||||||
fontSize: 16
|
|
||||||
id: accountLabel
|
|
||||||
textWidth: 170
|
|
||||||
color: MoneroComponents.Style.blackTheme ? "white" : "black"
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 60
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 36
|
|
||||||
themeTransition: false
|
|
||||||
elide: Text.ElideRight
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
MoneroComponents.TextPlain {
|
||||||
id: currencyLabel
|
visible: !(persistentSettings.fiatPriceToggle && persistentSettings.fiatPriceEnabled)
|
||||||
font.pixelSize: 16
|
id: balanceText
|
||||||
text: {
|
themeTransition: false
|
||||||
if (persistentSettings.fiatPriceEnabled && persistentSettings.fiatPriceToggle) {
|
|
||||||
return appWindow.fiatApiCurrencySymbol();
|
|
||||||
} else {
|
|
||||||
return "XMR"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
color: MoneroComponents.Style.blackTheme ? "white" : "black"
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 20
|
anchors.leftMargin: 20
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 100
|
anchors.topMargin: 76
|
||||||
themeTransition: false
|
font.family: "Arial"
|
||||||
|
color: "#FFFFFF"
|
||||||
MouseArea {
|
text: "N/A"
|
||||||
hoverEnabled: true
|
// dynamically adjust text size
|
||||||
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: {
|
font.pixelSize: {
|
||||||
var defaultSize = 29;
|
if (persistentSettings.hideBalance) {
|
||||||
var digits = (balancePart1.text.length - 1)
|
return 20;
|
||||||
if (digits > 2 && !(persistentSettings.fiatPriceEnabled && persistentSettings.fiatPriceToggle)) {
|
|
||||||
return defaultSize - 1.1 * digits
|
|
||||||
} else {
|
|
||||||
return defaultSize
|
|
||||||
}
|
}
|
||||||
|
var digits = text.split('.')[0].length
|
||||||
|
var defaultSize = 22;
|
||||||
|
if(digits > 2) {
|
||||||
|
return defaultSize - 1.1*digits
|
||||||
}
|
}
|
||||||
|
return defaultSize;
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: balancePart1MouseArea
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onEntered: {
|
onEntered: {
|
||||||
balancePart1.color = MoneroComponents.Style.orange
|
parent.color = MoneroComponents.Style.orange
|
||||||
balancePart2.color = MoneroComponents.Style.orange
|
|
||||||
}
|
}
|
||||||
onExited: {
|
onExited: {
|
||||||
balancePart1.color = Qt.binding(function() { return MoneroComponents.Style.blackTheme ? "white" : "black" })
|
parent.color = MoneroComponents.Style.white
|
||||||
balancePart2.color = Qt.binding(function() { return MoneroComponents.Style.blackTheme ? "white" : "black" })
|
|
||||||
}
|
}
|
||||||
onClicked: {
|
onClicked: {
|
||||||
console.log("Copied to clipboard");
|
console.log("Copied to clipboard");
|
||||||
clipboard.setText(balancePart1.text + balancePart2.text);
|
clipboard.setText(parent.text);
|
||||||
appWindow.showStatusMessage(qsTr("Copied to clipboard"),3)
|
appWindow.showStatusMessage(qsTr("Copied to clipboard"),3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.TextPlain {
|
MoneroComponents.TextPlain {
|
||||||
id: balancePart2
|
visible: !balanceText.visible
|
||||||
|
id: balanceTextFiat
|
||||||
themeTransition: false
|
themeTransition: false
|
||||||
anchors.left: balancePart1.right
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: 2
|
anchors.leftMargin: 20
|
||||||
anchors.baseline: currencyLabel.baseline
|
anchors.top: parent.top
|
||||||
color: MoneroComponents.Style.blackTheme ? "white" : "black"
|
anchors.topMargin: 76
|
||||||
text: {
|
font.family: "Arial"
|
||||||
if (persistentSettings.fiatPriceEnabled && persistentSettings.fiatPriceToggle) {
|
color: "#FFFFFF"
|
||||||
return balanceFiatString.split('.')[1]
|
text: "N/A"
|
||||||
} else {
|
font.pixelSize: balanceText.font.pixelSize
|
||||||
return balanceString.split('.')[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
font.pixelSize: 16
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onEntered: balancePart1MouseArea.entered()
|
onEntered: {
|
||||||
onExited: balancePart1MouseArea.exited()
|
parent.color = MoneroComponents.Style.orange
|
||||||
onClicked: balancePart1MouseArea.clicked(mouse)
|
}
|
||||||
|
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: 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
|
||||||
|
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
|
||||||
|
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.Label {
|
||||||
|
id: unlockedBalanceLabel
|
||||||
|
visible: true
|
||||||
|
text: qsTr("Unlocked balance") + translationManager.emptyString
|
||||||
|
color: "white"
|
||||||
|
fontSize: 14
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 20
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 110
|
||||||
|
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
|
||||||
|
textWidth: 238
|
||||||
|
themeTransition: false
|
||||||
|
}
|
||||||
Item { //separator
|
Item { //separator
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -341,7 +420,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: column1.bottom
|
anchors.top: (isMobile)? parent.top : column1.bottom
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
|
|||||||
@@ -46,6 +46,11 @@ 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
|
||||||
@@ -168,6 +173,23 @@ 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: {
|
||||||
@@ -178,7 +200,6 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
anchors.topMargin: appWindow.persistentSettings.customDecorations ? 50 : 0
|
anchors.topMargin: appWindow.persistentSettings.customDecorations ? 50 : 0
|
||||||
anchors.bottomMargin: 0
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
@@ -188,13 +209,13 @@ Rectangle {
|
|||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
ScrollBar.vertical: ScrollBar {
|
ScrollBar.vertical: ScrollBar {
|
||||||
parent: root
|
parent: mainFlickable.parent
|
||||||
anchors.left: parent.right
|
anchors.left: parent.right
|
||||||
anchors.leftMargin: -14 // 10 margin + 4 scrollbar width
|
anchors.leftMargin: 3
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: persistentSettings.customDecorations ? 60 : 10
|
anchors.topMargin: 4
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: persistentSettings.customDecorations ? 15 : 10
|
anchors.bottomMargin: persistentSettings.customDecorations ? 4 : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
onFlickingChanged: {
|
onFlickingChanged: {
|
||||||
@@ -237,7 +258,7 @@ Rectangle {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
id: borderLeft
|
id: borderLeft
|
||||||
visible: middlePanel.state !== "Merchant"
|
visible: middlePanel.state !== "Merchant"
|
||||||
anchors.top: parent.top
|
anchors.top: styledRow.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
width: 1
|
width: 1
|
||||||
|
|||||||
15
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 (Weblate): [translate.getmonero.org](https://translate.getmonero.org)
|
- Translation platform (Pootle): [translate.getmonero.org](https://translate.getmonero.org)
|
||||||
|
|
||||||
## Vulnerability response
|
## Vulnerability response
|
||||||
|
|
||||||
@@ -75,8 +75,6 @@ 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)
|
||||||
@@ -85,7 +83,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 libnorm-dev libusb-1.0-0-dev libpgm-dev`
|
`sudo apt install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev`
|
||||||
|
|
||||||
- For Gentoo
|
- For Gentoo
|
||||||
|
|
||||||
@@ -93,11 +91,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 zeromq-devel`
|
`sudo dnf install make automake cmake gcc-c++ boost-devel miniupnpc-devel graphviz doxygen unbound-devel libunwind-devel pkgconfig openssl-devel libcurl-devel hidapi-devel libusb-devel`
|
||||||
|
|
||||||
2. Install Qt:
|
2. Install Qt:
|
||||||
|
|
||||||
*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.
|
*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.
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
@@ -167,8 +165,9 @@ The executable can be found in the build/release/bin folder.
|
|||||||
|
|
||||||
5. Add the Qt bin directory to your path
|
5. Add the Qt bin directory to your path
|
||||||
|
|
||||||
- Example for Qt: `export PATH=$PATH:$HOME/Qt/5.9.7/clang_64/bin`
|
Example: `export PATH=$PATH:$HOME/Qt/5.9.7/clang_64/bin`
|
||||||
- Example for Homebrew: `export PATH=$PATH:/usr/local/opt/qt/bin`
|
|
||||||
|
This is the directory where Qt 5.x is installed on **your** system
|
||||||
|
|
||||||
6. Grab an up-to-date copy of the monero-gui repository
|
6. Grab an up-to-date copy of the monero-gui repository
|
||||||
|
|
||||||
|
|||||||
@@ -38,10 +38,8 @@ 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
|
||||||
@@ -53,16 +51,14 @@ Item {
|
|||||||
width: checkBoxLayout.width
|
width: checkBoxLayout.width
|
||||||
|
|
||||||
function toggle(){
|
function toggle(){
|
||||||
if (checkBox.toggleOnClick) {
|
|
||||||
checkBox.checked = !checkBox.checked
|
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: 10
|
spacing: (!isMobile ? 10 : 8)
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: checkMark
|
id: checkMark
|
||||||
@@ -90,11 +86,9 @@ Item {
|
|||||||
width: checkBox.imgWidth
|
width: checkBox.imgWidth
|
||||||
height: checkBox.imgHeight
|
height: checkBox.imgHeight
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
fontAwesomeFallbackIcon: checkBox.fontAwesomeIcons ? getIcon() : FontAwesome.plus
|
fontAwesomeFallbackIcon: FontAwesome.plus
|
||||||
fontAwesomeFallbackSize: 14
|
fontAwesomeFallbackSize: 14
|
||||||
image: checkBox.fontAwesomeIcons ? "" : getIcon()
|
image: {
|
||||||
|
|
||||||
function getIcon() {
|
|
||||||
if (checkBox.checked || checkBox.uncheckedIcon == "")
|
if (checkBox.checked || checkBox.uncheckedIcon == "")
|
||||||
return checkBox.checkedIcon;
|
return checkBox.checkedIcon;
|
||||||
return checkBox.uncheckedIcon;
|
return checkBox.uncheckedIcon;
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
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,11 +178,7 @@ Window {
|
|||||||
onAccepted: {
|
onAccepted: {
|
||||||
if(text.length > 0) {
|
if(text.length > 0) {
|
||||||
textArea.logCommand(">>> " + text)
|
textArea.logCommand(">>> " + text)
|
||||||
daemonManager.sendCommandAsync(text.split(" "), currentWallet.nettype, function(result) {
|
daemonManager.sendCommand(text, currentWallet.nettype);
|
||||||
if (!result) {
|
|
||||||
appWindow.showStatusMessage(qsTr("Failed to send command"), 3);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
text = ""
|
text = ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
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
|
||||||
@@ -38,7 +37,8 @@ import "effects/" as MoneroEffects
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: datePicker
|
id: datePicker
|
||||||
readonly property alias expanded: popup.visible
|
z: parent.z + 1
|
||||||
|
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,6 +52,19 @@ 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"
|
||||||
@@ -240,7 +253,7 @@ Item {
|
|||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: datePicker.expanded ? popup.close() : popup.open()
|
onClicked: datePicker.expanded = !datePicker.expanded
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
}
|
}
|
||||||
@@ -248,16 +261,12 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QtQuickControls2.Popup {
|
|
||||||
id: popup
|
|
||||||
padding: 0
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: calendarRect
|
id: calendarRect
|
||||||
width: head.width
|
anchors.left: parent.left
|
||||||
x: head.x
|
anchors.right: parent.right
|
||||||
y: head.y + head.height + 10
|
anchors.top: head.bottom
|
||||||
|
anchors.topMargin: 10
|
||||||
color: MoneroComponents.Style.middlePanelBackgroundColor
|
color: MoneroComponents.Style.middlePanelBackgroundColor
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: MoneroComponents.Style.appWindowBorderColor
|
border.color: MoneroComponents.Style.appWindowBorderColor
|
||||||
@@ -268,10 +277,6 @@ Item {
|
|||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
@@ -343,7 +348,7 @@ Item {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
if(styleData.visibleMonth) {
|
if(styleData.visibleMonth) {
|
||||||
currentDate = styleData.date
|
currentDate = styleData.date
|
||||||
popup.close()
|
datePicker.expanded = false
|
||||||
} else {
|
} else {
|
||||||
var date = styleData.date
|
var date = styleData.date
|
||||||
if(date.getMonth() > calendar.visibleMonth)
|
if(date.getMonth() > calendar.visibleMonth)
|
||||||
@@ -451,5 +456,4 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ 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
|
||||||
@@ -45,12 +44,4 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.Input {
|
TextField {
|
||||||
id : input
|
id : input
|
||||||
focus: true
|
focus: true
|
||||||
Layout.topMargin: 6
|
Layout.topMargin: 6
|
||||||
|
|||||||
@@ -57,10 +57,6 @@ 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;
|
||||||
@@ -68,12 +64,4 @@ TextArea {
|
|||||||
TextArea.cursorPosition = textArea.text.length;
|
TextArea.cursorPosition = textArea.text.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.ContextMenu {
|
|
||||||
cursorShape: Qt.IBeamCursor
|
|
||||||
onPaste: {
|
|
||||||
textArea.clear();
|
|
||||||
textArea.paste();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ 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
|
||||||
@@ -69,10 +68,5 @@ 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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ import "../components/effects/" as MoneroEffects
|
|||||||
Label {
|
Label {
|
||||||
id: item
|
id: item
|
||||||
fontSize: 18
|
fontSize: 18
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.top: item.bottom
|
anchors.top: item.bottom
|
||||||
|
|||||||
@@ -53,8 +53,6 @@ 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,6 +80,9 @@ 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
|
||||||
@@ -143,10 +146,7 @@ ColumnLayout {
|
|||||||
|
|
||||||
MoneroComponents.LabelButton {
|
MoneroComponents.LabelButton {
|
||||||
id: pasteButtonId
|
id: pasteButtonId
|
||||||
onClicked: {
|
onClicked: item.onPaste(clipboard.text())
|
||||||
input.clear();
|
|
||||||
input.paste();
|
|
||||||
}
|
|
||||||
text: qsTr("Paste") + translationManager.emptyString
|
text: qsTr("Paste") + translationManager.emptyString
|
||||||
visible: pasteButton
|
visible: pasteButton
|
||||||
}
|
}
|
||||||
|
|||||||
118
components/MobileHeader.qml
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
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,7 +29,6 @@
|
|||||||
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
|
||||||
|
|
||||||
@@ -147,50 +146,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.Input {
|
TextField {
|
||||||
id: passwordInput1
|
id: passwordInput1
|
||||||
Layout.topMargin: 6
|
Layout.topMargin: 6
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -203,7 +203,6 @@ Item {
|
|||||||
return passwordInput2
|
return passwordInput2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
implicitHeight: 50
|
|
||||||
bottomPadding: 10
|
bottomPadding: 10
|
||||||
leftPadding: 10
|
leftPadding: 10
|
||||||
topPadding: 10
|
topPadding: 10
|
||||||
@@ -297,7 +296,7 @@ Item {
|
|||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.Input {
|
TextField {
|
||||||
id: passwordInput2
|
id: passwordInput2
|
||||||
visible: !passwordDialogMode
|
visible: !passwordDialogMode
|
||||||
Layout.topMargin: 6
|
Layout.topMargin: 6
|
||||||
@@ -308,7 +307,6 @@ 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
|
||||||
@@ -392,7 +390,7 @@ Item {
|
|||||||
MoneroComponents.StandardButton {
|
MoneroComponents.StandardButton {
|
||||||
id: cancelButton
|
id: cancelButton
|
||||||
small: true
|
small: true
|
||||||
text: qsTr("Cancel") + translationManager.emptyString
|
text: root.walletName.length > 0 ? qsTr("Change wallet") + translationManager.emptyString : qsTr("Cancel") + translationManager.emptyString
|
||||||
KeyNavigation.tab: passwordInput1
|
KeyNavigation.tab: passwordInput1
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.close()
|
root.close()
|
||||||
@@ -409,7 +407,7 @@ Item {
|
|||||||
MoneroComponents.StandardButton {
|
MoneroComponents.StandardButton {
|
||||||
id: okButton
|
id: okButton
|
||||||
small: true
|
small: true
|
||||||
text: qsTr("Ok") + translationManager.emptyString
|
text: qsTr("Continue") + translationManager.emptyString
|
||||||
KeyNavigation.tab: cancelButton
|
KeyNavigation.tab: cancelButton
|
||||||
enabled: (passwordDialogMode == true) ? true : passwordInput1.text === passwordInput2.text
|
enabled: (passwordDialogMode == true) ? true : passwordInput1.text === passwordInput2.text
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ Item {
|
|||||||
|
|
||||||
MoneroComponents.TextPlain {
|
MoneroComponents.TextPlain {
|
||||||
id: label
|
id: label
|
||||||
Layout.leftMargin: 10
|
Layout.leftMargin: (!isMobile ? 10 : 8)
|
||||||
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: 2
|
columns: (isMobile) ? 1 : 2
|
||||||
columnSpacing: 32
|
columnSpacing: 32
|
||||||
id: root
|
id: root
|
||||||
property alias daemonAddrText: daemonAddr.text
|
property alias daemonAddrText: daemonAddr.text
|
||||||
|
|||||||
@@ -1,65 +0,0 @@
|
|||||||
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,8 +82,10 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -94,14 +96,14 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement without hardcoding sizes
|
// TODO: implement without hardcoding sizes
|
||||||
width: 520
|
width: isMobile ? screenWidth : 520
|
||||||
height: 380
|
height: isMobile ? screenHeight : 380
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
spacing: 10
|
spacing: 10
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: 20
|
anchors.margins: (isMobile? 17 : 20)
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: column
|
id: column
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
// 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
|
||||||
@@ -43,7 +42,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
|
||||||
readonly property alias expanded: popup.visible
|
property bool expanded: false
|
||||||
property int dropdownHeight: 42
|
property int dropdownHeight: 42
|
||||||
property int fontHeaderSize: 16
|
property int fontHeaderSize: 16
|
||||||
property int fontItemSize: 14
|
property int fontItemSize: 14
|
||||||
@@ -57,6 +56,18 @@ 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() {
|
||||||
@@ -117,21 +128,17 @@ Item {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
id: dropArea
|
id: dropArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: dropdown.expanded ? popup.close() : popup.open()
|
onClicked: dropdown.expanded = !dropdown.expanded
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Popup {
|
|
||||||
id: popup
|
|
||||||
padding: 0
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: droplist
|
id: droplist
|
||||||
x: dropdown.x
|
anchors.left: parent.left
|
||||||
width: dropdown.width
|
anchors.right: parent.right
|
||||||
y: head.y + head.height
|
anchors.top: head.bottom
|
||||||
clip: true
|
clip: true
|
||||||
height: dropdown.expanded ? columnid.height : 0
|
height: dropdown.expanded ? columnid.height : 0
|
||||||
color: dropdown.pressedColor
|
color: dropdown.pressedColor
|
||||||
@@ -165,11 +172,16 @@ Item {
|
|||||||
id: repeater
|
id: repeater
|
||||||
|
|
||||||
// Workaround for translations in listElements. All translated strings needs to be listed in this file.
|
// Workaround for translations in listElements. All translated strings needs to be listed in this file.
|
||||||
property string stringAutomatic: qsTr("Automatic") + translationManager.emptyString
|
property string stringLow: qsTr("Low (x1 fee)") + translationManager.emptyString
|
||||||
property string stringSlow: qsTr("Slow (x0.2 fee)") + translationManager.emptyString
|
property string stringMedium: qsTr("Medium (x20 fee)") + translationManager.emptyString
|
||||||
property string stringNormal: qsTr("Normal (x1 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 stringFast: qsTr("Fast (x5 fee)") + translationManager.emptyString
|
||||||
property string stringFastest: qsTr("Fastest (x200 fee)") + translationManager.emptyString
|
property string stringFastest: qsTr("Fastest (x41.5 fee)") + translationManager.emptyString
|
||||||
|
property string stringAll: qsTr("All") + translationManager.emptyString
|
||||||
|
property string stringSent: qsTr("Sent") + translationManager.emptyString
|
||||||
|
property string stringReceived: qsTr("Received") + translationManager.emptyString
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -224,7 +236,7 @@ Item {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
popup.close()
|
dropdown.expanded = false
|
||||||
columnid.currentIndex = index
|
columnid.currentIndex = index
|
||||||
changed();
|
changed();
|
||||||
dropdown.update()
|
dropdown.update()
|
||||||
@@ -234,5 +246,4 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ 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
|
||||||
@@ -107,6 +108,7 @@ 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"
|
||||||
@@ -163,6 +165,7 @@ 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) return 0;
|
if(!persistentSettings.customDecorations || isMobile) return 0;
|
||||||
return 50;
|
return 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,18 +56,18 @@ Rectangle {
|
|||||||
signal maximizeClicked
|
signal maximizeClicked
|
||||||
signal minimizeClicked
|
signal minimizeClicked
|
||||||
signal languageClicked
|
signal languageClicked
|
||||||
signal closeWalletClicked
|
signal goToBasicVersion(bool yes)
|
||||||
|
|
||||||
state: "default"
|
state: "default"
|
||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
name: "default";
|
name: "default";
|
||||||
PropertyChanges { target: btnCloseWallet; visible: true}
|
PropertyChanges { target: btnSidebarCollapse; 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: btnCloseWallet; visible: false}
|
PropertyChanges { target: btnSidebarCollapse; visible: false}
|
||||||
PropertyChanges { target: btnLanguageToggle; visible: false}
|
PropertyChanges { target: btnLanguageToggle; visible: false}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -93,20 +93,22 @@ Rectangle {
|
|||||||
|
|
||||||
// collapse sidebar
|
// collapse sidebar
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: btnCloseWallet
|
id: btnSidebarCollapse
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +118,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.closeWalletClicked(leftPanel.visible)
|
onClicked: root.goToBasicVersion(leftPanel.visible)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,10 +131,9 @@ Rectangle {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: FontAwesome.globe
|
text: FontAwesome.globe
|
||||||
font.family: FontAwesome.fontFamilySolid
|
font.family: FontAwesome.fontFamily
|
||||||
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
|
||||||
@@ -155,10 +156,9 @@ Rectangle {
|
|||||||
Layout.preferredHeight: parent.height
|
Layout.preferredHeight: parent.height
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: FontAwesome.moonO
|
text: MoneroComponents.Style.blackTheme ? FontAwesome.lightbulbO : FontAwesome.moonO
|
||||||
font.family: MoneroComponents.Style.blackTheme ? FontAwesome.fontFamilySolid : FontAwesome.fontFamily
|
font.family: FontAwesome.fontFamily
|
||||||
font.styleName: MoneroComponents.Style.blackTheme ? "Solid" : "Regular"
|
font.pixelSize: 16
|
||||||
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,7 +189,6 @@ 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
|
||||||
|
|
||||||
@@ -217,22 +216,6 @@ 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"
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
TextArea {
|
||||||
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();
|
||||||
|
|
||||||
MouseArea {
|
selectionColor: MoneroComponents.Style.textSelectionColor
|
||||||
anchors.fill: parent
|
selectedTextColor: MoneroComponents.Style.textSelectedColor
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,9 +39,8 @@ 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
|
||||||
@@ -68,16 +67,15 @@ Item {
|
|||||||
anchors.fill: root
|
anchors.fill: root
|
||||||
source: svgMask
|
source: svgMask
|
||||||
color: root.color
|
color: root.color
|
||||||
visible: image && isOpenGL
|
visible: isOpenGL
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: fontAwesomeFallback
|
id: fontAwesomeFallback
|
||||||
visible: !imgMockColor.visible
|
visible: !isOpenGL && root.fontAwesomeFallback
|
||||||
text: root.fontAwesomeFallbackIcon
|
text: !isOpenGL ? root.fontAwesomeFallbackIcon : ""
|
||||||
font.family: root.fontAwesomeFallbackFont
|
font.family: FontAwesome.fontFamily
|
||||||
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,23 +4,10 @@ import QtQuick 2.9
|
|||||||
Object {
|
Object {
|
||||||
|
|
||||||
FontLoader {
|
FontLoader {
|
||||||
id: regular
|
source: "./fontawesome-webfont.ttf"
|
||||||
source: "./fa-regular-400.ttf"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FontLoader {
|
property string fontFamily: "FontAwesome"
|
||||||
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"
|
||||||
@@ -607,7 +594,6 @@ 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/fontawesome-webfont.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.15.0.1
|
git -C $MONERO_DIR checkout v0.14.1.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_TAG="mac-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="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" ../..
|
||||||
else
|
else
|
||||||
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_TAG="mac-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D 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_TAG="linux-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D ARCH="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" ../..
|
||||||
else
|
else
|
||||||
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D BUILD_TAG="linux-x64" -D BUILD_GUI_DEPS=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D 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_TAG="win-x64" -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON $BUILD_TREZOR_FLAGS -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" -D CMAKE_TOOLCHAIN_FILE=../../cmake/64-bit-toolchain.cmake -D MSYS2_FOLDER=c:/msys64 ../..
|
cmake -D CMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -D STATIC=ON -D BOOST_ROOT="$BOOST_ROOT" -D ARCH="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 ../..
|
||||||
|
|
||||||
## Windows 32
|
## Windows 32
|
||||||
elif [ "$platform" == "mingw32" ]; then
|
elif [ "$platform" == "mingw32" ]; then
|
||||||
@@ -253,7 +253,4 @@ 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
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 10 KiB |
BIN
images/card-background.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
images/card-background@2x.png
Executable file
|
After Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 419 B After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 436 B After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 612 B After Width: | Height: | Size: 15 KiB |
BIN
images/minus-white.png
Normal file
|
After Width: | Height: | Size: 170 B |
BIN
images/minus-white@2x.png
Normal file
|
After Width: | Height: | Size: 170 B |
BIN
images/plus-in-circle-medium-white.png
Executable file
|
After Width: | Height: | Size: 399 B |
BIN
images/plus-in-circle-medium-white@2x.png
Executable file
|
After Width: | Height: | Size: 760 B |
BIN
images/plus-white.png
Normal file
|
After Width: | Height: | Size: 193 B |
BIN
images/plus-white@2x.png
Normal file
|
After Width: | Height: | Size: 195 B |
6
images/settings_local.svg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 359 B |
7
images/settings_remote.svg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 371 B |
6
images/sidebar.svg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 379 B |
6
images/themes/white/expand.svg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 328 B |
@@ -1,7 +1,6 @@
|
|||||||
; Monero Carbon Chamaeleon GUI Wallet Installer for Windows
|
; Monero Boron Butterfly 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
|
||||||
@@ -9,8 +8,7 @@ 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={#GuiVersion}
|
AppVersion=0.14.1.0
|
||||||
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
|
||||||
@@ -41,8 +39,6 @@ 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"
|
||||||
@@ -62,14 +58,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.15.0.0, the Monero .exe files do not carry version info anyway in their .exe headers.
|
; As of version 0.14.1.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: {#file AddBackslash(SourcePath) + "ReadMe.htm"}; DestDir: "{app}"; DestName: "ReadMe.htm"; Flags: ignoreversion
|
Source: "ReadMe.htm"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
Source: "FinishImage.bmp"; Flags: dontcopy
|
Source: "FinishImage.bmp"; Flags: dontcopy
|
||||||
|
|
||||||
; Monero GUI wallet exe and guide
|
; Monero GUI wallet exe and guide
|
||||||
@@ -201,7 +197,7 @@ begin
|
|||||||
// Additional wizard page for entering a special blockchain location
|
// Additional wizard page for entering a special blockchain location
|
||||||
blockChainDefaultDir := ExpandConstant('{commonappdata}\bitmonero');
|
blockChainDefaultDir := ExpandConstant('{commonappdata}\bitmonero');
|
||||||
s := 'The default folder to store the Monero blockchain is ' + blockChainDefaultDir;
|
s := 'The default folder to store the Monero blockchain is ' + blockChainDefaultDir;
|
||||||
s := s + '. As this will need more than 74 GB of free space, you may want to use a folder on a different drive.';
|
s := s + '. As this will need more than 70 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,
|
||||||
@@ -317,7 +313,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-wallet-guide.pdf"; IconFilename: "{app}\monero-wallet-gui.exe"
|
Name: "{group}\GUI Wallet Guide"; Filename: "{app}\monero-GUI-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 Carbon Chamaeleon release of Monero.
|
the GUI wallet that comes with the Boron Butterfly release of Monero.
|
||||||
|
|
||||||
This turns the GUI wallet into a more or less standard Windows program,
|
This turns the GUI wallet into a more or less standard Windows program,
|
||||||
by default installed into a subdirectory of `C:\Program Files`, a
|
by default installed into a subdirectory of `C:\Program Files`, a
|
||||||
@@ -18,7 +18,7 @@ Monero.
|
|||||||
As the setup script in file [Monero.iss](Monero.iss) has to list many
|
As the setup script in file [Monero.iss](Monero.iss) has to list many
|
||||||
files and directories of the GUI wallet package to install by name,
|
files and directories of the GUI wallet package to install by name,
|
||||||
this version of the script only works with exactly the GUI wallet
|
this version of the script only works with exactly the GUI wallet
|
||||||
for Monero release *Carbon Chamaeleon* that you find on
|
for Monero release *Boron Butterfly* 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,13 @@ See [LICENSE](LICENSE).
|
|||||||
|
|
||||||
You can only build on Windows, and the result is always a
|
You can only build on Windows, and the result is always a
|
||||||
Windows .exe file that can act as a standalone installer for the
|
Windows .exe file that can act as a standalone installer for the
|
||||||
Carbon Chamaeleon GUI wallet.
|
Boron Butterfly GUI wallet.
|
||||||
|
|
||||||
Note that the installer build process is now reproducible / deterministic. For details check the file [Deterministic.md](Deterministic.md).
|
|
||||||
|
|
||||||
The build steps in detail:
|
The build steps in detail:
|
||||||
|
|
||||||
1. Install *Inno Setup*. You can get it from [here](http://www.jrsoftware.org/isdl.php)
|
1. Install *Inno Setup*. You can get it from [here](http://www.jrsoftware.org/isdl.php)
|
||||||
2. Get the Inno Setup script plus related files by cloning the whole [monero-gui GitHub repository](https://github.com/monero-project/monero-gui); you will only need the files in the installer directory `installers\windows` however. Depending on development state, additionally instead of simply using `master` you may have to checkout a specific branch, like `release-v0.15`.
|
2. Get the Inno Setup script plus related files by cloning the whole [monero-gui GitHub repository](https://github.com/monero-project/monero-gui); you will only need the files in the installer directory `installers\windows` however. Depending on development state, additionally you may have to checkout a specific branch, like `release-v0.14`.
|
||||||
3. The setup script is written to take the GUI wallet files from a subdirectory named `bin`; so create `installers\windows\bin`, get the zip file of the GUI wallet from [here](https://getmonero.org/downloads/), unpack it somewhere, and copy all the files and subdirectories in the single subdirectory there (currently named `monero-gui-0.15.0.0`) to this `bin` subdirectory
|
3. The setup script is written to take the GUI wallet files from a subdirectory named `bin`; so create `installers\windows\bin`, get the zip file of the GUI wallet from [here](https://getmonero.org/downloads/), unpack it somewhere, and copy all the files and subdirectories in the single subdirectory there (currently named `monero-gui-0.14.1.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,12 +1,13 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Monero Carbon Chamaeleon GUI Wallet</title>
|
<title>Monero Boron Butterfly GUI Wallet</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body style="font-family: Arial, Helvetica, sans-serif">
|
<body style="font-family: Arial, Helvetica, sans-serif">
|
||||||
<h1>Monero Carbon Chamaeleon GUI Wallet</h1>
|
<h1>Monero Boron Butterfly GUI Wallet</h1>
|
||||||
|
|
||||||
<p>Copyright (c) 2014-2019, The Monero Project</p>
|
<p>Copyright (c) 2014-2019, The Monero Project<br>
|
||||||
|
Date: May 7, 2019</p>
|
||||||
|
|
||||||
<h2>Preface</h2>
|
<h2>Preface</h2>
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@
|
|||||||
|
|
||||||
<h2>Content of the Package</h2>
|
<h2>Content of the Package</h2>
|
||||||
|
|
||||||
<p>You just installed the <i>Monero GUI wallet</i> for Windows, release Carbon Chamaeleon, version {#GuiVersion}.
|
<p>You just installed the <i>Monero GUI wallet</i> for Windows, release Boron Butterfly, version 0.14.1.0.
|
||||||
The wallet enables you to send and receive Moneroj in a secure and very private way.
|
The wallet enables you to send and receive Moneroj in a secure and very private way.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@
|
|||||||
provides the most security and privacy possible for you.</p>
|
provides the most security and privacy possible for you.</p>
|
||||||
|
|
||||||
<p>However if your Internet access makes it difficult to run a full node, or if you have simply no room to store
|
<p>However if your Internet access makes it difficult to run a full node, or if you have simply no room to store
|
||||||
the blockchain locally (somewhat over 74 GB in November 2019, and of course growing), you can compromise and try to connect
|
the blockchain locally (somewhat over 70 GB in May 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 |
1
installers/windows/monero-wallet-gui.log
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-----
|
||||||
23
js/Utils.js
@@ -46,6 +46,7 @@ function showSeedPage() {
|
|||||||
leftPanel.selectItem(middlePanel.state);
|
leftPanel.selectItem(middlePanel.state);
|
||||||
}
|
}
|
||||||
passwordDialog.open();
|
passwordDialog.open();
|
||||||
|
if(isMobile) hideMenu();
|
||||||
updateBalance();
|
updateBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,6 +94,16 @@ 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);
|
||||||
}
|
}
|
||||||
@@ -133,3 +144,15 @@ 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,8 +39,10 @@ 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 = wizard.verticalCenter
|
prevButton.anchors.verticalCenter = (!isMobile) ? wizard.verticalCenter : undefined
|
||||||
nextButton.anchors.verticalCenter = wizard.verticalCenter
|
prevButton.anchors.bottom = (isMobile) ? wizard.bottom : undefined
|
||||||
|
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,9 +125,6 @@ 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");
|
||||||
@@ -174,10 +171,7 @@ 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);
|
||||||
|
|
||||||
@@ -198,9 +192,7 @@ 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();
|
||||||
@@ -408,10 +400,6 @@ 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)
|
||||||
|
|||||||
473
main.qml
@@ -47,7 +47,7 @@ import "js/Windows.js" as Windows
|
|||||||
|
|
||||||
ApplicationWindow {
|
ApplicationWindow {
|
||||||
id: appWindow
|
id: appWindow
|
||||||
title: "Monero" + (walletName ? " - " + walletName : "")
|
title: "Monero"
|
||||||
|
|
||||||
property var currentItem
|
property var currentItem
|
||||||
property bool hideBalanceForced: false
|
property bool hideBalanceForced: false
|
||||||
@@ -69,6 +69,7 @@ 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
|
||||||
@@ -86,8 +87,8 @@ ApplicationWindow {
|
|||||||
property bool themeTransition: false
|
property bool themeTransition: false
|
||||||
|
|
||||||
// fiat price conversion
|
// fiat price conversion
|
||||||
property real fiatPriceXMRUSD: 0
|
property int fiatPriceXMRUSD: 0
|
||||||
property real fiatPriceXMREUR: 0
|
property int fiatPriceXMREUR: 0
|
||||||
property var fiatPriceAPIs: {
|
property var fiatPriceAPIs: {
|
||||||
return {
|
return {
|
||||||
"kraken": {
|
"kraken": {
|
||||||
@@ -105,6 +106,19 @@ 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
|
||||||
|
|
||||||
@@ -112,6 +126,7 @@ 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; }
|
||||||
|
|
||||||
@@ -224,6 +239,7 @@ 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";
|
||||||
@@ -270,13 +286,7 @@ 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) {
|
||||||
if (callback) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentWallet.heightRefreshed.disconnect(onHeightRefreshed);
|
currentWallet.heightRefreshed.disconnect(onHeightRefreshed);
|
||||||
currentWallet.refreshed.disconnect(onWalletRefresh)
|
currentWallet.refreshed.disconnect(onWalletRefresh)
|
||||||
currentWallet.updated.disconnect(onWalletUpdate)
|
currentWallet.updated.disconnect(onWalletUpdate)
|
||||||
@@ -293,8 +303,8 @@ ApplicationWindow {
|
|||||||
middlePanel.sweepUnmixableClicked.disconnect(handleSweepUnmixable);
|
middlePanel.sweepUnmixableClicked.disconnect(handleSweepUnmixable);
|
||||||
middlePanel.getProofClicked.disconnect(handleGetProof);
|
middlePanel.getProofClicked.disconnect(handleGetProof);
|
||||||
middlePanel.checkProofClicked.disconnect(handleCheckProof);
|
middlePanel.checkProofClicked.disconnect(handleCheckProof);
|
||||||
|
}
|
||||||
|
|
||||||
appWindow.walletName = "";
|
|
||||||
currentWallet = undefined;
|
currentWallet = undefined;
|
||||||
|
|
||||||
appWindow.showProcessingSplash(qsTr("Closing wallet..."));
|
appWindow.showProcessingSplash(qsTr("Closing wallet..."));
|
||||||
@@ -334,6 +344,7 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
walletName = usefulName(wallet.path)
|
walletName = usefulName(wallet.path)
|
||||||
|
updateSyncing(false)
|
||||||
|
|
||||||
viewOnly = currentWallet.viewOnly;
|
viewOnly = currentWallet.viewOnly;
|
||||||
|
|
||||||
@@ -374,21 +385,11 @@ ApplicationWindow {
|
|||||||
currentDaemonAddress = localDaemonAddress
|
currentDaemonAddress = localDaemonAddress
|
||||||
|
|
||||||
console.log("initializing with daemon address: ", currentDaemonAddress)
|
console.log("initializing with daemon address: ", currentDaemonAddress)
|
||||||
currentWallet.initAsync(
|
currentWallet.initAsync(currentDaemonAddress, 0, persistentSettings.is_recovering, persistentSettings.is_recovering_from_device, persistentSettings.restore_height);
|
||||||
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;
|
||||||
@@ -405,20 +406,24 @@ ApplicationWindow {
|
|||||||
if (!currentWallet)
|
if (!currentWallet)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var balance = "?.??";
|
var balance_unlocked = qsTr("HIDDEN");
|
||||||
var balanceU = "?.??";
|
var balance = qsTr("HIDDEN");
|
||||||
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);
|
appWindow.fiatApiUpdateBalance(balance, balance_unlocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
leftPanel.minutesToUnlock = (balance !== balanceU) ? currentWallet.history.minutesToUnlock : "";
|
var accountLabel = currentWallet.getSubaddressLabel(currentWallet.currentSubaddressAccount, 0);
|
||||||
leftPanel.balanceString = balance
|
leftPanel.balanceLabelText = qsTr("Balance (#%1%2)").arg(currentWallet.currentSubaddressAccount).arg(accountLabel === "" ? "" : (" – " + accountLabel));
|
||||||
leftPanel.balanceUnlockedString = balanceU
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onUriHandler(uri){
|
function onUriHandler(uri){
|
||||||
@@ -457,6 +462,10 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,24 +475,16 @@ ApplicationWindow {
|
|||||||
leftPanel.networkStatus.connected = status
|
leftPanel.networkStatus.connected = status
|
||||||
|
|
||||||
// update local daemon status.
|
// update local daemon status.
|
||||||
const isDisconnected = status === Wallet.ConnectionStatus_Disconnected;
|
if(!isMobile && walletManager.isDaemonLocal(currentDaemonAddress))
|
||||||
if (walletManager.isDaemonLocal(currentDaemonAddress)) {
|
daemonRunning = status;
|
||||||
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 (appWindow.walletMode >= 2 && walletManager.isDaemonLocal(currentDaemonAddress) && !walletInitialized && isDisconnected) {
|
if(!isMobile && appWindow.walletMode >= 2 && walletManager.isDaemonLocal(currentDaemonAddress) && !walletInitialized && status === Wallet.ConnectionStatus_Disconnected && !daemonManager.running(persistentSettings.nettype)){
|
||||||
daemonManager.runningAsync(persistentSettings.nettype, function(running) {
|
|
||||||
if (!running) {
|
|
||||||
daemonManagerDialog.open();
|
daemonManagerDialog.open();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
// initialize transaction history once wallet is initialized first time;
|
// initialize transaction history once wallet is initialized first time;
|
||||||
if (!walletInitialized) {
|
if (!walletInitialized) {
|
||||||
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
|
currentWallet.history.refresh(currentWallet.currentSubaddressAccount)
|
||||||
@@ -591,6 +592,8 @@ 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();
|
||||||
@@ -599,19 +602,10 @@ ApplicationWindow {
|
|||||||
|
|
||||||
function connectRemoteNode() {
|
function connectRemoteNode() {
|
||||||
console.log("connecting remote node");
|
console.log("connecting remote node");
|
||||||
|
|
||||||
const callback = function() {
|
|
||||||
persistentSettings.useRemoteNode = true;
|
persistentSettings.useRemoteNode = true;
|
||||||
currentDaemonAddress = persistentSettings.remoteNodeAddress;
|
currentDaemonAddress = persistentSettings.remoteNodeAddress;
|
||||||
currentWallet.initAsync(currentDaemonAddress, isTrustedDaemon());
|
currentWallet.initAsync(currentDaemonAddress);
|
||||||
walletManager.setDaemonAddressAsync(currentDaemonAddress);
|
walletManager.setDaemonAddressAsync(currentDaemonAddress);
|
||||||
};
|
|
||||||
|
|
||||||
if (typeof daemonManager != "undefined" && daemonRunning) {
|
|
||||||
showDaemonIsRunningDialog(callback);
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function disconnectRemoteNode() {
|
function disconnectRemoteNode() {
|
||||||
@@ -621,7 +615,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, isTrustedDaemon());
|
currentWallet.initAsync(currentDaemonAddress);
|
||||||
walletManager.setDaemonAddressAsync(currentDaemonAddress);
|
walletManager.setDaemonAddressAsync(currentDaemonAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -643,7 +637,7 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update wallet sync progress
|
// Update wallet sync progress
|
||||||
leftPanel.isSyncing = (currentWallet.connected() !== Wallet.ConnectionStatus_Disconnected) && !daemonSynced
|
updateSyncing((currentWallet.connected() !== Wallet.ConnectionStatus_Disconnected) && !daemonSynced)
|
||||||
// Update transfer page status
|
// Update transfer page status
|
||||||
middlePanel.updateStatus();
|
middlePanel.updateStatus();
|
||||||
|
|
||||||
@@ -693,8 +687,8 @@ ApplicationWindow {
|
|||||||
simpleModeConnectionTimer.stop();
|
simpleModeConnectionTimer.stop();
|
||||||
|
|
||||||
appWindow.showProcessingSplash(qsTr("Waiting for daemon to start..."))
|
appWindow.showProcessingSplash(qsTr("Waiting for daemon to start..."))
|
||||||
const noSync = appWindow.walletMode === 0;
|
daemonManager.start(flags, persistentSettings.nettype, persistentSettings.blockchainDataDir, persistentSettings.bootstrapNodeAddress);
|
||||||
daemonManager.start(flags, persistentSettings.nettype, persistentSettings.blockchainDataDir, persistentSettings.bootstrapNodeAddress, noSync);
|
persistentSettings.daemonFlags = flags
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopDaemon(){
|
function stopDaemon(){
|
||||||
@@ -710,7 +704,6 @@ 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(){
|
||||||
@@ -848,9 +841,7 @@ ApplicationWindow {
|
|||||||
", priority: ", priority,
|
", priority: ", priority,
|
||||||
", description: ", description);
|
", description: ", description);
|
||||||
|
|
||||||
var splashMsg = qsTr("Creating transaction...");
|
showProcessingSplash("Creating transaction");
|
||||||
splashMsg += appWindow.currentWallet.isLedger() ? qsTr("\n\nPlease check your hardware wallet –\nyour input may be required.") : "";
|
|
||||||
showProcessingSplash(splashMsg);
|
|
||||||
|
|
||||||
transactionDescription = description;
|
transactionDescription = description;
|
||||||
|
|
||||||
@@ -1088,6 +1079,12 @@ 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;
|
||||||
@@ -1122,19 +1119,32 @@ 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
|
||||||
clearMoneroCardLabelText();
|
leftPanel.balanceText = leftPanel.unlockedBalanceText = walletManager.displayAmount(0);
|
||||||
|
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
|
||||||
@@ -1251,34 +1261,22 @@ ApplicationWindow {
|
|||||||
Prices.getJSON(url);
|
Prices.getJSON(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fiatApiCurrencySymbol() {
|
function fiatApiUpdateBalance(balance, unlocked_balance){
|
||||||
switch (persistentSettings.fiatPriceCurrency) {
|
|
||||||
case "xmrusd":
|
|
||||||
return "USD";
|
|
||||||
case "xmreur":
|
|
||||||
return "EUR";
|
|
||||||
default:
|
|
||||||
console.error("unsupported currency", persistentSettings.fiatPriceCurrency);
|
|
||||||
return "UNSUPPORTED";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function fiatApiConvertToFiat(amount) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
function fiatApiUpdateBalance(balance){
|
|
||||||
// update balance card
|
// update balance card
|
||||||
var bFiat = "?.??"
|
var ticker = persistentSettings.fiatPriceCurrency === "xmrusd" ? appWindow.fiatPriceXMRUSD : appWindow.fiatPriceXMREUR;
|
||||||
if (!hideBalanceForced && !persistentSettings.hideBalance) {
|
var symbol = persistentSettings.fiatPriceCurrency === "xmrusd" ? "$" : "€"
|
||||||
bFiat = fiatApiConvertToFiat(balance);
|
if(ticker <= 0){
|
||||||
|
console.log(fiatApiError("Could not update balance card; invalid ticker value"));
|
||||||
|
leftPanel.unlockedBalanceTextFiat = "N/A";
|
||||||
|
leftPanel.balanceTextFiat = "N/A";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
leftPanel.balanceFiatString = bFiat;
|
|
||||||
|
var uFiat = Utils.formatMoney(unlocked_balance * ticker);
|
||||||
|
var bFiat = Utils.formatMoney(balance * ticker);
|
||||||
|
|
||||||
|
leftPanel.unlockedBalanceTextFiat = symbol + uFiat;
|
||||||
|
leftPanel.balanceTextFiat = symbol + bFiat;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fiatTimerStart(){
|
function fiatTimerStart(){
|
||||||
@@ -1296,9 +1294,6 @@ 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);
|
||||||
@@ -1388,6 +1383,7 @@ 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
|
||||||
@@ -1395,7 +1391,9 @@ 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
|
||||||
@@ -1594,96 +1592,153 @@ 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: parent.top
|
anchors.top: mobileHeader.bottom
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1691,14 +1746,102 @@ ApplicationWindow {
|
|||||||
|
|
||||||
MiddlePanel {
|
MiddlePanel {
|
||||||
id: middlePanel
|
id: middlePanel
|
||||||
accountView.currentAccountIndex: currentWallet ? currentWallet.currentSubaddressAccount : 0
|
anchors.top: mobileHeader.bottom
|
||||||
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
|
||||||
@@ -1763,14 +1906,21 @@ 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 {
|
||||||
@@ -1854,43 +2004,41 @@ 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;
|
||||||
|
|
||||||
const disconnectedTimeoutSec = 30;
|
var disconnected = leftPanel.networkStatus.connected === Wallet.ConnectionStatus_Disconnected;
|
||||||
const firstCheckDelaySec = 2;
|
var disconnectedEpoch = appWindow.disconnectedEpoch;
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
const sinceLastConnect = Utils.epoch() - appWindow.disconnectedEpoch;
|
// disconnected longer than 5 seconds?
|
||||||
if (sinceLastConnect < disconnectedTimeoutSec && checkNoSyncFlag()) {
|
if(disconnected && disconnectedEpoch > 0 && (Utils.epoch() - disconnectedEpoch) >= 5){
|
||||||
|
// for bootstrap mode, first wait until daemon is killed
|
||||||
|
if(appWindow.walletMode === 1 && appWindow.daemonRunning) {
|
||||||
|
appWindow.stopDaemon();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appWindow.daemonRunning) {
|
// fetch new node list
|
||||||
appWindow.stopDaemon();
|
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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
appWindow.startDaemon("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
@@ -1934,23 +2082,6 @@ 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");
|
||||||
@@ -1972,12 +2103,22 @@ 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) {
|
||||||
if (appWindow.walletMode == 0) {
|
// Show confirmation dialog
|
||||||
stopDaemon();
|
confirmationDialog.title = qsTr("Daemon is running") + translationManager.emptyString;
|
||||||
|
confirmationDialog.text = qsTr("Daemon will still be running in background when GUI is closed.");
|
||||||
|
confirmationDialog.icon = StandardIcon.Question
|
||||||
|
confirmationDialog.cancelText = qsTr("Stop daemon")
|
||||||
|
confirmationDialog.onAcceptedCallback = function() {
|
||||||
closeAccepted();
|
closeAccepted();
|
||||||
} else {
|
|
||||||
showDaemonIsRunningDialog(closeAccepted);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
confirmationDialog.onRejectedCallback = function() {
|
||||||
|
daemonManager.stop(persistentSettings.nettype);
|
||||||
|
closeAccepted();
|
||||||
|
};
|
||||||
|
|
||||||
|
confirmationDialog.open()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
closeAccepted();
|
closeAccepted();
|
||||||
}
|
}
|
||||||
@@ -1999,12 +2140,17 @@ 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 (isMac || isWindows || isLinux) {
|
if (osBuildTag !== "unknownBuildTag") {
|
||||||
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
|
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
|
||||||
} else {
|
} else {
|
||||||
msg = qsTr("New version of Monero v%1 is available. Check out getmonero.org").arg(version) + translationManager.emptyString
|
msg = qsTr("New version of Monero is available. Check out getmonero.org") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
notifier.show(msg)
|
notifier.show(msg)
|
||||||
} else {
|
} else {
|
||||||
@@ -2033,16 +2179,14 @@ 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.balanceString = "?.??"
|
leftPanel.minutesToUnlockTxt = qsTr("Unlocked balance")
|
||||||
leftPanel.balanceFiatString = "?.??"
|
leftPanel.balanceLabelText = qsTr("Balance")
|
||||||
}
|
}
|
||||||
|
|
||||||
// some fields need an extra nudge when changing languages
|
// some fields need an extra nudge when changing languages
|
||||||
function resetLanguageFields(){
|
function resetLanguageFields(){
|
||||||
clearMoneroCardLabelText()
|
clearMoneroCardLabelText()
|
||||||
if (currentWallet) {
|
onWalletRefresh()
|
||||||
onWalletRefresh();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function userActivity() {
|
function userActivity() {
|
||||||
@@ -2085,22 +2229,11 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function changeWalletMode(mode){
|
function changeWalletMode(mode){
|
||||||
appWindow.disconnectedEpoch = 0;
|
|
||||||
appWindow.walletMode = mode;
|
appWindow.walletMode = mode;
|
||||||
persistentSettings.walletMode = mode;
|
persistentSettings.walletMode = mode;
|
||||||
applyWalletMode(mode);
|
persistentSettings.useRemoteNode = mode === 0 ? true : false;
|
||||||
}
|
|
||||||
|
|
||||||
function applyWalletMode(mode){
|
console.log("walletMode changed: " + (mode === 0 ? "simple": mode === 1 ? "simple (bootstrap)" : "Advanced"));
|
||||||
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.7
|
# qml components require at least QT 5.9.0
|
||||||
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.7")
|
error("Can't build with Qt $${QT_VERSION}. Use at least Qt 5.9.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
@@ -16,21 +16,10 @@ 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
|
||||||
}
|
}
|
||||||
@@ -153,25 +142,25 @@ ios:arm64 {
|
|||||||
LIBS += \
|
LIBS += \
|
||||||
-L$$PWD/../ofxiOSBoost/build/libs/boost/lib/arm64 \
|
-L$$PWD/../ofxiOSBoost/build/libs/boost/lib/arm64 \
|
||||||
}
|
}
|
||||||
|
!ios:!android {
|
||||||
LIBS_COMMON = \
|
LIBS += -L$$WALLET_ROOT/lib \
|
||||||
-lwallet_merged \
|
-lwallet_merged \
|
||||||
-llmdb \
|
-llmdb \
|
||||||
-lepee \
|
-lepee \
|
||||||
-lunbound \
|
-lunbound \
|
||||||
-lsodium \
|
-lsodium \
|
||||||
-leasylogging \
|
-leasylogging
|
||||||
-lrandomx
|
|
||||||
|
|
||||||
!ios:!android {
|
|
||||||
LIBS += -L$$WALLET_ROOT/lib \
|
|
||||||
$$LIBS_COMMON
|
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
message("Host is Android")
|
message("Host is Android")
|
||||||
LIBS += -L$$WALLET_ROOT/lib \
|
LIBS += -L$$WALLET_ROOT/lib \
|
||||||
$$LIBS_COMMON
|
-lwallet_merged \
|
||||||
|
-llmdb \
|
||||||
|
-lepee \
|
||||||
|
-lunbound \
|
||||||
|
-lsodium \
|
||||||
|
-leasylogging
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -186,7 +175,12 @@ 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 \
|
||||||
$$LIBS_COMMON
|
-lwallet_merged \
|
||||||
|
-llmdb \
|
||||||
|
-lepee \
|
||||||
|
-lunbound \
|
||||||
|
-lsodium \
|
||||||
|
-leasylogging
|
||||||
|
|
||||||
LIBS+= \
|
LIBS+= \
|
||||||
-L$$PWD/../OpenSSL-for-iPhone/lib \
|
-L$$PWD/../OpenSSL-for-iPhone/lib \
|
||||||
@@ -293,7 +287,6 @@ win32 {
|
|||||||
-licudt \
|
-licudt \
|
||||||
-licutu \
|
-licutu \
|
||||||
-liconv \
|
-liconv \
|
||||||
-lstdc++ \
|
|
||||||
-lpthread \
|
-lpthread \
|
||||||
-lsetupapi \
|
-lsetupapi \
|
||||||
-lssl \
|
-lssl \
|
||||||
@@ -344,13 +337,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
|
||||||
@@ -370,19 +363,11 @@ 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$$OPENSSL_LIBRARY_DIRS \
|
-L/usr/local/opt/openssl/lib \
|
||||||
-L/usr/local/opt/boost/lib \
|
-L/usr/local/opt/boost/lib \
|
||||||
-lboost_serialization \
|
-lboost_serialization \
|
||||||
-lboost_thread-mt \
|
-lboost_thread-mt \
|
||||||
@@ -512,9 +497,6 @@ 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
|
||||||
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
|
#ifdef Q_OS_LINUX
|
||||||
#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) && !defined(Q_OS_ANDROID) // X11 version
|
#elif defined(Q_OS_LINUX) // 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,7 +31,6 @@ 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
|
||||||
@@ -49,7 +48,6 @@ 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;
|
||||||
@@ -66,7 +64,7 @@ Rectangle {
|
|||||||
/* main layout */
|
/* main layout */
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
anchors.margins: 20
|
anchors.margins: (isMobile)? 17 : 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -103,7 +101,8 @@ Rectangle {
|
|||||||
id: balanceAll
|
id: balanceAll
|
||||||
font.family: MoneroComponents.Style.fontMonoRegular.name;
|
font.family: MoneroComponents.Style.fontMonoRegular.name;
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.dimmedFontColor
|
||||||
|
themeTransition: false
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
@@ -136,7 +135,8 @@ Rectangle {
|
|||||||
id: unlockedBalanceAll
|
id: unlockedBalanceAll
|
||||||
font.family: MoneroComponents.Style.fontMonoRegular.name;
|
font.family: MoneroComponents.Style.fontMonoRegular.name;
|
||||||
font.pixelSize: 16
|
font.pixelSize: 16
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.dimmedFontColor
|
||||||
|
themeTransition: false
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
@@ -177,11 +177,10 @@ Rectangle {
|
|||||||
ListView {
|
ListView {
|
||||||
id: subaddressAccountListView
|
id: subaddressAccountListView
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
anchors.fill: parent
|
||||||
clip: true
|
clip: true
|
||||||
boundsBehavior: ListView.StopAtBounds
|
boundsBehavior: ListView.StopAtBounds
|
||||||
interactive: false
|
interactive: false
|
||||||
currentIndex: currentAccountIndex
|
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: Rectangle {
|
||||||
id: tableItem2
|
id: tableItem2
|
||||||
@@ -213,7 +212,7 @@ Rectangle {
|
|||||||
|
|
||||||
MoneroComponents.Label {
|
MoneroComponents.Label {
|
||||||
id: idLabel
|
id: idLabel
|
||||||
color: index === currentAccountIndex ? MoneroComponents.Style.defaultFontColor : "#757575"
|
color: index === appWindow.current_subaddress_account_table_index ? 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
|
||||||
@@ -280,9 +279,9 @@ Rectangle {
|
|||||||
onEntered: tableItem2.color = MoneroComponents.Style.titleBarButtonHoverColor
|
onEntered: tableItem2.color = MoneroComponents.Style.titleBarButtonHoverColor
|
||||||
onExited: tableItem2.color = "transparent"
|
onExited: tableItem2.color = "transparent"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
appWindow.currentWallet.switchSubaddressAccount(index);
|
if (index == subaddressAccountListView.currentIndex && selectAndSend)
|
||||||
if (selectAndSend)
|
|
||||||
appWindow.showPageRequest("Transfer");
|
appWindow.showPageRequest("Transfer");
|
||||||
|
subaddressAccountListView.currentIndex = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -321,9 +320,17 @@ 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: {
|
||||||
appWindow.onWalletUpdate();
|
if (selectAndSend) {
|
||||||
|
appWindow.showPageRequest("Transfer");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -344,9 +351,8 @@ Rectangle {
|
|||||||
id: addNewAccountCheckbox
|
id: addNewAccountCheckbox
|
||||||
visible: !selectAndSend
|
visible: !selectAndSend
|
||||||
border: false
|
border: false
|
||||||
uncheckedIcon: FontAwesome.plusCircle
|
checkedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
||||||
toggleOnClick: false
|
uncheckedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
||||||
fontAwesomeIcons: true
|
|
||||||
fontSize: 16
|
fontSize: 16
|
||||||
iconOnTheLeft: true
|
iconOnTheLeft: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -358,6 +364,7 @@ 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
|
||||||
appWindow.onWalletUpdate();
|
appWindow.onWalletUpdate();
|
||||||
}
|
}
|
||||||
inputDialog.onRejectedCallback = null;
|
inputDialog.onRejectedCallback = null;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ Rectangle {
|
|||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
anchors.margins: 20
|
anchors.margins: (isMobile)? 17 : 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -67,18 +67,21 @@ Rectangle {
|
|||||||
spacing: 0
|
spacing: 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
Text {
|
TextArea {
|
||||||
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
|
||||||
@@ -88,17 +91,20 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
TextArea {
|
||||||
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
|
||||||
@@ -139,7 +145,7 @@ Rectangle {
|
|||||||
ListView {
|
ListView {
|
||||||
id: addressBookListView
|
id: addressBookListView
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
anchors.fill: parent
|
||||||
clip: true
|
clip: true
|
||||||
boundsBehavior: ListView.StopAtBounds
|
boundsBehavior: ListView.StopAtBounds
|
||||||
interactive: false
|
interactive: false
|
||||||
@@ -278,9 +284,8 @@ Rectangle {
|
|||||||
MoneroComponents.CheckBox {
|
MoneroComponents.CheckBox {
|
||||||
id: addNewEntryCheckbox
|
id: addNewEntryCheckbox
|
||||||
border: false
|
border: false
|
||||||
uncheckedIcon: FontAwesome.plusCircle
|
checkedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
||||||
toggleOnClick: false
|
uncheckedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
||||||
fontAwesomeIcons: true
|
|
||||||
fontSize: 16
|
fontSize: 16
|
||||||
iconOnTheLeft: true
|
iconOnTheLeft: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -320,8 +325,8 @@ Rectangle {
|
|||||||
wrapMode: Text.WrapAnywhere
|
wrapMode: Text.WrapAnywhere
|
||||||
addressValidation: true
|
addressValidation: true
|
||||||
pasteButton: true
|
pasteButton: true
|
||||||
onTextChanged: {
|
onPaste: function(clipboardText) {
|
||||||
const parsed = walletManager.parse_uri_to_object(addressLine.text);
|
const parsed = walletManager.parse_uri_to_object(clipboardText);
|
||||||
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,6 +181,7 @@ 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
|
||||||
@@ -227,7 +228,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") + ":" + translationManager.emptyString
|
text: qsTr("Sort by") + ":"
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
@@ -250,6 +251,7 @@ Rectangle {
|
|||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
text: qsTr("Blockheight") + translationManager.emptyString
|
text: qsTr("Blockheight") + translationManager.emptyString
|
||||||
color: root.sortBy === "blockheight" ? MoneroComponents.Style.defaultFontColor : MoneroComponents.Style.dimmedFontColor
|
color: root.sortBy === "blockheight" ? MoneroComponents.Style.defaultFontColor : MoneroComponents.Style.dimmedFontColor
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
themeTransition: false
|
themeTransition: false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,6 +312,7 @@ Rectangle {
|
|||||||
text: qsTr("Date") + translationManager.emptyString
|
text: qsTr("Date") + translationManager.emptyString
|
||||||
color: root.sortBy === "timestamp" ? MoneroComponents.Style.defaultFontColor : MoneroComponents.Style.dimmedFontColor
|
color: root.sortBy === "timestamp" ? MoneroComponents.Style.defaultFontColor : MoneroComponents.Style.dimmedFontColor
|
||||||
themeTransition: false
|
themeTransition: false
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroEffects.ImageMask {
|
MoneroEffects.ImageMask {
|
||||||
@@ -369,6 +372,7 @@ Rectangle {
|
|||||||
text: qsTr("Amount") + translationManager.emptyString
|
text: qsTr("Amount") + translationManager.emptyString
|
||||||
color: root.sortBy === "amount" ? MoneroComponents.Style.defaultFontColor : MoneroComponents.Style.dimmedFontColor
|
color: root.sortBy === "amount" ? MoneroComponents.Style.defaultFontColor : MoneroComponents.Style.dimmedFontColor
|
||||||
themeTransition: false
|
themeTransition: false
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroEffects.ImageMask {
|
MoneroEffects.ImageMask {
|
||||||
@@ -446,7 +450,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") + ":" + translationManager.emptyString
|
text: qsTr("Page") + ":"
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
@@ -650,7 +654,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: displayAmount
|
text: _amount + " XMR"
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
@@ -869,7 +873,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 : dateTime
|
text: persistentSettings.historyHumanDates ? dateHuman : date + " " + time
|
||||||
|
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -881,7 +885,7 @@ Rectangle {
|
|||||||
onEntered: {
|
onEntered: {
|
||||||
parent.color = MoneroComponents.Style.orange
|
parent.color = MoneroComponents.Style.orange
|
||||||
if (persistentSettings.historyHumanDates) {
|
if (persistentSettings.historyHumanDates) {
|
||||||
parent.text = dateTime;
|
parent.text = date + " " + time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onExited: {
|
onExited: {
|
||||||
@@ -938,7 +942,7 @@ Rectangle {
|
|||||||
anchors.leftMargin: 10
|
anchors.leftMargin: 10
|
||||||
text: FontAwesome.productHunt
|
text: FontAwesome.productHunt
|
||||||
small: true
|
small: true
|
||||||
label.font.family: FontAwesome.fontFamilyBrands
|
label.font.family: FontAwesome.fontFamily
|
||||||
fontSize: 18
|
fontSize: 18
|
||||||
width: 36
|
width: 36
|
||||||
|
|
||||||
@@ -1196,7 +1200,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, dateTime, displayAmount, isout);
|
if(res[i].state === 'details') root.showTxDetails(hash, paymentId, destinations, subaddrAccount, subaddrIndex);
|
||||||
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;
|
||||||
@@ -1360,9 +1364,8 @@ Rectangle {
|
|||||||
// applying filters
|
// applying filters
|
||||||
root.txData = JSON.parse(JSON.stringify(root.txModelData)); // deepcopy
|
root.txData = JSON.parse(JSON.stringify(root.txModelData)); // deepcopy
|
||||||
|
|
||||||
const timezoneOffset = new Date().getTimezoneOffset() * 60;
|
var fromDate = fromDatePicker.currentDate.getTime() / 1000;
|
||||||
var fromDate = Math.floor(fromDatePicker.currentDate.getTime() / 86400000) * 86400 + timezoneOffset;
|
var toDate = toDatePicker.currentDate.getTime() / 1000;
|
||||||
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 +1482,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 displayAmount = amount;
|
var _amount = amount;
|
||||||
if(displayAmount === 0){
|
if(_amount === 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.
|
||||||
displayAmount = TxUtils.destinationsToAmount(destinations);
|
_amount = TxUtils.destinationsToAmount(destinations);
|
||||||
displayAmount = Number(displayAmount *1);
|
_amount = Number(_amount *1);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx_note = currentWallet.getUserNote(hash);
|
var tx_note = currentWallet.getUserNote(hash);
|
||||||
@@ -1502,14 +1505,15 @@ Rectangle {
|
|||||||
"i": i,
|
"i": i,
|
||||||
"isout": isout,
|
"isout": isout,
|
||||||
"amount": Number(amount),
|
"amount": Number(amount),
|
||||||
"displayAmount": displayAmount + " XMR",
|
"_amount": _amount,
|
||||||
"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,
|
||||||
@@ -1581,25 +1585,22 @@ Rectangle {
|
|||||||
elem.parent.text = txKey ? txKey : '-';
|
elem.parent.text = txKey ? txKey : '-';
|
||||||
elem.parent.state = 'ready';
|
elem.parent.state = 'ready';
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
toClipboard(elem.parent.text);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showTxDetails(hash, paymentId, destinations, subaddrAccount, subaddrIndex, dateTime, amount, isout) {
|
toClipboard(elem.parent.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showTxDetails(hash, paymentId, destinations, subaddrAccount, subaddrIndex){
|
||||||
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, integratedAddress, dateTime, amount);
|
informationPopup.content = buildTxDetailsString(hash, paymentId, tx_key, tx_note, destinations, rings, address, address_label);
|
||||||
informationPopup.onCloseCallback = null
|
informationPopup.onCloseCallback = null
|
||||||
informationPopup.open();
|
informationPopup.open();
|
||||||
});
|
});
|
||||||
@@ -1627,18 +1628,16 @@ 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, integratedAddress, dateTime, amount) {
|
function buildTxDetailsString(tx_id, paymentId, tx_key,tx_note, destinations, rings, address, address_label) {
|
||||||
var trStart = '<tr><td style="white-space: nowrap; padding-top:5px"><b>',
|
var trStart = '<tr><td width="85" style="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 : "")
|
||||||
+ (dateTime ? trStart + qsTr("Date") + ":" + trMiddle + dateTime + trEnd : "")
|
+ (address_label ? trStart + qsTr("Address label:") + trMiddle + address_label + 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: 20
|
anchors.margins: (isMobile)? 17 : 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
|
|
||||||
spacing: 30
|
spacing: 30
|
||||||
@@ -251,7 +251,7 @@ Rectangle {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
loadPage("Settings")
|
loadPage("Settings")
|
||||||
}
|
}
|
||||||
Layout.alignment: Qt.AlignCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
width: 135
|
width: 135
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ Rectangle {
|
|||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
anchors.margins: 20
|
anchors.margins: (isMobile)? 17 : 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ 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
|
||||||
@@ -66,7 +65,7 @@ Rectangle {
|
|||||||
/* main layout */
|
/* main layout */
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
anchors.margins: 20
|
anchors.margins: (isMobile)? 17 : 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -102,7 +101,7 @@ Rectangle {
|
|||||||
ListView {
|
ListView {
|
||||||
id: subaddressListView
|
id: subaddressListView
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
anchors.fill: parent
|
||||||
clip: true
|
clip: true
|
||||||
boundsBehavior: ListView.StopAtBounds
|
boundsBehavior: ListView.StopAtBounds
|
||||||
interactive: false
|
interactive: false
|
||||||
@@ -244,9 +243,8 @@ Rectangle {
|
|||||||
MoneroComponents.CheckBox {
|
MoneroComponents.CheckBox {
|
||||||
id: addNewAddressCheckbox
|
id: addNewAddressCheckbox
|
||||||
border: false
|
border: false
|
||||||
uncheckedIcon: FontAwesome.plusCircle
|
checkedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
||||||
toggleOnClick: false
|
uncheckedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
||||||
fontAwesomeIcons: true
|
|
||||||
fontSize: 16
|
fontSize: 16
|
||||||
iconOnTheLeft: true
|
iconOnTheLeft: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -258,7 +256,6 @@ Rectangle {
|
|||||||
inputDialog.onAcceptedCallback = function() {
|
inputDialog.onAcceptedCallback = function() {
|
||||||
appWindow.currentWallet.subaddress.addRow(appWindow.currentWallet.currentSubaddressAccount, inputDialog.inputText)
|
appWindow.currentWallet.subaddress.addRow(appWindow.currentWallet.currentSubaddressAccount, inputDialog.inputText)
|
||||||
current_subaddress_table_index = appWindow.currentWallet.numSubaddresses(appWindow.currentWallet.currentSubaddressAccount) - 1
|
current_subaddress_table_index = appWindow.currentWallet.numSubaddresses(appWindow.currentWallet.currentSubaddressAccount) - 1
|
||||||
subaddressListView.currentIndex = current_subaddress_table_index
|
|
||||||
}
|
}
|
||||||
inputDialog.onRejectedCallback = null;
|
inputDialog.onRejectedCallback = null;
|
||||||
inputDialog.open()
|
inputDialog.open()
|
||||||
@@ -311,20 +308,6 @@ 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: 20
|
anchors.margins: (isMobile)? 17 : 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: 2
|
columns: (isMobile) ? 1 : 2
|
||||||
columnSpacing: 32
|
columnSpacing: 32
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
@@ -368,7 +368,7 @@ Rectangle {
|
|||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
columnSpacing: 20
|
columnSpacing: 20
|
||||||
columns: 2
|
columns: (isMobile) ? 1 : 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: 2
|
columns: (isMobile) ? 1 : 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: 20
|
anchors.margins: (isMobile)? 17 : 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: descriptionLine.text.match(/^[0-9a-f]{64}$/i)
|
property bool warningLongPidDescription: false
|
||||||
|
|
||||||
Clipboard { id: clipboard }
|
Clipboard { id: clipboard }
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ Rectangle {
|
|||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: pageRoot
|
id: pageRoot
|
||||||
anchors.margins: 20
|
anchors.margins: (isMobile)? 17 : 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -143,16 +143,8 @@ 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: appWindow.walletMode < 2 ? 1 : 2
|
columns: (isMobile || !(appWindow.walletMode >= 2)) ? 1 : 2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
columnSpacing: 32
|
columnSpacing: 32
|
||||||
|
|
||||||
@@ -168,10 +160,6 @@ 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")
|
||||||
@@ -182,16 +170,8 @@ Rectangle {
|
|||||||
inlineButtonText: qsTr("All") + translationManager.emptyString
|
inlineButtonText: qsTr("All") + translationManager.emptyString
|
||||||
inlineButton.onClicked: amountLine.text = "(all)"
|
inlineButton.onClicked: amountLine.text = "(all)"
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
const match = amountLine.text.match(/^0+(\d.*)/);
|
if(amountLine.text.indexOf('.') === 0){
|
||||||
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;
|
amountLine.text = '0' + amountLine.text;
|
||||||
if (amountLine.text.length > 2) {
|
|
||||||
amountLine.cursorPosition = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,10 +203,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.2 fee)") ; column2: ""; priority: 1}
|
ListElement { column1: qsTr("Slow (x0.25 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 (x200 fee)") ; column2: ""; priority: 4 }
|
ListElement { column1: qsTr("Fastest (x41.5 fee)") ; column2: ""; priority: 4 }
|
||||||
}
|
}
|
||||||
|
|
||||||
StandardDropdown {
|
StandardDropdown {
|
||||||
@@ -269,15 +249,20 @@ Rectangle {
|
|||||||
appWindow.showPageRequest("AddressBook");
|
appWindow.showPageRequest("AddressBook");
|
||||||
}
|
}
|
||||||
pasteButton: true
|
pasteButton: true
|
||||||
onTextChanged: {
|
onPaste: function(clipboardText) {
|
||||||
const parsed = walletManager.parse_uri_to_object(text);
|
const parsed = walletManager.parse_uri_to_object(clipboardText);
|
||||||
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
|
||||||
@@ -338,12 +323,6 @@ 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
|
||||||
|
|
||||||
@@ -351,9 +330,8 @@ Rectangle {
|
|||||||
CheckBox {
|
CheckBox {
|
||||||
id: descriptionCheckbox
|
id: descriptionCheckbox
|
||||||
border: false
|
border: false
|
||||||
checkedIcon: FontAwesome.minusCircle
|
checkedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
||||||
uncheckedIcon: FontAwesome.plusCircle
|
uncheckedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
||||||
fontAwesomeIcons: true
|
|
||||||
fontSize: descriptionLine.labelFontSize
|
fontSize: descriptionLine.labelFontSize
|
||||||
iconOnTheLeft: true
|
iconOnTheLeft: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -374,14 +352,13 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
visible: paymentIdCheckbox.checked
|
visible: appWindow.persistentSettings.showPid || 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: FontAwesome.minusCircle
|
checkedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
||||||
uncheckedIcon: FontAwesome.plusCircle
|
uncheckedIcon: "qrc:///images/plus-in-circle-medium-white.png"
|
||||||
fontAwesomeIcons: true
|
|
||||||
fontSize: paymentIdLine.labelFontSize
|
fontSize: paymentIdLine.labelFontSize
|
||||||
iconOnTheLeft: true
|
iconOnTheLeft: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -398,7 +375,6 @@ 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
|
||||||
@@ -410,10 +386,8 @@ Rectangle {
|
|||||||
MoneroComponents.WarningBox {
|
MoneroComponents.WarningBox {
|
||||||
// @TODO: remove after pid removal hardfork
|
// @TODO: remove after pid removal hardfork
|
||||||
id: paymentIdWarningBox
|
id: paymentIdWarningBox
|
||||||
text: qsTr("Long payment IDs are obsolete. \
|
text: qsTr("You can enable transfers with payment ID on the settings page.") + translationManager.emptyString;
|
||||||
Long payment IDs were not encrypted on the blockchain and would harm your privacy. \
|
visible: !persistentSettings.showPid && (warningLongPidTransfer || warningLongPidDescription)
|
||||||
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 {
|
||||||
@@ -469,7 +443,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: 20
|
anchors.margins: (isMobile)? 17 : 20
|
||||||
anchors.topMargin: 32
|
anchors.topMargin: 32
|
||||||
spacing: 26
|
spacing: 26
|
||||||
enabled: !viewOnly || pageRoot.enabled
|
enabled: !viewOnly || pageRoot.enabled
|
||||||
@@ -488,7 +462,7 @@ Rectangle {
|
|||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
visible: persistentSettings.transferShowAdvanced && appWindow.walletMode >= 2
|
visible: persistentSettings.transferShowAdvanced && appWindow.walletMode >= 2
|
||||||
columns: 6
|
columns: (isMobile) ? 2 : 6
|
||||||
|
|
||||||
StandardButton {
|
StandardButton {
|
||||||
id: sweepUnmixableButton
|
id: sweepUnmixableButton
|
||||||
@@ -766,8 +740,7 @@ 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. Unless key images are imported, " +
|
root.sendButtonWarning = qsTr("Wallet is view-only and sends are not possible.") + translationManager.emptyString;
|
||||||
"the balance reflects only incoming but not outgoing transactions.") + translationManager.emptyString;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,11 +761,6 @@ 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: 20
|
anchors.margins: (isMobile)? 17 : 20
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ 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();
|
||||||
@@ -54,6 +56,8 @@ Item {
|
|||||||
timer.running = false
|
timer.running = false
|
||||||
root.enableTracking = false
|
root.enableTracking = false
|
||||||
trackingModel.clear()
|
trackingModel.clear()
|
||||||
|
|
||||||
|
appWindow.showMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
@@ -89,8 +93,9 @@ Item {
|
|||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.preferredHeight: 220
|
height: 220
|
||||||
Layout.fillWidth: true
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: tracker
|
id: tracker
|
||||||
@@ -158,7 +163,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){
|
||||||
@@ -253,7 +258,8 @@ Item {
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.preferredHeight: 40
|
Layout.preferredHeight: 40
|
||||||
Layout.fillWidth: true
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
width: (parent.width - qrImg.width) - (50)
|
width: (parent.width - qrImg.width) - (50)
|
||||||
@@ -265,7 +271,7 @@ Item {
|
|||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.bold: false
|
font.bold: false
|
||||||
color: "white"
|
color: "white"
|
||||||
text: qsTr("<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 12px;}</style>Currently selected address: ") + addressLabel + qsTr(" <a href='#'>(Change)</a>") + translationManager.emptyString
|
text: "<style type='text/css'>a {text-decoration: none; color: #FF6C3C; font-size: 12px;}</style>Currently selected address: " + addressLabel + " <a href='#'>(Change)</a>"
|
||||||
textFormat: Text.RichText
|
textFormat: Text.RichText
|
||||||
themeTransition: false
|
themeTransition: false
|
||||||
|
|
||||||
@@ -446,7 +452,7 @@ Item {
|
|||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
font.bold: false
|
font.bold: false
|
||||||
color: "white"
|
color: "white"
|
||||||
text: qsTr("Amount to receive") + " (XMR)" + translationManager.emptyString
|
text: qsTr("Amount to receive") + " (XMR)"
|
||||||
themeTransition: false
|
themeTransition: false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,7 +461,7 @@ Item {
|
|||||||
width: 220
|
width: 220
|
||||||
source: "qrc:///images/merchant/input_box.png"
|
source: "qrc:///images/merchant/input_box.png"
|
||||||
|
|
||||||
MoneroComponents.Input {
|
TextField {
|
||||||
id: amountToReceive
|
id: amountToReceive
|
||||||
topPadding: 0
|
topPadding: 0
|
||||||
leftPadding: 10
|
leftPadding: 10
|
||||||
@@ -518,7 +524,8 @@ Item {
|
|||||||
Item {
|
Item {
|
||||||
Layout.topMargin: 32
|
Layout.topMargin: 32
|
||||||
Layout.preferredHeight: 40
|
Layout.preferredHeight: 40
|
||||||
Layout.fillWidth: true
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 16
|
spacing: 16
|
||||||
@@ -623,7 +630,7 @@ Item {
|
|||||||
in_txpool = true;
|
in_txpool = true;
|
||||||
} else {
|
} else {
|
||||||
if (blockchainHeight == null)
|
if (blockchainHeight == null)
|
||||||
blockchainHeight = walletManager.blockchainHeight()
|
blockchainHeight = appWindow.currentWallet.blockChainHeight()
|
||||||
confirmations = blockchainHeight - blockHeight - 1
|
confirmations = blockchainHeight - blockHeight - 1
|
||||||
displayAmount = model.data(idx, TransactionHistoryModel.TransactionDisplayAmountRole);
|
displayAmount = model.data(idx, TransactionHistoryModel.TransactionDisplayAmountRole);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,25 +4,19 @@ import QtGraphicalEffects 1.0
|
|||||||
|
|
||||||
import "../../components" as MoneroComponents
|
import "../../components" as MoneroComponents
|
||||||
|
|
||||||
Item {
|
RowLayout {
|
||||||
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;
|
||||||
|
|
||||||
width: checkBoxLayout.width
|
|
||||||
height: 22
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: checkBoxLayout
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
Item {
|
|
||||||
height: root.height
|
|
||||||
width: root.height
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: checkbox
|
id: checkbox
|
||||||
anchors.fill: parent
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
implicitHeight: 22
|
||||||
|
width: 22
|
||||||
radius: 5
|
radius: 5
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
@@ -32,6 +26,27 @@ Item {
|
|||||||
source: "qrc:///images/uncheckedIcon.png"
|
source: "qrc:///images/uncheckedIcon.png"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoneroComponents.TextPlain {
|
||||||
|
id: content
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.bold: false
|
||||||
|
color: "white"
|
||||||
|
text: ""
|
||||||
|
themeTransition: false
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
root.checked = !root.checked;
|
||||||
|
changed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DropShadow {
|
DropShadow {
|
||||||
anchors.fill: source
|
anchors.fill: source
|
||||||
cached: true
|
cached: true
|
||||||
@@ -43,24 +58,4 @@ Item {
|
|||||||
smooth: true
|
smooth: true
|
||||||
source: checkbox
|
source: checkbox
|
||||||
}
|
}
|
||||||
}
|
|
||||||
MoneroComponents.TextPlain {
|
|
||||||
id: content
|
|
||||||
font.pixelSize: 14
|
|
||||||
font.bold: false
|
|
||||||
color: "white"
|
|
||||||
text: ""
|
|
||||||
themeTransition: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
root.checked = !root.checked;
|
|
||||||
changed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ Rectangle {
|
|||||||
property bool showCloseButton: true
|
property bool showCloseButton: true
|
||||||
|
|
||||||
height: {
|
height: {
|
||||||
if(!persistentSettings.customDecorations) return 0;
|
if(!persistentSettings.customDecorations || isMobile) return 0;
|
||||||
return 50;
|
return 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,9 @@ 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(appWindow.width < 890){
|
if(isMobile){
|
||||||
|
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: 20
|
anchors.margins: (isMobile)? 17 : 20
|
||||||
anchors.topMargin: 0
|
anchors.topMargin: 0
|
||||||
spacing: 30
|
spacing: 30
|
||||||
|
|
||||||
|
|||||||
@@ -47,11 +47,12 @@ 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: 20
|
anchors.margins: (isMobile)? 17 : 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)
|
||||||
@@ -59,6 +60,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.CheckBox {
|
MoneroComponents.CheckBox {
|
||||||
|
visible: !isMobile
|
||||||
id: hideBalanceCheckBox
|
id: hideBalanceCheckBox
|
||||||
checked: persistentSettings.hideBalance
|
checked: persistentSettings.hideBalance
|
||||||
onClicked: {
|
onClicked: {
|
||||||
@@ -68,11 +70,20 @@ 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;
|
||||||
@@ -80,6 +91,7 @@ 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
|
||||||
@@ -93,8 +105,7 @@ Rectangle {
|
|||||||
Layout.leftMargin: 42
|
Layout.leftMargin: 42
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
Text {
|
MoneroComponents.TextBlock {
|
||||||
color: MoneroComponents.Style.defaultFontColor
|
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: {
|
text: {
|
||||||
@@ -143,12 +154,6 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMoved: persistentSettings.lockOnUserInActivityInterval = userInactivitySlider.value;
|
onMoved: persistentSettings.lockOnUserInActivityInterval = userInactivitySlider.value;
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,6 +267,14 @@ 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: 20
|
anchors.margins: (isMobile)? 17 : 20
|
||||||
anchors.topMargin: 0
|
anchors.topMargin: 0
|
||||||
spacing: 10
|
spacing: 10
|
||||||
|
|
||||||
@@ -216,11 +216,7 @@ Rectangle {
|
|||||||
onAccepted: {
|
onAccepted: {
|
||||||
if(text.length > 0) {
|
if(text.length > 0) {
|
||||||
consoleArea.logCommand(">>> " + text)
|
consoleArea.logCommand(">>> " + text)
|
||||||
daemonManager.sendCommandAsync(text.split(" "), currentWallet.nettype, function(result) {
|
daemonManager.sendCommand(text, currentWallet.nettype);
|
||||||
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: 20
|
anchors.margins: (isMobile)? 17 : 20
|
||||||
anchors.topMargin: 0
|
anchors.topMargin: 0
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -96,13 +96,17 @@ Rectangle{
|
|||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
MoneroComponents.Label {
|
MoneroEffects.ImageMask {
|
||||||
fontSize: 32
|
height: 27
|
||||||
text: FontAwesome.home
|
width: 27
|
||||||
fontFamily: FontAwesome.fontFamilySolid
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.centerIn: parent
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
fontColor: MoneroComponents.Style.defaultFontColor
|
fontAwesomeFallbackIcon: FontAwesome.shield
|
||||||
styleName: "Solid"
|
fontAwesomeFallbackSize: 26
|
||||||
|
image: "qrc:///images/settings_local.svg"
|
||||||
|
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
opacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +123,7 @@ Rectangle{
|
|||||||
text: qsTr("Local node") + translationManager.emptyString
|
text: qsTr("Local node") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
TextArea {
|
||||||
id: localNodeArea
|
id: localNodeArea
|
||||||
anchors.top: localNodeHeader.bottom
|
anchors.top: localNodeHeader.bottom
|
||||||
anchors.topMargin: 4
|
anchors.topMargin: 4
|
||||||
@@ -129,11 +133,14 @@ 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
|
||||||
@@ -195,13 +202,16 @@ Rectangle{
|
|||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
MoneroComponents.Label {
|
MoneroEffects.ImageMask {
|
||||||
fontSize: 28
|
height: 29
|
||||||
text: FontAwesome.cloud
|
width: 22
|
||||||
fontFamily: FontAwesome.fontFamilySolid
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
styleName: "Solid"
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.centerIn: parent
|
fontAwesomeFallbackIcon: FontAwesome.cloudDownload
|
||||||
fontColor: MoneroComponents.Style.defaultFontColor
|
fontAwesomeFallbackSize: 26
|
||||||
|
image: "qrc:///images/settings_remote.svg"
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
opacity: MoneroComponents.Style.blackTheme ? 1.0 : 0.8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,7 +228,7 @@ Rectangle{
|
|||||||
text: qsTr("Remote node") + translationManager.emptyString
|
text: qsTr("Remote node") + translationManager.emptyString
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
TextArea {
|
||||||
id: remoteNodeArea
|
id: remoteNodeArea
|
||||||
anchors.top: remoteNodeHeader.bottom
|
anchors.top: remoteNodeHeader.bottom
|
||||||
anchors.topMargin: 4
|
anchors.topMargin: 4
|
||||||
@@ -227,12 +237,16 @@ 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
|
||||||
@@ -246,6 +260,7 @@ Rectangle{
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
persistentSettings.useRemoteNode = true;
|
||||||
appWindow.connectRemoteNode();
|
appWindow.connectRemoteNode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,7 +285,7 @@ Rectangle{
|
|||||||
spacing: 20
|
spacing: 20
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
visible: persistentSettings.useRemoteNode
|
visible: !isMobile && persistentSettings.useRemoteNode
|
||||||
|
|
||||||
MoneroComponents.WarningBox {
|
MoneroComponents.WarningBox {
|
||||||
Layout.topMargin: 26
|
Layout.topMargin: 26
|
||||||
@@ -302,7 +317,7 @@ Rectangle{
|
|||||||
}
|
}
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
columns: 2
|
columns: (isMobile) ? 1 : 2
|
||||||
columnSpacing: 32
|
columnSpacing: 32
|
||||||
|
|
||||||
MoneroComponents.LineEdit {
|
MoneroComponents.LineEdit {
|
||||||
@@ -362,11 +377,11 @@ Rectangle{
|
|||||||
id: localNodeLayout
|
id: localNodeLayout
|
||||||
spacing: 20
|
spacing: 20
|
||||||
Layout.topMargin: 40
|
Layout.topMargin: 40
|
||||||
visible: !persistentSettings.useRemoteNode
|
visible: !isMobile && !persistentSettings.useRemoteNode
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
MoneroComponents.StandardButton {
|
||||||
small: true
|
small: true
|
||||||
text: (appWindow.daemonRunning ? qsTr("Stop daemon") : qsTr("Start daemon")) + translationManager.emptyString
|
text: (appWindow.daemonRunning ? qsTr("Stop local node") : qsTr("Start daemon")) + translationManager.emptyString
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (appWindow.daemonRunning) {
|
if (appWindow.daemonRunning) {
|
||||||
appWindow.stopDaemon();
|
appWindow.stopDaemon();
|
||||||
@@ -388,7 +403,6 @@ 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;
|
||||||
@@ -421,7 +435,7 @@ Rectangle{
|
|||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
visible: !persistentSettings.useRemoteNode
|
visible: !isMobile && !persistentSettings.useRemoteNode
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -443,11 +457,7 @@ Rectangle{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
if (daemonAddrText == "auto") {
|
|
||||||
persistentSettings.bootstrapNodeAddress = daemonAddrText;
|
|
||||||
} else {
|
|
||||||
persistentSettings.bootstrapNodeAddress = daemonAddrText ? bootstrapNodeEdit.getAddress() : "";
|
persistentSettings.bootstrapNodeAddress = daemonAddrText ? bootstrapNodeEdit.getAddress() : "";
|
||||||
}
|
|
||||||
console.log("setting bootstrap node to " + persistentSettings.bootstrapNodeAddress)
|
console.log("setting bootstrap node to " + persistentSettings.bootstrapNodeAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,29 +45,112 @@ 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: 20
|
anchors.margins: (isMobile)? 17 : 20
|
||||||
anchors.topMargin: 0
|
anchors.topMargin: 0
|
||||||
spacing: 8
|
spacing: 0
|
||||||
|
|
||||||
MoneroComponents.SettingsListItem {
|
Rectangle {
|
||||||
buttonText: qsTr("Close wallet") + translationManager.emptyString
|
// divider
|
||||||
description: qsTr("Logs out of this wallet.") + translationManager.emptyString
|
Layout.preferredHeight: 1
|
||||||
title: qsTr("Close this wallet") + translationManager.emptyString
|
Layout.fillWidth: true
|
||||||
|
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("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: {
|
onClicked: {
|
||||||
middlePanel.addressBookView.clearFields();
|
middlePanel.addressBookView.clearFields();
|
||||||
middlePanel.transferView.clearFields();
|
middlePanel.transferView.clearFields();
|
||||||
middlePanel.receiveView.clearFields();
|
middlePanel.receiveView.clearFields();
|
||||||
appWindow.showWizard();
|
appWindow.showWizard();
|
||||||
}
|
}
|
||||||
|
width: 135
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.SettingsListItem {
|
Rectangle {
|
||||||
buttonText: qsTr("Create wallet") + translationManager.emptyString
|
// divider
|
||||||
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.preferredHeight: 1
|
||||||
title: qsTr("Create a view-only wallet") + translationManager.emptyString
|
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
|
||||||
visible: !appWindow.viewOnly
|
visible: !appWindow.viewOnly
|
||||||
|
|
||||||
|
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("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 {
|
||||||
|
small: true
|
||||||
|
text: qsTr("Create wallet") + translationManager.emptyString
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var newPath = currentWallet.path + "_viewonly";
|
var newPath = currentWallet.path + "_viewonly";
|
||||||
if (currentWallet.createViewOnly(newPath, appWindow.walletPassword)) {
|
if (currentWallet.createViewOnly(newPath, appWindow.walletPassword)) {
|
||||||
@@ -82,24 +165,111 @@ Rectangle {
|
|||||||
informationPopup.open()
|
informationPopup.open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
width: 135
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.SettingsListItem {
|
Rectangle {
|
||||||
buttonText: qsTr("Show seed") + translationManager.emptyString
|
// divider
|
||||||
description: qsTr("Store this information safely to recover your wallet in the future.") + translationManager.emptyString
|
visible: !appWindow.viewOnly
|
||||||
title: qsTr("Show seed & keys") + translationManager.emptyString
|
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: {
|
onClicked: {
|
||||||
Utils.showSeedPage();
|
Utils.showSeedPage();
|
||||||
}
|
}
|
||||||
|
width: 135
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.SettingsListItem {
|
Rectangle {
|
||||||
buttonText: qsTr("Rescan") + translationManager.emptyString
|
// divider
|
||||||
description: qsTr("Use this feature if you think the shown balance is not accurate.") + translationManager.emptyString
|
Layout.preferredHeight: 1
|
||||||
title: qsTr("Rescan wallet balance") + translationManager.emptyString
|
Layout.fillWidth: true
|
||||||
visible: appWindow.walletMode >= 2
|
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: {
|
onClicked: {
|
||||||
if (!currentWallet.rescanSpent()) {
|
if (!currentWallet.rescanSpent()) {
|
||||||
console.error("Error: ", currentWallet.errorString);
|
console.error("Error: ", currentWallet.errorString);
|
||||||
@@ -116,13 +286,56 @@ Rectangle {
|
|||||||
informationPopup.open();
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
MoneroComponents.SettingsListItem {
|
GridLayout {
|
||||||
buttonText: qsTr("Change password") + translationManager.emptyString
|
Layout.fillWidth: true
|
||||||
description: qsTr("Change the password of your wallet.") + translationManager.emptyString
|
Layout.preferredHeight: childrenRect.height
|
||||||
title: qsTr("Change wallet password") + translationManager.emptyString
|
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: {
|
onClicked: {
|
||||||
passwordDialog.onAcceptedCallback = function() {
|
passwordDialog.onAcceptedCallback = function() {
|
||||||
if(appWindow.walletPassword === passwordDialog.password){
|
if(appWindow.walletPassword === passwordDialog.password){
|
||||||
@@ -139,6 +352,8 @@ Rectangle {
|
|||||||
passwordDialog.onRejectedCallback = null;
|
passwordDialog.onRejectedCallback = null;
|
||||||
passwordDialog.open()
|
passwordDialog.open()
|
||||||
}
|
}
|
||||||
|
width: 135
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
24
qml.qrc
@@ -7,8 +7,11 @@
|
|||||||
<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>
|
||||||
@@ -18,8 +21,6 @@
|
|||||||
<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>
|
||||||
@@ -106,14 +107,13 @@
|
|||||||
<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-black.png</file>
|
<file>images/card-background.png</file>
|
||||||
<file>images/card-background-black@2x.png</file>
|
<file>images/card-background@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,18 +167,20 @@
|
|||||||
<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/fa-brands-400.ttf</file>
|
<file>fonts/FontAwesome/fontawesome-webfont.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>
|
||||||
@@ -234,6 +236,7 @@
|
|||||||
<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>
|
||||||
@@ -241,6 +244,7 @@
|
|||||||
<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 = 120;
|
static const int DAEMON_START_TIMEOUT_SECONDS = 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 noSync /* = false*/)
|
bool DaemonManager::start(const QString &flags, NetworkType::Type nettype, const QString &dataDir, const QString &bootstrapNodeAddress)
|
||||||
{
|
{
|
||||||
// prepare command line arguments and pass to monerod
|
// prepare command line arguments and pass to monerod
|
||||||
QStringList arguments;
|
QStringList arguments;
|
||||||
@@ -99,10 +99,6 @@ 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
|
||||||
@@ -135,13 +131,11 @@ bool DaemonManager::start(const QString &flags, NetworkType::Type nettype, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start start watcher
|
// Start start watcher
|
||||||
m_scheduler.run([this, nettype, noSync] {
|
m_scheduler.run([this, nettype] {
|
||||||
if (startWatcher(nettype)) {
|
if (startWatcher(nettype))
|
||||||
emit daemonStarted();
|
emit daemonStarted();
|
||||||
m_noSync = noSync;
|
else
|
||||||
} else {
|
|
||||||
emit daemonStartFailure();
|
emit daemonStartFailure();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -150,7 +144,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
|
||||||
@@ -240,27 +234,26 @@ void DaemonManager::printError()
|
|||||||
bool DaemonManager::running(NetworkType::Type nettype) const
|
bool DaemonManager::running(NetworkType::Type nettype) const
|
||||||
{
|
{
|
||||||
QString status;
|
QString status;
|
||||||
sendCommand({"sync_info"}, nettype, status);
|
sendCommand("status", nettype, status);
|
||||||
qDebug() << status;
|
qDebug() << status;
|
||||||
return status.contains("Height:");
|
// `./monerod status` returns BUSY when syncing.
|
||||||
|
// Treat busy as connected, until fixed upstream.
|
||||||
|
if (status.contains("Height:") || status.contains("BUSY") ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
bool DaemonManager::sendCommand(const QString &cmd, NetworkType::Type nettype) const
|
||||||
bool DaemonManager::noSync() const noexcept
|
|
||||||
{
|
{
|
||||||
return m_noSync;
|
QString message;
|
||||||
|
return sendCommand(cmd, nettype, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonManager::runningAsync(NetworkType::Type nettype, const QJSValue& callback) const
|
bool DaemonManager::sendCommand(const QString &cmd, NetworkType::Type nettype, QString &message) 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(cmd);
|
QStringList external_cmd;
|
||||||
|
external_cmd << cmd;
|
||||||
|
|
||||||
// Add network type flag if needed
|
// Add network type flag if needed
|
||||||
if (nettype == NetworkType::TESTNET)
|
if (nettype == NetworkType::TESTNET)
|
||||||
@@ -279,14 +272,6 @@ bool DaemonManager::sendCommand(const QStringList &cmd, NetworkType::Type nettyp
|
|||||||
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,21 +44,19 @@ 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 = "", bool noSync = false);
|
Q_INVOKABLE bool start(const QString &flags, NetworkType::Type nettype, const QString &dataDir = "", const QString &bootstrapNodeAddress = "");
|
||||||
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 void runningAsync(NetworkType::Type nettype, const QJSValue& callback) const;
|
Q_INVOKABLE bool running(NetworkType::Type nettype) 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 void sendCommandAsync(const QStringList &cmd, NetworkType::Type nettype, const QJSValue& callback) const;
|
Q_INVOKABLE bool sendCommand(const QString &cmd, NetworkType::Type nettype) 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 running(NetworkType::Type nettype) const;
|
bool sendCommand(const QString &cmd, NetworkType::Type nettype, QString &message) 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:
|
||||||
@@ -83,9 +81,8 @@ 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;
|
|
||||||
|
|
||||||
mutable FutureScheduler m_scheduler;
|
FutureScheduler m_scheduler;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DAEMONMANAGER_H
|
#endif // DAEMONMANAGER_H
|
||||||
|
|||||||
@@ -32,13 +32,10 @@
|
|||||||
|
|
||||||
#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);
|
||||||
@@ -56,18 +53,13 @@ TransactionInfo *TransactionHistory::transaction(int index)
|
|||||||
|
|
||||||
QList<TransactionInfo *> TransactionHistory::getAll(quint32 accountIndex) const
|
QList<TransactionInfo *> TransactionHistory::getAll(quint32 accountIndex) const
|
||||||
{
|
{
|
||||||
QDateTime firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block
|
|
||||||
QDateTime lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
|
|
||||||
|
|
||||||
emit refreshStarted();
|
|
||||||
|
|
||||||
{
|
|
||||||
QWriteLocker locker(&m_tinfoLock);
|
|
||||||
|
|
||||||
// XXX this invalidates previously saved history that might be used by model
|
// XXX this invalidates previously saved history that might be used by model
|
||||||
|
emit refreshStarted();
|
||||||
qDeleteAll(m_tinfo);
|
qDeleteAll(m_tinfo);
|
||||||
m_tinfo.clear();
|
m_tinfo.clear();
|
||||||
|
|
||||||
|
QDateTime firstDateTime = QDateTime(QDate(2014, 4, 18)); // the genesis block
|
||||||
|
QDateTime lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
|
||||||
quint64 lastTxHeight = 0;
|
quint64 lastTxHeight = 0;
|
||||||
m_locked = false;
|
m_locked = false;
|
||||||
m_minutesToUnlock = 0;
|
m_minutesToUnlock = 0;
|
||||||
@@ -96,8 +88,6 @@ QList<TransactionInfo *> TransactionHistory::getAll(quint32 accountIndex) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
emit refreshFinished();
|
emit refreshFinished();
|
||||||
|
|
||||||
if (m_firstDateTime != firstDateTime) {
|
if (m_firstDateTime != firstDateTime) {
|
||||||
@@ -122,8 +112,6 @@ 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,7 +31,6 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QReadWriteLock>
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
namespace Monero {
|
namespace Monero {
|
||||||
@@ -77,7 +76,6 @@ 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(size_t index) const
|
quint64 UnsignedTransaction::amount(int 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(size_t index) const
|
|||||||
return arr[index];
|
return arr[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 UnsignedTransaction::fee(size_t index) const
|
quint64 UnsignedTransaction::fee(int 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(size_t index) const
|
|||||||
return arr[index];
|
return arr[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 UnsignedTransaction::mixin(size_t index) const
|
quint64 UnsignedTransaction::mixin(int 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(size_t index) const;
|
Q_INVOKABLE quint64 amount(int index) const;
|
||||||
Q_INVOKABLE quint64 fee(size_t index) const;
|
Q_INVOKABLE quint64 fee(int index) const;
|
||||||
Q_INVOKABLE quint64 mixin(size_t index) const;
|
Q_INVOKABLE quint64 mixin(int index) const;
|
||||||
QStringList recipientAddress() const;
|
QStringList recipientAddress() const;
|
||||||
QStringList paymentId() const;
|
QStringList paymentId() const;
|
||||||
quint64 txCount() const;
|
quint64 txCount() const;
|
||||||
|
|||||||
@@ -55,8 +55,6 @@ 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
|
||||||
@@ -208,7 +206,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, bool trustedDaemon, quint64 upperTransactionLimit, bool isRecovering, bool isRecoveringFromDevice, quint64 restoreHeight)
|
bool Wallet::init(const QString &daemonAddress, quint64 upperTransactionLimit, bool isRecovering, bool isRecoveringFromDevice, quint64 restoreHeight)
|
||||||
{
|
{
|
||||||
qDebug() << "init non async";
|
qDebug() << "init non async";
|
||||||
if (isRecovering){
|
if (isRecovering){
|
||||||
@@ -223,7 +221,6 @@ bool Wallet::init(const QString &daemonAddress, bool trustedDaemon, quint64 uppe
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +231,7 @@ void Wallet::setDaemonLogin(const QString &daemonUsername, const QString &daemon
|
|||||||
m_daemonPassword = daemonPassword;
|
m_daemonPassword = daemonPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wallet::initAsync(const QString &daemonAddress, bool trustedDaemon, quint64 upperTransactionLimit, bool isRecovering, bool isRecoveringFromDevice, quint64 restoreHeight)
|
void Wallet::initAsync(const QString &daemonAddress, 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
|
||||||
@@ -243,28 +240,19 @@ void Wallet::initAsync(const QString &daemonAddress, bool trustedDaemon, quint64
|
|||||||
emit connectionStatusChanged(m_connectionStatus);
|
emit connectionStatusChanged(m_connectionStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_scheduler.run([this, daemonAddress, trustedDaemon, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight] {
|
m_scheduler.run([this, daemonAddress, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight] {
|
||||||
bool success = init(daemonAddress, trustedDaemon, upperTransactionLimit, isRecovering, isRecoveringFromDevice, restoreHeight);
|
bool success = init(daemonAddress, 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
|
||||||
{
|
{
|
||||||
@@ -318,13 +306,8 @@ 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)
|
||||||
@@ -352,13 +335,6 @@ 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()
|
||||||
{
|
{
|
||||||
@@ -647,15 +623,6 @@ 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());
|
||||||
@@ -970,16 +937,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);
|
||||||
@@ -989,7 +956,6 @@ 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 NOTIFY currentSubaddressAccountChanged)
|
Q_PROPERTY(quint32 currentSubaddressAccount READ currentSubaddressAccount)
|
||||||
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,8 +144,11 @@ 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, bool trustedDaemon = false, quint64 upperTransactionLimit = 0, bool isRecovering = false, bool isRecoveringFromDevice = false, quint64 restoreHeight = 0);
|
Q_INVOKABLE void initAsync(const QString &daemonAddress, 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 = "");
|
||||||
@@ -176,11 +179,6 @@ 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;
|
||||||
@@ -290,10 +288,6 @@ 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;
|
||||||
@@ -359,13 +353,11 @@ 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);
|
||||||
@@ -382,9 +374,6 @@ 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;
|
||||||
@@ -396,8 +385,6 @@ 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;
|
||||||
@@ -409,6 +396,8 @@ 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 daemon_address.isEmpty() ? false : Monero::Utils::isAddressLocal(daemon_address.toStdString());
|
return 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 &) const
|
int AddressBookModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return m_addressBook->count();
|
return m_addressBook->count();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ void SubaddressAccountModel::endReset(){
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SubaddressAccountModel::rowCount(const QModelIndex &) const
|
int SubaddressAccountModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return m_subaddressAccount->count();
|
return m_subaddressAccount->count();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ void SubaddressModel::endReset(){
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SubaddressModel::rowCount(const QModelIndex &) const
|
int SubaddressModel::rowCount(const QModelIndex &parent) 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)
|
QPair<bool, QFuture<QJSValueList>> FutureScheduler::run(std::function<QJSValueList() noexcept> function, const QJSValue &callback) noexcept
|
||||||
{
|
{
|
||||||
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);
|
QPair<bool, QFuture<QJSValueList>> run(std::function<QJSValueList() noexcept> function, const QJSValue &callback) noexcept;
|
||||||
|
|
||||||
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 "libwalletqt/WalletManager.h"
|
#include "src/libwalletqt/WalletManager.h"
|
||||||
#include "NetworkType.h"
|
#include "src/NetworkType.h"
|
||||||
#include "qt/utils.h"
|
#include "src/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 "libwalletqt/WalletManager.h"
|
#include "src/libwalletqt/WalletManager.h"
|
||||||
#include "NetworkType.h"
|
#include "src/NetworkType.h"
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
|
|
||||||
class WalletKeysFiles
|
class WalletKeysFiles
|
||||||
|
|||||||