Wizard redesign
|
@ -435,6 +435,7 @@ Rectangle {
|
||||||
|
|
||||||
MoneroComponents.MenuButton {
|
MoneroComponents.MenuButton {
|
||||||
id: merchantButton
|
id: merchantButton
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
text: qsTr("Merchant") + translationManager.emptyString
|
text: qsTr("Merchant") + translationManager.emptyString
|
||||||
|
@ -449,7 +450,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: merchantButton.present
|
visible: merchantButton.present && appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
|
@ -484,6 +485,7 @@ Rectangle {
|
||||||
// ------------- Advanced tab ---------------
|
// ------------- Advanced tab ---------------
|
||||||
MoneroComponents.MenuButton {
|
MoneroComponents.MenuButton {
|
||||||
id: advancedButton
|
id: advancedButton
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
text: qsTr("Advanced") + translationManager.emptyString
|
text: qsTr("Advanced") + translationManager.emptyString
|
||||||
|
@ -494,8 +496,9 @@ Rectangle {
|
||||||
parent.previousButton = advancedButton
|
parent.previousButton = advancedButton
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: advancedButton.present
|
visible: advancedButton.present && appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
|
@ -506,7 +509,7 @@ Rectangle {
|
||||||
// ------------- Mining tab ---------------
|
// ------------- Mining tab ---------------
|
||||||
MoneroComponents.MenuButton {
|
MoneroComponents.MenuButton {
|
||||||
id: miningButton
|
id: miningButton
|
||||||
visible: !isAndroid && !isIOS
|
visible: !isAndroid && !isIOS && appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
text: qsTr("Mining") + translationManager.emptyString
|
text: qsTr("Mining") + translationManager.emptyString
|
||||||
|
@ -521,7 +524,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: miningButton.present
|
visible: miningButton.present && appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
|
@ -531,6 +534,7 @@ Rectangle {
|
||||||
// ------------- TxKey tab ---------------
|
// ------------- TxKey tab ---------------
|
||||||
MoneroComponents.MenuButton {
|
MoneroComponents.MenuButton {
|
||||||
id: txkeyButton
|
id: txkeyButton
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
text: qsTr("Prove/check") + translationManager.emptyString
|
text: qsTr("Prove/check") + translationManager.emptyString
|
||||||
|
@ -544,7 +548,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: txkeyButton.present
|
visible: txkeyButton.present && appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
|
@ -554,6 +558,7 @@ Rectangle {
|
||||||
// ------------- Shared RingDB tab ---------------
|
// ------------- Shared RingDB tab ---------------
|
||||||
MoneroComponents.MenuButton {
|
MoneroComponents.MenuButton {
|
||||||
id: sharedringdbButton
|
id: sharedringdbButton
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
text: qsTr("Shared RingDB") + translationManager.emptyString
|
text: qsTr("Shared RingDB") + translationManager.emptyString
|
||||||
|
@ -567,7 +572,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: sharedringdbButton.present
|
visible: sharedringdbButton.present && appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
|
@ -579,6 +584,7 @@ Rectangle {
|
||||||
// ------------- Sign/verify tab ---------------
|
// ------------- Sign/verify tab ---------------
|
||||||
MoneroComponents.MenuButton {
|
MoneroComponents.MenuButton {
|
||||||
id: signButton
|
id: signButton
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
text: qsTr("Sign/verify") + translationManager.emptyString
|
text: qsTr("Sign/verify") + translationManager.emptyString
|
||||||
|
@ -592,7 +598,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: signButton.present
|
visible: signButton.present && appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
|
@ -624,6 +630,7 @@ Rectangle {
|
||||||
// ------------- Sign/verify tab ---------------
|
// ------------- Sign/verify tab ---------------
|
||||||
MoneroComponents.MenuButton {
|
MoneroComponents.MenuButton {
|
||||||
id: keysButton
|
id: keysButton
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
text: qsTr("Seed & Keys") + translationManager.emptyString
|
text: qsTr("Seed & Keys") + translationManager.emptyString
|
||||||
|
@ -637,7 +644,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: settingsButton.present
|
visible: settingsButton.present && appWindow.walletMode >= 2
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
|
|
|
@ -33,14 +33,20 @@ import "../components" as MoneroComponents
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: inlineButton
|
id: inlineButton
|
||||||
height: rect.height * scaleRatio
|
height: parent.height
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
|
property bool small: false
|
||||||
property string shadowPressedColor: "#B32D00"
|
property string shadowPressedColor: "#B32D00"
|
||||||
property string shadowReleasedColor: "#FF4304"
|
property string shadowReleasedColor: "#FF4304"
|
||||||
property string pressedColor: "#FF4304"
|
property string pressedColor: "#FF4304"
|
||||||
property string releasedColor: "#FF6C3C"
|
property string releasedColor: "#FF6C3C"
|
||||||
property string icon: ""
|
property string icon: ""
|
||||||
property string textColor: "#FFFFFF"
|
property string textColor: "#FFFFFF"
|
||||||
property int fontSize: 12 * scaleRatio
|
property int fontSize: small ? 14 * scaleRatio : 16 * scaleRatio
|
||||||
|
property int rectHeight: small ? 24 * scaleRatio : 28 * scaleRatio
|
||||||
|
property int rectHMargin: small ? 16 * scaleRatio : 22 * scaleRatio
|
||||||
property alias text: inlineText.text
|
property alias text: inlineText.text
|
||||||
property alias buttonColor: rect.color
|
property alias buttonColor: rect.color
|
||||||
signal clicked()
|
signal clicked()
|
||||||
|
@ -59,14 +65,14 @@ Item {
|
||||||
width: inlineText.text ? (inlineText.width + 22) * scaleRatio : inlineButton.icon ? (inlineImage.width + 16) * scaleRatio : rect.height
|
width: inlineText.text ? (inlineText.width + 22) * scaleRatio : inlineButton.icon ? (inlineImage.width + 16) * scaleRatio : rect.height
|
||||||
radius: 4
|
radius: 4
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: inlineText
|
id: inlineText
|
||||||
font.family: MoneroComponents.Style.fontBold.name
|
font.family: MoneroComponents.Style.fontBold.name
|
||||||
font.bold: true
|
font.bold: true
|
||||||
font.pixelSize: 16 * scaleRatio
|
font.pixelSize: inlineButton.fontSize
|
||||||
color: "black"
|
color: "black"
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
|
@ -51,6 +51,9 @@ TextArea {
|
||||||
selectionColor: MoneroComponents.Style.dimmedFontColor
|
selectionColor: MoneroComponents.Style.dimmedFontColor
|
||||||
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
||||||
|
|
||||||
|
property int minimumHeight: 100 * scaleRatio
|
||||||
|
height: contentHeight > minimumHeight ? contentHeight : minimumHeight
|
||||||
|
|
||||||
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 }`
|
||||||
|
|
170
components/LanguageSidebar.qml
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.XmlListModel 2.0
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
|
||||||
|
Drawer {
|
||||||
|
id: sideBar
|
||||||
|
|
||||||
|
// @TODO: Qt 5.10 introduces `opened` built-in for Drawer
|
||||||
|
property bool isOpened: false
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
isOpened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpened: {
|
||||||
|
isOpened = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
width: 240 * scaleRatio
|
||||||
|
height: parent.height - (persistentSettings.customDecorations ? 50 : 0)
|
||||||
|
y: titleBar.height
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: "#0d0d0d"
|
||||||
|
width: parent.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
color: "red"
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
clip: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
width: sideBar.width
|
||||||
|
height: sideBar.height
|
||||||
|
|
||||||
|
model: langModel
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
id: item
|
||||||
|
color: "transparent"
|
||||||
|
width: sideBar.width
|
||||||
|
height: 32 * scaleRatio
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 16 * scaleRatio
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 14 * scaleRatio
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
text: display_name
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
color: MoneroComponents.Style.dividerColor
|
||||||
|
opacity: MoneroComponents.Style.dividerOpacity
|
||||||
|
height: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// button gradient while checked
|
||||||
|
Image {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: "../images/menuButtonGradient.png"
|
||||||
|
opacity: 0.65
|
||||||
|
visible: true
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
var locale_spl = locale.split("_");
|
||||||
|
|
||||||
|
// reload active translations
|
||||||
|
console.log(locale_spl[0]);
|
||||||
|
translationManager.setLanguage(locale_spl[0]);
|
||||||
|
|
||||||
|
// set wizard language settings
|
||||||
|
wizard.language_locale = locale;
|
||||||
|
wizard.language_wallet = wallet_language;
|
||||||
|
wizard.language_language = display_name + " (" + locale_spl[1] + ") ";
|
||||||
|
sideBar.close()
|
||||||
|
}
|
||||||
|
hoverEnabled: true
|
||||||
|
onEntered: {
|
||||||
|
// item.color = "#26FFFFFF"
|
||||||
|
parent.opacity = 1
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
// item.color = "transparent"
|
||||||
|
parent.opacity = 0.65
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollIndicator.vertical: ScrollIndicator {
|
||||||
|
// @TODO: QT 5.9 introduces `policy: ScrollBar.AlwaysOn`
|
||||||
|
active: true
|
||||||
|
contentItem.opacity: 0.7
|
||||||
|
onActiveChanged: {
|
||||||
|
if (!active) {
|
||||||
|
active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Flags model
|
||||||
|
XmlListModel {
|
||||||
|
id: langModel
|
||||||
|
source: "/lang/languages.xml"
|
||||||
|
query: "/languages/language"
|
||||||
|
|
||||||
|
XmlRole { name: "display_name"; query: "@display_name/string()" }
|
||||||
|
XmlRole { name: "locale"; query: "@locale/string()" }
|
||||||
|
XmlRole { name: "wallet_language"; query: "@wallet_language/string()" }
|
||||||
|
XmlRole { name: "flag"; query: "@flag/string()" }
|
||||||
|
// TODO: XmlListModel is read only, we should store current language somewhere else
|
||||||
|
// and set current language accordingly
|
||||||
|
XmlRole { name: "isCurrent"; query: "@enabled/string()" }
|
||||||
|
|
||||||
|
onStatusChanged: {
|
||||||
|
if(status === XmlListModel.Ready){
|
||||||
|
console.log("languages available: ",count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,7 +54,9 @@ Item {
|
||||||
|
|
||||||
property bool borderDisabled: false
|
property bool borderDisabled: false
|
||||||
property string borderColor: {
|
property string borderColor: {
|
||||||
if(input.activeFocus){
|
if(error && input.text !== ""){
|
||||||
|
return MoneroComponents.Style.inputBorderColorInvalid;
|
||||||
|
} else if(input.activeFocus){
|
||||||
return MoneroComponents.Style.inputBorderColorActive;
|
return MoneroComponents.Style.inputBorderColorActive;
|
||||||
} else {
|
} else {
|
||||||
return MoneroComponents.Style.inputBorderColorInActive;
|
return MoneroComponents.Style.inputBorderColorInActive;
|
||||||
|
@ -211,8 +213,6 @@ Item {
|
||||||
visible: item.inlineButtonText ? true : false
|
visible: item.inlineButtonText ? true : false
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: 8 * scaleRatio
|
anchors.rightMargin: 8 * scaleRatio
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 6 * scaleRatio
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,12 @@ ColumnLayout {
|
||||||
property alias labelButtonText: labelButton.text
|
property alias labelButtonText: labelButton.text
|
||||||
property alias placeholderText: placeholderLabel.text
|
property alias placeholderText: placeholderLabel.text
|
||||||
|
|
||||||
|
property int inputPaddingLeft: 10 * scaleRatio
|
||||||
|
property int inputPaddingRight: 10 * scaleRatio
|
||||||
|
property int inputPaddingTop: 10 * scaleRatio
|
||||||
|
property int inputPaddingBottom: 10 * scaleRatio
|
||||||
|
property int inputRadius: 4
|
||||||
|
|
||||||
property bool placeholderCenter: false
|
property bool placeholderCenter: false
|
||||||
property string placeholderFontFamily: MoneroComponents.Style.fontRegular.name
|
property string placeholderFontFamily: MoneroComponents.Style.fontRegular.name
|
||||||
property bool placeholderFontBold: false
|
property bool placeholderFontBold: false
|
||||||
|
@ -153,8 +159,12 @@ ColumnLayout {
|
||||||
readOnly: false
|
readOnly: false
|
||||||
addressValidation: false
|
addressValidation: false
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
topPadding: 10 * scaleRatio
|
|
||||||
bottomPadding: 10 * scaleRatio
|
leftPadding: item.inputPaddingLeft
|
||||||
|
rightPadding: item.inputPaddingRight
|
||||||
|
topPadding: item.inputPaddingTop
|
||||||
|
bottomPadding: item.inputPaddingBottom
|
||||||
|
|
||||||
wrapMode: item.wrapMode
|
wrapMode: item.wrapMode
|
||||||
fontSize: item.fontSize
|
fontSize: item.fontSize
|
||||||
fontBold: item.fontBold
|
fontBold: item.fontBold
|
||||||
|
@ -182,7 +192,7 @@ ColumnLayout {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.width: 1
|
border.width: 1
|
||||||
border.color: item.borderColor
|
border.color: item.borderColor
|
||||||
radius: 4
|
radius: item.inputRadius
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: !item.borderDisabled
|
visible: !item.borderDisabled
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,13 @@ Rectangle {
|
||||||
}
|
}
|
||||||
if (status == Wallet.ConnectionStatus_WrongVersion)
|
if (status == Wallet.ConnectionStatus_WrongVersion)
|
||||||
return qsTr("Wrong version")
|
return qsTr("Wrong version")
|
||||||
if (status == Wallet.ConnectionStatus_Disconnected)
|
if (status == Wallet.ConnectionStatus_Disconnected){
|
||||||
|
if(appWindow.walletMode <= 1){
|
||||||
|
return qsTr("Searching node") + translationManager.emptyString;
|
||||||
|
}
|
||||||
return qsTr("Disconnected")
|
return qsTr("Disconnected")
|
||||||
|
}
|
||||||
|
|
||||||
return qsTr("Invalid connection status")
|
return qsTr("Invalid connection status")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import QtQuick.Controls.Styles 1.2
|
||||||
import QtQuick 2.2
|
import QtQuick 2.2
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import "../js/Utils.js" as Utils
|
||||||
import "../components" as MoneroComponents
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
|
@ -65,7 +66,14 @@ GridLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAddress() {
|
function getAddress() {
|
||||||
return daemonAddr.text.trim() + ":" + daemonPort.text.trim()
|
var addr = daemonAddr.text.trim();
|
||||||
|
var port = daemonPort.text.trim();
|
||||||
|
|
||||||
|
// validation
|
||||||
|
if(addr === "" || addr.length < 2) return "";
|
||||||
|
if(!Utils.isNumeric(port)) return "";
|
||||||
|
|
||||||
|
return addr + ":" + port;
|
||||||
}
|
}
|
||||||
|
|
||||||
LineEdit {
|
LineEdit {
|
||||||
|
|
|
@ -16,6 +16,7 @@ QtObject {
|
||||||
|
|
||||||
property string defaultFontColor: "white"
|
property string defaultFontColor: "white"
|
||||||
property string dimmedFontColor: "#BBBBBB"
|
property string dimmedFontColor: "#BBBBBB"
|
||||||
|
property string lightGreyFontColor: "#DFDFDF"
|
||||||
property string errorColor: "#FA6800"
|
property string errorColor: "#FA6800"
|
||||||
property string inputBoxBackground: "black"
|
property string inputBoxBackground: "black"
|
||||||
property string inputBoxBackgroundError: "#FFDDDD"
|
property string inputBoxBackgroundError: "#FFDDDD"
|
||||||
|
|
|
@ -126,37 +126,88 @@ Rectangle {
|
||||||
z: parent.z + 1
|
z: parent.z + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// collapse left panel
|
RowLayout {
|
||||||
Rectangle {
|
|
||||||
id: goToBasicVersionButton
|
|
||||||
property bool containsMouse: titleBar.mouseX >= x && titleBar.mouseX <= x + width
|
|
||||||
property bool checked: false
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
color: "transparent"
|
anchors.top: parent.top
|
||||||
height: titleBar.height
|
width: 40
|
||||||
width: height
|
height: parent.height
|
||||||
visible: !titleBar.orange && titleBar.basicButtonVisible
|
spacing: 0
|
||||||
z: parent.z + 2
|
z: parent.z + 2
|
||||||
|
|
||||||
Image {
|
Rectangle {
|
||||||
width: 14
|
Layout.preferredHeight: parent.height
|
||||||
height: 14
|
Layout.preferredWidth: Layout.preferredHeight
|
||||||
anchors.centerIn: parent
|
|
||||||
source: "../images/expand.png"
|
id: goToBasicVersionButton
|
||||||
|
property bool containsMouse: titleBar.mouseX >= x && titleBar.mouseX <= x + width
|
||||||
|
property bool checked: false
|
||||||
|
color: "transparent"
|
||||||
|
height: titleBar.height
|
||||||
|
width: height
|
||||||
|
visible: !titleBar.orange && titleBar.basicButtonVisible
|
||||||
|
|
||||||
|
Image {
|
||||||
|
width: 14
|
||||||
|
height: 14
|
||||||
|
anchors.centerIn: parent
|
||||||
|
source: "../images/expand.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: basicMouseArea
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onEntered: { goToBasicVersionButton.color = titleBar.orange ? titleBar.buttonHoverColorOrange : titleBar.buttonHoverColor }
|
||||||
|
onExited: goToBasicVersionButton.color = "transparent";
|
||||||
|
onClicked: {
|
||||||
|
releaseFocus()
|
||||||
|
parent.checked = !parent.checked
|
||||||
|
titleBar.goToBasicVersion(leftPanel.visible)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
// language selection
|
||||||
id: basicMouseArea
|
Rectangle {
|
||||||
hoverEnabled: true
|
Layout.preferredHeight: parent.height
|
||||||
anchors.fill: parent
|
Layout.preferredWidth: Layout.preferredHeight
|
||||||
cursorShape: Qt.PointingHandCursor
|
visible: !titleBar.orange && persistentSettings.customDecorations
|
||||||
onEntered: { goToBasicVersionButton.color = titleBar.orange ? titleBar.buttonHoverColorOrange : titleBar.buttonHoverColor }
|
|
||||||
onExited: goToBasicVersionButton.color = "transparent";
|
id: languageSelection
|
||||||
onClicked: {
|
property bool containsMouse: titleBar.mouseX >= x && titleBar.mouseX <= x + width
|
||||||
releaseFocus()
|
property bool checked: false
|
||||||
parent.checked = !parent.checked
|
color: "transparent"
|
||||||
titleBar.goToBasicVersion(leftPanel.visible)
|
height: titleBar.height
|
||||||
|
width: height
|
||||||
|
z: parent.z + 2
|
||||||
|
|
||||||
|
Image {
|
||||||
|
width: 14
|
||||||
|
height: 14
|
||||||
|
anchors.centerIn: parent
|
||||||
|
source: "../images/langFlagGrey.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onEntered: parent.color = "#262626";
|
||||||
|
onExited: parent.color = "transparent";
|
||||||
|
onClicked: {
|
||||||
|
releaseFocus();
|
||||||
|
|
||||||
|
// Show welcome screen if on home
|
||||||
|
if(wizard.wizardState === "wizardHome" || wizard.wizardState === "wizardModeSelection"){
|
||||||
|
wizard.skipModeSelection = true;
|
||||||
|
wizard.wizardState = 'wizardLanguage';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
languageSidebar.isOpened ? languageSidebar.close() : languageSidebar.open();
|
||||||
|
console.log('change language');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,12 @@ Rectangle {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.preferredHeight: 33
|
Layout.preferredHeight: 33 * scaleRatio
|
||||||
Layout.preferredWidth: 33
|
Layout.preferredWidth: 33 * scaleRatio
|
||||||
Layout.rightMargin: 14
|
Layout.rightMargin: 12 * scaleRatio
|
||||||
Layout.leftMargin: 14
|
Layout.leftMargin: 18 * scaleRatio
|
||||||
Layout.topMargin: 12
|
Layout.topMargin: 12 * scaleRatio
|
||||||
Layout.bottomMargin: 12
|
Layout.bottomMargin: 12 * scaleRatio
|
||||||
source: "../images/warning.png"
|
source: "../images/warning.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,22 +44,19 @@ Rectangle {
|
||||||
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
|
||||||
selectionColor: MoneroComponents.Style.dimmedFontColor
|
|
||||||
selectByMouse: true
|
selectByMouse: true
|
||||||
textFormat: Text.RichText
|
textFormat: Text.RichText
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
textMargin: 0
|
textMargin: 0
|
||||||
leftPadding: 0
|
leftPadding: 4 * scaleRatio
|
||||||
topPadding: 6
|
rightPadding: 18 * scaleRatio
|
||||||
|
topPadding: 10 * scaleRatio
|
||||||
|
bottomPadding: 10 * scaleRatio
|
||||||
readOnly: true
|
readOnly: true
|
||||||
onLinkActivated: root.linkActivated();
|
onLinkActivated: root.linkActivated();
|
||||||
|
|
||||||
// @TODO: Legacy. Remove after Qt 5.8.
|
selectionColor: MoneroComponents.Style.dimmedFontColor
|
||||||
// https://stackoverflow.com/questions/41990013
|
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
enabled: false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
images/create-wallet.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
images/create-wallet@2x.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
images/langFlagGrey.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
images/local-node-full.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
images/local-node-full@2x.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
images/local-node.png
Normal file
After Width: | Height: | Size: 848 B |
BIN
images/local-node@2x.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
images/open-wallet-from-file.png
Normal file
After Width: | Height: | Size: 742 B |
BIN
images/open-wallet-from-file@2x.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
images/remote-node.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
images/remote-node@2x.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
images/restore-wallet-from-hardware.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
images/restore-wallet-from-hardware@2x.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
images/restore-wallet.png
Normal file
After Width: | Height: | Size: 1,008 B |
BIN
images/restore-wallet@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
images/world-flags-globe.png
Normal file
After Width: | Height: | Size: 737 KiB |
|
@ -12,6 +12,7 @@ function destinationsToAddress(destinations){
|
||||||
}
|
}
|
||||||
|
|
||||||
function addressTruncate(address, range){
|
function addressTruncate(address, range){
|
||||||
|
if(typeof(address) === "undefined") return;
|
||||||
if(typeof(range) === "undefined") range = 8;
|
if(typeof(range) === "undefined") range = 8;
|
||||||
return address.substring(0, range) + "..." + address.substring(address.length-range);
|
return address.substring(0, range) + "..." + address.substring(address.length-range);
|
||||||
}
|
}
|
||||||
|
|
20
js/Utils.js
|
@ -87,3 +87,23 @@ function ago(epoch) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function netTypeToString(){
|
||||||
|
// 0: mainnet, 1: testnet, 2: stagenet
|
||||||
|
var nettype = appWindow.persistentSettings.nettype;
|
||||||
|
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(){
|
||||||
|
return Math.floor((new Date).getTime()/1000);
|
||||||
|
}
|
||||||
|
|
179
js/Wizard.js
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
.pragma library
|
||||||
|
|
||||||
|
function updateFromQrCode(address, payment_id, amount, tx_description, recipient_name, extra_parameters) {
|
||||||
|
// Switch to recover from keys
|
||||||
|
recoverFromSeedMode = false
|
||||||
|
spendkey.text = ""
|
||||||
|
viewKeyLine.text = ""
|
||||||
|
restoreHeightItem.text = ""
|
||||||
|
|
||||||
|
if(typeof extra_parameters.secret_view_key != "undefined") {
|
||||||
|
viewKeyLine.text = extra_parameters.secret_view_key
|
||||||
|
}
|
||||||
|
if(typeof extra_parameters.secret_spend_key != "undefined") {
|
||||||
|
spendkey.text = extra_parameters.secret_spend_key
|
||||||
|
}
|
||||||
|
if(typeof extra_parameters.restore_height != "undefined") {
|
||||||
|
restoreHeightItem.text = extra_parameters.restore_height
|
||||||
|
}
|
||||||
|
addressLine.text = address
|
||||||
|
|
||||||
|
cameraUi.qrcode_decoded.disconnect(updateFromQrCode)
|
||||||
|
|
||||||
|
// Check if keys are correct
|
||||||
|
checkNextButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
function restart(){
|
||||||
|
wizard.currentPage = 0;
|
||||||
|
wizard.settings = ({})
|
||||||
|
wizard.currentPath = "create_wallet"
|
||||||
|
wizard.pages = paths[currentPath]
|
||||||
|
wizardRestarted();
|
||||||
|
|
||||||
|
//hide all pages except first
|
||||||
|
for (var i = 1; i < wizard.pages.length; i++){
|
||||||
|
wizard.pages[i].opacity = 0;
|
||||||
|
}
|
||||||
|
//Show first pages
|
||||||
|
wizard.pages[0].opacity = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchPage(next) {
|
||||||
|
// Android focus workaround
|
||||||
|
releaseFocus();
|
||||||
|
|
||||||
|
// save settings for current page;
|
||||||
|
if (next && typeof pages[currentPage].onPageClosed !== 'undefined') {
|
||||||
|
if (pages[currentPage].onPageClosed(settings) !== true) {
|
||||||
|
print ("Can't go to the next page");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
console.log("switchpage: currentPage: ", currentPage);
|
||||||
|
|
||||||
|
// Update prev/next button positions for mobile/desktop
|
||||||
|
prevButton.anchors.verticalCenter = (!isMobile) ? wizard.verticalCenter : undefined
|
||||||
|
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) {
|
||||||
|
pages[currentPage].opacity = 0
|
||||||
|
var step_value = next ? 1 : -1
|
||||||
|
currentPage += step_value
|
||||||
|
pages[currentPage].opacity = 1;
|
||||||
|
|
||||||
|
var nextButtonVisible = currentPage > 1 && currentPage < pages.length - 1
|
||||||
|
nextButton.visible = nextButtonVisible
|
||||||
|
|
||||||
|
if (typeof pages[currentPage].onPageOpened !== 'undefined') {
|
||||||
|
pages[currentPage].onPageOpened(settings,next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openRecoveryWalletPage() {
|
||||||
|
wizardRestarted();
|
||||||
|
print ("show recovery wallet page");
|
||||||
|
currentPath = "recovery_wallet"
|
||||||
|
pages = paths[currentPath]
|
||||||
|
// Create temporary wallet
|
||||||
|
createWalletPage.createWallet(settings)
|
||||||
|
wizard.nextButton.visible = true
|
||||||
|
// goto next page
|
||||||
|
switchPage(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openCreateViewOnlyWalletPage(){
|
||||||
|
pages[currentPage].opacity = 0
|
||||||
|
currentPath = "create_view_only_wallet"
|
||||||
|
pages = paths[currentPath]
|
||||||
|
currentPage = pages.indexOf(createViewOnlyWalletPage)
|
||||||
|
createViewOnlyWalletPage.opacity = 1
|
||||||
|
nextButton.visible = true
|
||||||
|
rootItem.state = "wizard";
|
||||||
|
}
|
||||||
|
|
||||||
|
function openCreateWalletFromDevicePage() {
|
||||||
|
wizardRestarted();
|
||||||
|
print ("show create wallet from device page");
|
||||||
|
currentPath = "create_wallet_from_device"
|
||||||
|
pages = paths[currentPath]
|
||||||
|
wizard.nextButton.visible = true
|
||||||
|
// goto next page
|
||||||
|
switchPage(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createWalletPath(isIOS, folder_path,account_name){
|
||||||
|
// Remove trailing slash - (default on windows and mac)
|
||||||
|
if (folder_path.substring(folder_path.length -1) === "/"){
|
||||||
|
folder_path = folder_path.substring(0,folder_path.length -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store releative path on ios.
|
||||||
|
if(isIOS)
|
||||||
|
folder_path = "";
|
||||||
|
|
||||||
|
return folder_path + "/" + account_name + "/" + account_name
|
||||||
|
}
|
||||||
|
|
||||||
|
function walletPathExists(directory, filename, isIOS, walletManager) {
|
||||||
|
if(!filename || filename === "") return false;
|
||||||
|
if(!directory || directory === "") return false;
|
||||||
|
|
||||||
|
// make sure directory endswith path seperator
|
||||||
|
// @TODO: use .endswith() after Qt 5.8
|
||||||
|
var trailing_path_sep = directory[directory.length-1];
|
||||||
|
if(trailing_path_sep !== "/" && trailing_path_sep !== "\\")
|
||||||
|
directory += "/"
|
||||||
|
|
||||||
|
if(isIOS)
|
||||||
|
var path = moneroAccountsDir + filename;
|
||||||
|
else
|
||||||
|
var path = directory + filename + "/" + filename;
|
||||||
|
|
||||||
|
if (walletManager.walletExists(path))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAscii(str){
|
||||||
|
for (var i = 0; i < str.length; i++) {
|
||||||
|
if (str.charCodeAt(i) > 127)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function tr(text) {
|
||||||
|
return qsTr(text) + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
function lineBreaksToSpaces(text) {
|
||||||
|
return text.trim().replace(/(\r\n|\n|\r)/gm, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
function usefulName(path) {
|
||||||
|
// arbitrary "short enough" limit
|
||||||
|
if (path.length < 32)
|
||||||
|
return path
|
||||||
|
return path.replace(/.*[\/\\]/, '').replace(/\.keys$/, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkSeed(seed) {
|
||||||
|
console.log("Checking seed")
|
||||||
|
var wordsArray = lineBreaksToSpaces(seed).split(" ");
|
||||||
|
return wordsArray.length === 25 || wordsArray.length === 24
|
||||||
|
}
|
||||||
|
|
||||||
|
function restoreWalletCheckViewSpendAddress(walletmanager, nettype, viewkey, spendkey, addressline){
|
||||||
|
var addressOK = (viewkey.length > 0 || spendkey.length > 0) ? walletmanager.addressValid(addressline, nettype) : false
|
||||||
|
var viewKeyOK = (viewkey.length > 0) ? walletmanager.keyValid(viewkey, addressline, true, nettype) : true
|
||||||
|
// Spendkey is optional
|
||||||
|
var spendKeyOK = (spendkey.length > 0) ? walletmanager.keyValid(spendkey, addressline, false, nettype) : true
|
||||||
|
|
||||||
|
return addressOK && viewKeyOK && spendKeyOK
|
||||||
|
}
|
163
main.qml
|
@ -37,8 +37,8 @@ import moneroComponents.Wallet 1.0
|
||||||
import moneroComponents.PendingTransaction 1.0
|
import moneroComponents.PendingTransaction 1.0
|
||||||
import moneroComponents.NetworkType 1.0
|
import moneroComponents.NetworkType 1.0
|
||||||
|
|
||||||
|
|
||||||
import "components"
|
import "components"
|
||||||
|
import "components" as MoneroComponents
|
||||||
import "wizard"
|
import "wizard"
|
||||||
import "js/Utils.js" as Utils
|
import "js/Utils.js" as Utils
|
||||||
import "js/Windows.js" as Windows
|
import "js/Windows.js" as Windows
|
||||||
|
@ -73,6 +73,7 @@ ApplicationWindow {
|
||||||
property int blocksToSync: 1
|
property int blocksToSync: 1
|
||||||
property var isMobile: (appWindow.width > 700 && !isAndroid) ? false : true
|
property var isMobile: (appWindow.width > 700 && !isAndroid) ? false : true
|
||||||
property bool isMining: false
|
property bool isMining: false
|
||||||
|
property int walletMode: persistentSettings.walletMode
|
||||||
property var cameraUi
|
property var cameraUi
|
||||||
property bool remoteNodeConnected: false
|
property bool remoteNodeConnected: false
|
||||||
property bool androidCloseTapped: false;
|
property bool androidCloseTapped: false;
|
||||||
|
@ -81,7 +82,21 @@ ApplicationWindow {
|
||||||
readonly property string localDaemonAddress : "localhost:" + getDefaultDaemonRpcPort(persistentSettings.nettype)
|
readonly property string localDaemonAddress : "localhost:" + getDefaultDaemonRpcPort(persistentSettings.nettype)
|
||||||
property string currentDaemonAddress;
|
property string currentDaemonAddress;
|
||||||
property bool startLocalNodeCancelled: false
|
property bool startLocalNodeCancelled: false
|
||||||
property int estimatedBlockchainSize: 50 // GB
|
property int disconnectedEpoch: 0
|
||||||
|
property int estimatedBlockchainSize: 75 // GB
|
||||||
|
property alias viewState: rootItem.state
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "https://autonode.xmr.pm/"; // monero-gui workgroup
|
||||||
|
}
|
||||||
|
|
||||||
// true if wallet ever synchronized
|
// true if wallet ever synchronized
|
||||||
property bool walletInitialized : false
|
property bool walletInitialized : false
|
||||||
|
@ -186,10 +201,12 @@ ApplicationWindow {
|
||||||
restoreHeight = 0;
|
restoreHeight = 0;
|
||||||
persistentSettings.is_recovering = false
|
persistentSettings.is_recovering = false
|
||||||
walletPassword = ""
|
walletPassword = ""
|
||||||
|
fileDialog.folder = "file://" + moneroAccountsDir
|
||||||
fileDialog.open();
|
fileDialog.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
function initialize() {
|
function initialize() {
|
||||||
|
appWindow.viewState = "normal";
|
||||||
console.log("initializing..")
|
console.log("initializing..")
|
||||||
|
|
||||||
// Use stored log level
|
// Use stored log level
|
||||||
|
@ -213,19 +230,17 @@ ApplicationWindow {
|
||||||
closeWallet();
|
closeWallet();
|
||||||
currentWallet = undefined
|
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";
|
||||||
leftPanel.selectItem(middlePanel.state)
|
leftPanel.selectItem(middlePanel.state)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Local daemon settings
|
// Local daemon settings
|
||||||
walletManager.setDaemonAddress(localDaemonAddress)
|
walletManager.setDaemonAddress(localDaemonAddress)
|
||||||
|
|
||||||
// enable user inactivity timer
|
// enable timers
|
||||||
userInActivityTimer.running = true;
|
userInActivityTimer.running = true;
|
||||||
|
simpleModeConnectionTimer.running = true;
|
||||||
|
|
||||||
// wallet already opened with wizard, we just need to initialize it
|
// wallet already opened with wizard, we just need to initialize it
|
||||||
if (typeof wizard.m_wallet !== 'undefined') {
|
if (typeof wizard.m_wallet !== 'undefined') {
|
||||||
|
@ -389,8 +404,8 @@ ApplicationWindow {
|
||||||
// Update fee multiplier dropdown on transfer page
|
// Update fee multiplier dropdown on transfer page
|
||||||
middlePanel.transferView.updatePriorityDropdown();
|
middlePanel.transferView.updatePriorityDropdown();
|
||||||
|
|
||||||
// If wallet isnt connected and no daemon is running - Ask
|
// If wallet isnt connected, advanced wallet mode and no daemon is running - Ask
|
||||||
if(!isMobile && walletManager.isDaemonLocal(appWindow.persistentSettings.daemon_address) && !walletInitialized && status === Wallet.ConnectionStatus_Disconnected && !daemonManager.running(persistentSettings.nettype)){
|
if(!isMobile && appWindow.walletMode >= 2 && walletManager.isDaemonLocal(appWindow.persistentSettings.daemon_address) && !walletInitialized && status === Wallet.ConnectionStatus_Disconnected && !daemonManager.running(persistentSettings.nettype)){
|
||||||
daemonManagerDialog.open();
|
daemonManagerDialog.open();
|
||||||
}
|
}
|
||||||
// initialize transaction history once wallet is initialized first time;
|
// initialize transaction history once wallet is initialized first time;
|
||||||
|
@ -401,7 +416,7 @@ ApplicationWindow {
|
||||||
// check if daemon was already mining and add mining logo if true
|
// check if daemon was already mining and add mining logo if true
|
||||||
middlePanel.miningView.update();
|
middlePanel.miningView.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWalletOpened(wallet) {
|
function onWalletOpened(wallet) {
|
||||||
walletName = usefulName(wallet.path)
|
walletName = usefulName(wallet.path)
|
||||||
|
@ -414,6 +429,7 @@ ApplicationWindow {
|
||||||
passwordDialog.onRejectedCallback = function() {
|
passwordDialog.onRejectedCallback = function() {
|
||||||
walletPassword = "";
|
walletPassword = "";
|
||||||
//appWindow.enableUI(false)
|
//appWindow.enableUI(false)
|
||||||
|
wizard.wizardState = "wizardHome";
|
||||||
rootItem.state = "wizard";
|
rootItem.state = "wizard";
|
||||||
}
|
}
|
||||||
// opening with password but password doesn't match
|
// opening with password but password doesn't match
|
||||||
|
@ -426,6 +442,9 @@ ApplicationWindow {
|
||||||
|
|
||||||
// wallet opened successfully, subscribing for wallet updates
|
// wallet opened successfully, subscribing for wallet updates
|
||||||
connectWallet(wallet)
|
connectWallet(wallet)
|
||||||
|
|
||||||
|
// Force switch normal view
|
||||||
|
rootItem.state = "normal";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -527,6 +546,9 @@ ApplicationWindow {
|
||||||
// Pause refresh while starting daemon
|
// Pause refresh while starting daemon
|
||||||
currentWallet.pauseRefresh();
|
currentWallet.pauseRefresh();
|
||||||
|
|
||||||
|
// Pause simplemode connection timer
|
||||||
|
simpleModeConnectionTimer.stop();
|
||||||
|
|
||||||
appWindow.showProcessingSplash(qsTr("Waiting for daemon to start..."))
|
appWindow.showProcessingSplash(qsTr("Waiting for daemon to start..."))
|
||||||
daemonManager.start(flags, persistentSettings.nettype, persistentSettings.blockchainDataDir, persistentSettings.bootstrapNodeAddress);
|
daemonManager.start(flags, persistentSettings.nettype, persistentSettings.blockchainDataDir, persistentSettings.bootstrapNodeAddress);
|
||||||
persistentSettings.daemonFlags = flags
|
persistentSettings.daemonFlags = flags
|
||||||
|
@ -544,6 +566,8 @@ ApplicationWindow {
|
||||||
currentWallet.connected(true);
|
currentWallet.connected(true);
|
||||||
// resume refresh
|
// resume refresh
|
||||||
currentWallet.startRefresh();
|
currentWallet.startRefresh();
|
||||||
|
// resume simplemode connection timer
|
||||||
|
simpleModeConnectionTimer.start();
|
||||||
}
|
}
|
||||||
function onDaemonStopped(){
|
function onDaemonStopped(){
|
||||||
console.log("daemon stopped");
|
console.log("daemon stopped");
|
||||||
|
@ -938,11 +962,13 @@ ApplicationWindow {
|
||||||
closeWallet();
|
closeWallet();
|
||||||
currentWallet = undefined;
|
currentWallet = undefined;
|
||||||
wizard.restart();
|
wizard.restart();
|
||||||
|
wizard.wizardState = "wizardHome";
|
||||||
rootItem.state = "wizard"
|
rootItem.state = "wizard"
|
||||||
// reset balance
|
// reset balance
|
||||||
leftPanel.balanceText = leftPanel.unlockedBalanceText = walletManager.displayAmount(0);
|
leftPanel.balanceText = leftPanel.unlockedBalanceText = walletManager.displayAmount(0);
|
||||||
// disable inactivity timer
|
// disable timers
|
||||||
userInActivityTimer.running = false;
|
userInActivityTimer.running = false;
|
||||||
|
simpleModeConnectionTimer.running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideMenu() {
|
function hideMenu() {
|
||||||
|
@ -1004,6 +1030,7 @@ ApplicationWindow {
|
||||||
initialize(persistentSettings);
|
initialize(persistentSettings);
|
||||||
}
|
}
|
||||||
passwordDialog.onRejectedCallback = function() {
|
passwordDialog.onRejectedCallback = function() {
|
||||||
|
wizard.wizardState = "wizardHome";
|
||||||
rootItem.state = "wizard"
|
rootItem.state = "wizard"
|
||||||
}
|
}
|
||||||
passwordDialog.open(usefulName(walletPath()))
|
passwordDialog.open(usefulName(walletPath()))
|
||||||
|
@ -1048,12 +1075,15 @@ 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
|
||||||
property int kdfRounds: 1
|
property int kdfRounds: 1
|
||||||
property bool hideBalance: false
|
property bool hideBalance: false
|
||||||
property bool lockOnUserInActivity: true
|
property bool lockOnUserInActivity: true
|
||||||
|
property int walletMode: 2
|
||||||
|
property string remoteNodeService: ""
|
||||||
property int lockOnUserInActivityInterval: 10 // minutes
|
property int lockOnUserInActivityInterval: 10 // minutes
|
||||||
property bool showPid: false
|
property bool showPid: false
|
||||||
}
|
}
|
||||||
|
@ -1116,11 +1146,11 @@ ApplicationWindow {
|
||||||
//Open Wallet from file
|
//Open Wallet from file
|
||||||
FileDialog {
|
FileDialog {
|
||||||
id: fileDialog
|
id: fileDialog
|
||||||
title: "Please choose a file"
|
title: qsTr("Please choose a file")
|
||||||
folder: "file://" +moneroAccountsDir
|
folder: "file://" + moneroAccountsDir
|
||||||
nameFilters: [ "Wallet files (*.keys)"]
|
nameFilters: [ "Wallet files (*.keys)"]
|
||||||
sidebarVisible: false
|
sidebarVisible: false
|
||||||
|
visible: false
|
||||||
|
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
persistentSettings.wallet_path = walletManager.urlToLocalPath(fileDialog.fileUrl)
|
persistentSettings.wallet_path = walletManager.urlToLocalPath(fileDialog.fileUrl)
|
||||||
|
@ -1135,7 +1165,8 @@ ApplicationWindow {
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
passwordDialog.onRejectedCallback = function() {
|
passwordDialog.onRejectedCallback = function() {
|
||||||
console.log("Canceled")
|
console.log("Canceled");
|
||||||
|
wizard.wizardState = "wizardHome";
|
||||||
rootItem.state = "wizard";
|
rootItem.state = "wizard";
|
||||||
}
|
}
|
||||||
passwordDialog.open(usefulName(walletPath()));
|
passwordDialog.open(usefulName(walletPath()));
|
||||||
|
@ -1150,27 +1181,31 @@ ApplicationWindow {
|
||||||
// Choose blockchain folder
|
// Choose blockchain folder
|
||||||
FileDialog {
|
FileDialog {
|
||||||
id: blockchainFileDialog
|
id: blockchainFileDialog
|
||||||
|
property string directory: ""
|
||||||
|
signal changed();
|
||||||
|
|
||||||
title: "Please choose a folder"
|
title: "Please choose a folder"
|
||||||
selectFolder: true
|
selectFolder: true
|
||||||
folder: "file://" + persistentSettings.blockchainDataDir
|
folder: "file://" + persistentSettings.blockchainDataDir
|
||||||
|
|
||||||
|
onRejected: console.log("data dir selection canceled")
|
||||||
onAccepted: {
|
onAccepted: {
|
||||||
var dataDir = walletManager.urlToLocalPath(blockchainFileDialog.fileUrl)
|
var dataDir = walletManager.urlToLocalPath(blockchainFileDialog.fileUrl)
|
||||||
var validator = daemonManager.validateDataDir(dataDir);
|
var validator = daemonManager.validateDataDir(dataDir);
|
||||||
if(!validator.valid) {
|
if(validator.valid) {
|
||||||
|
persistentSettings.blockchainDataDir = dataDir;
|
||||||
|
} else {
|
||||||
confirmationDialog.title = qsTr("Warning") + translationManager.emptyString;
|
confirmationDialog.title = qsTr("Warning") + translationManager.emptyString;
|
||||||
confirmationDialog.text = "";
|
confirmationDialog.text = "";
|
||||||
if(validator.readOnly)
|
if(validator.readOnly)
|
||||||
confirmationDialog.text += qsTr("Error: Filesystem is read only") + "\n\n"
|
confirmationDialog.text += qsTr("Error: Filesystem is read only") + "\n\n"
|
||||||
if(validator.storageAvailable < 20)
|
if(validator.storageAvailable < estimatedBlockchainSize)
|
||||||
confirmationDialog.text += qsTr("Warning: There's only %1 GB available on the device. Blockchain requires ~%2 GB of data.").arg(validator.storageAvailable).arg(estimatedBlockchainSize) + "\n\n"
|
confirmationDialog.text += qsTr("Warning: There's only %1 GB available on the device. Blockchain requires ~%2 GB of data.").arg(validator.storageAvailable).arg(estimatedBlockchainSize) + "\n\n"
|
||||||
else
|
else
|
||||||
confirmationDialog.text += qsTr("Note: There's %1 GB available on the device. Blockchain requires ~%2 GB of data.").arg(validator.storageAvailable).arg(estimatedBlockchainSize) + "\n\n"
|
confirmationDialog.text += qsTr("Note: There's %1 GB available on the device. Blockchain requires ~%2 GB of data.").arg(validator.storageAvailable).arg(estimatedBlockchainSize) + "\n\n"
|
||||||
if(!validator.lmdbExists)
|
if(!validator.lmdbExists)
|
||||||
confirmationDialog.text += qsTr("Note: lmdb folder not found. A new folder will be created.") + "\n\n"
|
confirmationDialog.text += qsTr("Note: lmdb folder not found. A new folder will be created.") + "\n\n"
|
||||||
|
|
||||||
|
|
||||||
confirmationDialog.icon = StandardIcon.Question
|
confirmationDialog.icon = StandardIcon.Question
|
||||||
confirmationDialog.cancelText = qsTr("Cancel")
|
confirmationDialog.cancelText = qsTr("Cancel")
|
||||||
|
|
||||||
|
@ -1180,25 +1215,15 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel
|
// Cancel
|
||||||
confirmationDialog.onRejectedCallback = function() {
|
confirmationDialog.onRejectedCallback = function() { };
|
||||||
};
|
|
||||||
|
|
||||||
confirmationDialog.open()
|
confirmationDialog.open()
|
||||||
} else {
|
|
||||||
persistentSettings.blockchainDataDir = dataDir
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blockchainFileDialog.directory = blockchainFileDialog.fileUrl;
|
||||||
delete validator;
|
delete validator;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
onRejected: {
|
|
||||||
console.log("data dir selection canceled")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PasswordDialog {
|
PasswordDialog {
|
||||||
id: passwordDialog
|
id: passwordDialog
|
||||||
visible: false
|
visible: false
|
||||||
|
@ -1287,19 +1312,16 @@ ApplicationWindow {
|
||||||
PropertyChanges { target: leftPanel; visible: false }
|
PropertyChanges { target: leftPanel; visible: false }
|
||||||
PropertyChanges { target: rightPanel; visible: false }
|
PropertyChanges { target: rightPanel; visible: false }
|
||||||
PropertyChanges { target: middlePanel; visible: false }
|
PropertyChanges { target: middlePanel; visible: false }
|
||||||
PropertyChanges { target: titleBar; basicButtonVisible: false }
|
|
||||||
PropertyChanges { target: wizard; visible: true }
|
PropertyChanges { target: wizard; visible: true }
|
||||||
PropertyChanges { target: appWindow; width: (screenWidth < 930 || isAndroid || isIOS)? screenWidth : 930; }
|
PropertyChanges { target: appWindow; width: (screenWidth < 969 || isAndroid || isIOS)? screenWidth : 969 } //rightPanelExpanded ? 1269 : 1269 - 300;
|
||||||
PropertyChanges { target: appWindow; height: maxWindowHeight; }
|
PropertyChanges { target: appWindow; height: maxWindowHeight; }
|
||||||
PropertyChanges { target: resizeArea; visible: true }
|
PropertyChanges { target: resizeArea; visible: true }
|
||||||
PropertyChanges { target: titleBar; showMaximizeButton: true }
|
|
||||||
// PropertyChanges { target: frameArea; blocked: true }
|
// PropertyChanges { target: frameArea; blocked: true }
|
||||||
PropertyChanges { target: titleBar; visible: true }
|
|
||||||
PropertyChanges { target: titleBar; y: 0 }
|
|
||||||
PropertyChanges { target: titleBar; showMoneroLogo: false }
|
|
||||||
PropertyChanges { target: titleBar; titleBarGradientImageOpacity: 0.2 }
|
|
||||||
PropertyChanges { target: titleBar; small: true }
|
|
||||||
PropertyChanges { target: mobileHeader; visible: false }
|
PropertyChanges { target: mobileHeader; visible: false }
|
||||||
|
PropertyChanges { target: titleBar; basicButtonVisible: false }
|
||||||
|
PropertyChanges { target: titleBar; showMaximizeButton: true }
|
||||||
|
PropertyChanges { target: titleBar; visible: true }
|
||||||
|
PropertyChanges { target: titleBar; title: qsTr("Monero") + translationManager.emptyString }
|
||||||
}, State {
|
}, State {
|
||||||
name: "normal"
|
name: "normal"
|
||||||
PropertyChanges { target: leftPanel; visible: (isMobile)? false : true }
|
PropertyChanges { target: leftPanel; visible: (isMobile)? false : true }
|
||||||
|
@ -1573,17 +1595,13 @@ ApplicationWindow {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
WizardMain {
|
WizardController {
|
||||||
id: wizard
|
id: wizard
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onUseMoneroClicked: {
|
onUseMoneroClicked: {
|
||||||
rootItem.state = "normal" // TODO: listen for this state change in appWindow;
|
rootItem.state = "normal";
|
||||||
appWindow.initialize();
|
appWindow.initialize();
|
||||||
}
|
}
|
||||||
onOpenWalletFromFileClicked: {
|
|
||||||
rootItem.state = "normal" // TODO: listen for this state change in appWindow;
|
|
||||||
appWindow.openWalletFromFile();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
property int minWidth: 326
|
property int minWidth: 326
|
||||||
|
@ -1730,6 +1748,50 @@ ApplicationWindow {
|
||||||
onTriggered: checkInUserActivity()
|
onTriggered: checkInUserActivity()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkSimpleModeConnection(){
|
||||||
|
// auto-connection mechanism for simple mode
|
||||||
|
if(persistentSettings.nettype != NetworkType.MAINNET) return;
|
||||||
|
if(appWindow.walletMode >= 2) return;
|
||||||
|
|
||||||
|
var disconnected = leftPanel.networkStatus.connected === Wallet.ConnectionStatus_Disconnected;
|
||||||
|
var disconnectedEpoch = appWindow.disconnectedEpoch;
|
||||||
|
if(disconnectedEpoch === 0){
|
||||||
|
appWindow.disconnectedEpoch = Utils.epoch();
|
||||||
|
}
|
||||||
|
|
||||||
|
// disconnected longer than 5 seconds?
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch new node list
|
||||||
|
wizard.fetchRemoteNodes(function() {
|
||||||
|
// fetched node, connect
|
||||||
|
if(appWindow.walletMode === 0){
|
||||||
|
appWindow.connectRemoteNode();
|
||||||
|
} else if(appWindow.walletMode === 1){
|
||||||
|
appWindow.startDaemon(persistentSettings.daemonFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset state
|
||||||
|
appWindow.disconnectedEpoch = 0;
|
||||||
|
return;
|
||||||
|
}, function(){
|
||||||
|
appWindow.showStatusMessage(qsTr("Failed to fetch remote nodes from third-party server."), simpleModeConnectionTimer.interval / 1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
// Simple mode connection check timer
|
||||||
|
id: simpleModeConnectionTimer
|
||||||
|
interval: 2000; running: false; repeat: true
|
||||||
|
onTriggered: appWindow.checkSimpleModeConnection()
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: statusMessage
|
id: statusMessage
|
||||||
z: 99
|
z: 99
|
||||||
|
@ -1873,6 +1935,7 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkInUserActivity() {
|
function checkInUserActivity() {
|
||||||
|
if(rootItem.state !== "normal") return;
|
||||||
if(!persistentSettings.lockOnUserInActivity) return;
|
if(!persistentSettings.lockOnUserInActivity) return;
|
||||||
|
|
||||||
// prompt password after X seconds of inactivity
|
// prompt password after X seconds of inactivity
|
||||||
|
@ -1903,6 +1966,14 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changeWalletMode(mode){
|
||||||
|
appWindow.walletMode = mode;
|
||||||
|
persistentSettings.walletMode = mode;
|
||||||
|
persistentSettings.useRemoteNode = mode === 0 ? true : false;
|
||||||
|
|
||||||
|
console.log("walletMode changed: " + (mode === 0 ? "simple": mode === 1 ? "simple (bootstrap)" : "Advanced"));
|
||||||
|
}
|
||||||
|
|
||||||
// Daemon console
|
// Daemon console
|
||||||
DaemonConsole {
|
DaemonConsole {
|
||||||
id: daemonConsolePopup
|
id: daemonConsolePopup
|
||||||
|
@ -1922,4 +1993,8 @@ ApplicationWindow {
|
||||||
color: "black"
|
color: "black"
|
||||||
opacity: 0.8
|
opacity: 0.8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoneroComponents.LanguageSidebar {
|
||||||
|
id: languageSidebar
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -462,10 +462,7 @@ OTHER_FILES += \
|
||||||
|
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
notes.txt \
|
notes.txt \
|
||||||
monero/src/wallet/CMakeLists.txt \
|
monero/src/wallet/CMakeLists.txt
|
||||||
components/MobileHeader.qml \
|
|
||||||
pages/merchant/Merchant.qml \
|
|
||||||
pages/merchant/MerchantCheckbox.qml
|
|
||||||
|
|
||||||
|
|
||||||
# windows application icon
|
# windows application icon
|
||||||
|
|
|
@ -325,6 +325,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearFields() {
|
function clearFields() {
|
||||||
|
// @TODO: add fields
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPageClosed() {
|
function onPageClosed() {
|
||||||
|
|
|
@ -443,6 +443,7 @@ Rectangle {
|
||||||
enabled: !viewOnly || pageRoot.enabled
|
enabled: !viewOnly || pageRoot.enabled
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
CheckBox2 {
|
CheckBox2 {
|
||||||
id: showAdvancedCheckbox
|
id: showAdvancedCheckbox
|
||||||
checked: persistentSettings.transferShowAdvanced
|
checked: persistentSettings.transferShowAdvanced
|
||||||
|
@ -454,7 +455,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
visible: persistentSettings.transferShowAdvanced
|
visible: persistentSettings.transferShowAdvanced && appWindow.walletMode >= 2
|
||||||
columns: (isMobile) ? 2 : 6
|
columns: (isMobile) ? 2 : 6
|
||||||
|
|
||||||
StandardButton {
|
StandardButton {
|
||||||
|
@ -676,9 +677,11 @@ Rectangle {
|
||||||
//TODO: enable send page when we're connected and daemon is synced
|
//TODO: enable send page when we're connected and daemon is synced
|
||||||
|
|
||||||
function updateStatus() {
|
function updateStatus() {
|
||||||
|
var messageNotConnected = qsTr("Wallet is not connected to daemon.");
|
||||||
|
if(appWindow.walletMode >= 2) messageNotConnected += root.startLinkText;
|
||||||
pageRoot.enabled = true;
|
pageRoot.enabled = true;
|
||||||
if(typeof currentWallet === "undefined") {
|
if(typeof currentWallet === "undefined") {
|
||||||
root.warningContent = qsTr("Wallet is not connected to daemon.") + root.startLinkText
|
root.warningContent = messageNotConnected;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,7 +693,7 @@ Rectangle {
|
||||||
|
|
||||||
switch (currentWallet.connected()) {
|
switch (currentWallet.connected()) {
|
||||||
case Wallet.ConnectionStatus_Disconnected:
|
case Wallet.ConnectionStatus_Disconnected:
|
||||||
root.warningContent = qsTr("Wallet is not connected to daemon.") + root.startLinkText
|
root.warningContent = messageNotConnected;
|
||||||
break
|
break
|
||||||
case Wallet.ConnectionStatus_WrongVersion:
|
case Wallet.ConnectionStatus_WrongVersion:
|
||||||
root.warningContent = qsTr("Connected daemon is not compatible with GUI. \n" +
|
root.warningContent = qsTr("Connected daemon is not compatible with GUI. \n" +
|
||||||
|
@ -698,7 +701,7 @@ Rectangle {
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
if(!appWindow.daemonSynced){
|
if(!appWindow.daemonSynced){
|
||||||
root.warningContent = qsTr("Waiting on daemon synchronization to finish")
|
root.warningContent = qsTr("Waiting on daemon synchronization to finish.")
|
||||||
} else {
|
} else {
|
||||||
// everything OK, enable transfer page
|
// everything OK, enable transfer page
|
||||||
// Light wallet is always ready
|
// Light wallet is always ready
|
||||||
|
|
|
@ -182,6 +182,7 @@ Rectangle {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
// NODE
|
// NODE
|
||||||
id: navNode
|
id: navNode
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
Layout.preferredWidth: navNodeText.width + grid.textMargin
|
Layout.preferredWidth: navNodeText.width + grid.textMargin
|
||||||
Layout.preferredHeight: 32
|
Layout.preferredHeight: 32
|
||||||
Layout.minimumWidth: 72 * scaleRatio
|
Layout.minimumWidth: 72 * scaleRatio
|
||||||
|
@ -225,6 +226,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle{
|
Rectangle{
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
Layout.preferredWidth: 1
|
Layout.preferredWidth: 1
|
||||||
Layout.preferredHeight: 32
|
Layout.preferredHeight: 32
|
||||||
color: grid.borderColor
|
color: grid.borderColor
|
||||||
|
@ -232,6 +234,7 @@ Rectangle {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
// LOG
|
// LOG
|
||||||
id: navLog
|
id: navLog
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
Layout.preferredWidth: navLogText.width + grid.textMargin
|
Layout.preferredWidth: navLogText.width + grid.textMargin
|
||||||
Layout.preferredHeight: 32
|
Layout.preferredHeight: 32
|
||||||
Layout.minimumWidth: 72 * scaleRatio
|
Layout.minimumWidth: 72 * scaleRatio
|
||||||
|
@ -275,6 +278,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Rectangle{
|
Rectangle{
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
Layout.preferredWidth: 1
|
Layout.preferredWidth: 1
|
||||||
Layout.preferredHeight: 32
|
Layout.preferredHeight: 32
|
||||||
color: grid.borderColor
|
color: grid.borderColor
|
||||||
|
|
|
@ -39,6 +39,15 @@ Rectangle {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
height: 1400 * scaleRatio
|
height: 1400 * scaleRatio
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
property string walletModeString: {
|
||||||
|
if(appWindow.walletMode === 0){
|
||||||
|
return qsTr("Simple mode") + translationManager.emptyString;
|
||||||
|
} else if(appWindow.walletMode === 1){
|
||||||
|
return qsTr("Simple mode") + " (bootstrap)" + translationManager.emptyString;
|
||||||
|
} else if(appWindow.walletMode === 2){
|
||||||
|
return qsTr("Advanced mode") + translationManager.emptyString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: infoLayout
|
id: infoLayout
|
||||||
|
@ -239,6 +248,36 @@ Rectangle {
|
||||||
font.pixelSize: 14 * scaleRatio
|
font.pixelSize: 14 * scaleRatio
|
||||||
text: walletLogPath
|
text: walletLogPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
height: 1
|
||||||
|
Layout.topMargin: 2 * scaleRatio
|
||||||
|
Layout.bottomMargin: 2 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: MoneroComponents.Style.dividerColor
|
||||||
|
opacity: MoneroComponents.Style.dividerOpacity
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
height: 1
|
||||||
|
Layout.topMargin: 2 * scaleRatio
|
||||||
|
Layout.bottomMargin: 2 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: MoneroComponents.Style.dividerColor
|
||||||
|
opacity: MoneroComponents.Style.dividerOpacity
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.TextBlock {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: 14 * scaleRatio
|
||||||
|
text: qsTr("Wallet mode: ") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.TextBlock {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: 14 * scaleRatio
|
||||||
|
text: walletModeString
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy info to clipboard
|
// Copy info to clipboard
|
||||||
|
@ -261,6 +300,7 @@ Rectangle {
|
||||||
data += currentWallet.walletCreationHeight;
|
data += currentWallet.walletCreationHeight;
|
||||||
|
|
||||||
data += "\nWallet log path: " + walletLogPath;
|
data += "\nWallet log path: " + walletLogPath;
|
||||||
|
data += "\nWallet mode: " + walletModeString;
|
||||||
|
|
||||||
console.log("Copied to clipboard");
|
console.log("Copied to clipboard");
|
||||||
clipboard.setText(data);
|
clipboard.setText(data);
|
||||||
|
|
|
@ -164,6 +164,17 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
visible: !persistentSettings.customDecorations
|
||||||
|
Layout.topMargin: 10 * scaleRatio
|
||||||
|
small: true
|
||||||
|
text: "Change language"
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
languageSidebar.isOpened ? languageSidebar.close() : languageSidebar.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MoneroComponents.TextBlock {
|
MoneroComponents.TextBlock {
|
||||||
visible: isMobile
|
visible: isMobile
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
|
|
|
@ -258,6 +258,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: settingsWallet.itemHeight
|
Layout.preferredHeight: settingsWallet.itemHeight
|
||||||
columnSpacing: 0
|
columnSpacing: 0
|
||||||
|
@ -326,6 +327,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
// divider
|
// divider
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
Layout.preferredHeight: 1 * scaleRatio
|
Layout.preferredHeight: 1 * scaleRatio
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 8 * scaleRatio
|
Layout.topMargin: 8 * scaleRatio
|
||||||
|
|
57
qml.qrc
|
@ -62,23 +62,13 @@
|
||||||
<file>images/resize@2x.png</file>
|
<file>images/resize@2x.png</file>
|
||||||
<file>images/resizeHovered.png</file>
|
<file>images/resizeHovered.png</file>
|
||||||
<file>images/resizeHovered@2x.png</file>
|
<file>images/resizeHovered@2x.png</file>
|
||||||
<file>wizard/WizardWelcome.qml</file>
|
|
||||||
<file>wizard/WizardMain.qml</file>
|
|
||||||
<file>images/nextPage.png</file>
|
<file>images/nextPage.png</file>
|
||||||
<file>images/nextPage@2x.png</file>
|
<file>images/nextPage@2x.png</file>
|
||||||
<file>wizard/WizardOptions.qml</file>
|
|
||||||
<file>images/createWallet.png</file>
|
<file>images/createWallet.png</file>
|
||||||
<file>images/createWalletFromDevice.png</file>
|
<file>images/createWalletFromDevice.png</file>
|
||||||
<file>images/openAccount.png</file>
|
<file>images/openAccount.png</file>
|
||||||
<file>images/recoverWallet.png</file>
|
<file>images/recoverWallet.png</file>
|
||||||
<file>wizard/WizardCreateWallet.qml</file>
|
|
||||||
<file>wizard/WizardCreateWalletFromDevice.qml</file>
|
|
||||||
<file>images/copyToClipboard.png</file>
|
<file>images/copyToClipboard.png</file>
|
||||||
<file>wizard/WizardPassword.qml</file>
|
|
||||||
<file>wizard/WizardConfigure.qml</file>
|
|
||||||
<file>wizard/WizardDonation.qml</file>
|
|
||||||
<file>wizard/WizardFinish.qml</file>
|
|
||||||
<file>wizard/WizardPasswordInput.qml</file>
|
|
||||||
<file>lang/languages.xml</file>
|
<file>lang/languages.xml</file>
|
||||||
<file>lang/flags/bd.png</file>
|
<file>lang/flags/bd.png</file>
|
||||||
<file>lang/flags/bg.png</file>
|
<file>lang/flags/bg.png</file>
|
||||||
|
@ -123,10 +113,6 @@
|
||||||
<file>lang/flags/gb.png</file>
|
<file>lang/flags/gb.png</file>
|
||||||
<file>lang/flags/us.png</file>
|
<file>lang/flags/us.png</file>
|
||||||
<file>lang/flags/pirate.png</file>
|
<file>lang/flags/pirate.png</file>
|
||||||
<file>wizard/WizardManageWalletUI.qml</file>
|
|
||||||
<file>wizard/WizardRecoveryWallet.qml</file>
|
|
||||||
<file>wizard/WizardMemoTextInput.qml</file>
|
|
||||||
<file>wizard/utils.js</file>
|
|
||||||
<file>pages/Receive.qml</file>
|
<file>pages/Receive.qml</file>
|
||||||
<file>pages/TxKey.qml</file>
|
<file>pages/TxKey.qml</file>
|
||||||
<file>pages/SharedRingDB.qml</file>
|
<file>pages/SharedRingDB.qml</file>
|
||||||
|
@ -140,14 +126,11 @@
|
||||||
<file>pages/Sign.qml</file>
|
<file>pages/Sign.qml</file>
|
||||||
<file>components/DaemonManagerDialog.qml</file>
|
<file>components/DaemonManagerDialog.qml</file>
|
||||||
<file>version.js</file>
|
<file>version.js</file>
|
||||||
<file>wizard/WizardPasswordUI.qml</file>
|
|
||||||
<file>wizard/WizardCreateViewOnlyWallet.qml</file>
|
|
||||||
<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/MobileHeader.qml</file>
|
||||||
<file>components/TextBlock.qml</file>
|
<file>components/TextBlock.qml</file>
|
||||||
<file>wizard/WizardDaemonSettings.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>
|
||||||
|
@ -247,5 +230,45 @@
|
||||||
<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>
|
||||||
|
<file>wizard/WizardAskPassword.qml</file>
|
||||||
|
<file>wizard/WizardController.qml</file>
|
||||||
|
<file>wizard/WizardCreateWallet1.qml</file>
|
||||||
|
<file>wizard/WizardCreateWallet2.qml</file>
|
||||||
|
<file>wizard/WizardCreateWallet3.qml</file>
|
||||||
|
<file>wizard/WizardCreateWallet4.qml</file>
|
||||||
|
<file>wizard/WizardCreateDevice1.qml</file>
|
||||||
|
<file>wizard/WizardDaemonSettings.qml</file>
|
||||||
|
<file>wizard/WizardHeader.qml</file>
|
||||||
|
<file>wizard/WizardHome.qml</file>
|
||||||
|
<file>wizard/WizardLanguage.qml</file>
|
||||||
|
<file>wizard/WizardNav.qml</file>
|
||||||
|
<file>wizard/WizardWalletInput.qml</file>
|
||||||
|
<file>wizard/WizardRestoreWallet1.qml</file>
|
||||||
|
<file>wizard/WizardRestoreWallet2.qml</file>
|
||||||
|
<file>wizard/WizardRestoreWallet3.qml</file>
|
||||||
|
<file>wizard/WizardRestoreWallet4.qml</file>
|
||||||
|
<file>wizard/WizardSummary.qml</file>
|
||||||
|
<file>wizard/WizardSummaryItem.qml</file>
|
||||||
|
<file>wizard/WizardModeSelection.qml</file>
|
||||||
|
<file>wizard/WizardModeRemoteNodeWarning.qml</file>
|
||||||
|
<file>wizard/WizardModeBootstrap.qml</file>
|
||||||
|
<file>wizard/WizardMenuItem.qml</file>
|
||||||
|
<file>js/Wizard.js</file>
|
||||||
|
<file>components/LanguageSidebar.qml</file>
|
||||||
|
<file>images/world-flags-globe.png</file>
|
||||||
|
<file>images/langFlagGrey.png</file>
|
||||||
|
<file>images/restore-wallet-from-hardware@2x.png</file>
|
||||||
|
<file>images/restore-wallet-from-hardware.png</file>
|
||||||
|
<file>images/open-wallet-from-file@2x.png</file>
|
||||||
|
<file>images/open-wallet-from-file.png</file>
|
||||||
|
<file>images/restore-wallet@2x.png</file>
|
||||||
|
<file>images/restore-wallet.png</file>
|
||||||
|
<file>images/create-wallet@2x.png</file>
|
||||||
|
<file>images/create-wallet.png</file>
|
||||||
|
<file>images/remote-node.png</file>
|
||||||
|
<file>images/local-node.png</file>
|
||||||
|
<file>images/local-node-full.png</file>
|
||||||
|
<file>wizard/WizardNavProgressDot.qml</file>
|
||||||
|
<file>wizard/WizardOpenWallet1.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -275,9 +275,9 @@ QVariantMap DaemonManager::validateDataDir(const QString &dataDir) const
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure there is 20GB storage available
|
// Make sure there is 75GB storage available
|
||||||
storageAvailable = storage.bytesAvailable()/1000/1000/1000;
|
storageAvailable = storage.bytesAvailable()/1000/1000/1000;
|
||||||
if (storageAvailable < 20) {
|
if (storageAvailable < 75) {
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
259
wizard/WizardAskPassword.qml
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: root
|
||||||
|
Layout.fillWidth: true
|
||||||
|
property alias password: passwordInput.text
|
||||||
|
property int passwordFill: 0
|
||||||
|
property string passwordStrengthText: qsTr("Strength: ") + translationManager.emptyString
|
||||||
|
|
||||||
|
function calcStrengthAndVerify(){
|
||||||
|
calcPasswordStrength();
|
||||||
|
return passwordInput.text === passwordInputConfirm.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calcPasswordStrength(inp) {
|
||||||
|
if(isAndroid) return;
|
||||||
|
if(passwordInput.text.length <= 1){
|
||||||
|
root.passwordFill = 0;
|
||||||
|
progressText.text = passwordStrengthText + qsTr("Low") + translationManager.emptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// scorePassword returns value from 0 to... lots
|
||||||
|
var strength = walletManager.getPasswordStrength(passwordInput.text);
|
||||||
|
// consider anything below 10 bits as dire
|
||||||
|
strength -= 10
|
||||||
|
if (strength < 0)
|
||||||
|
strength = 0;
|
||||||
|
// use a slight parabola to discourage short passwords
|
||||||
|
strength = strength ^ 1.2 / 3
|
||||||
|
strength += 20;
|
||||||
|
if (strength > 100)
|
||||||
|
strength = 100;
|
||||||
|
|
||||||
|
root.passwordFill = strength;
|
||||||
|
|
||||||
|
var strengthString;
|
||||||
|
if(strength <= 33){
|
||||||
|
strengthString = qsTr("Low");
|
||||||
|
} else if(strength <= 66){
|
||||||
|
strengthString = qsTr("Medium");
|
||||||
|
} else {
|
||||||
|
strengthString = qsTr("High");
|
||||||
|
}
|
||||||
|
|
||||||
|
progressText.text = passwordStrengthText + strengthString + translationManager.emptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
spacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader{
|
||||||
|
title: qsTr("Give your wallet a password") + translationManager.emptyString
|
||||||
|
subtitle: qsTr("This password cannot be recovered. If you forget it then the wallet will have to be restored from its 25 word mnemonic seed.") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.WarningBox {
|
||||||
|
text: qsTr("<b>Enter a strong password</b> (Using letters, numbers, and/or symbols).") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 0
|
||||||
|
visible: !isAndroid
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
TextInput {
|
||||||
|
id: progressText
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 6
|
||||||
|
font.family: MoneroComponents.Style.fontMedium.name
|
||||||
|
font.pixelSize: 14 * scaleRatio
|
||||||
|
font.bold: false
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
text: root.passwordStrengthText + '-'
|
||||||
|
height: 18 * scaleRatio
|
||||||
|
passwordCharacter: "*"
|
||||||
|
}
|
||||||
|
|
||||||
|
TextInput {
|
||||||
|
id: progressTextValue
|
||||||
|
font.family: MoneroComponents.Style.fontMedium.name
|
||||||
|
font.pixelSize: 13 * scaleRatio
|
||||||
|
font.bold: true
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
height:18 * scaleRatio
|
||||||
|
passwordCharacter: "*"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: bar
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 8
|
||||||
|
|
||||||
|
radius: 8 * scaleRatio
|
||||||
|
color: "#333333" // progressbar bg
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: fillRect
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
height: bar.height
|
||||||
|
property int maxWidth: bar.width * scaleRatio
|
||||||
|
width: (maxWidth * root.passwordFill) / 100
|
||||||
|
radius: 8
|
||||||
|
color: "#FA6800"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color:"#333"
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 8 * scaleRatio
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 4 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Password")
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
font.pixelSize: 14 * scaleRatio
|
||||||
|
font.family: MoneroComponents.Style.fontLight.name
|
||||||
|
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: passwordInput
|
||||||
|
|
||||||
|
Layout.topMargin: 6 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
bottomPadding: 10 * scaleRatio
|
||||||
|
leftPadding: 10 * scaleRatio
|
||||||
|
topPadding: 10 * scaleRatio
|
||||||
|
|
||||||
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
KeyNavigation.tab: passwordInputConfirm
|
||||||
|
|
||||||
|
font.family: MoneroComponents.Style.fontLight.name
|
||||||
|
font.pixelSize: 15 * scaleRatio
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
selectionColor: MoneroComponents.Style.dimmedFontColor
|
||||||
|
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
||||||
|
|
||||||
|
text: walletOptionsPassword
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
radius: 4
|
||||||
|
border.color: Qt.rgba(255, 255, 255, 0.35)
|
||||||
|
border.width: 1
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Image {
|
||||||
|
width: 12 * scaleRatio
|
||||||
|
height: 16 * scaleRatio
|
||||||
|
source: "../images/lockIcon.png"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 4
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: qsTr("Password (confirm)") + translationManager.emptyString
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
font.pixelSize: 14 * scaleRatio
|
||||||
|
font.family: MoneroComponents.Style.fontLight.name
|
||||||
|
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id : passwordInputConfirm
|
||||||
|
|
||||||
|
Layout.topMargin: 6 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
bottomPadding: 10 * scaleRatio
|
||||||
|
leftPadding: 10 * scaleRatio
|
||||||
|
topPadding: 10 * scaleRatio
|
||||||
|
|
||||||
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
echoMode: TextInput.Password
|
||||||
|
KeyNavigation.tab: passwordInputConfirm
|
||||||
|
|
||||||
|
font.family: MoneroComponents.Style.fontLight.name
|
||||||
|
font.pixelSize: 15 * scaleRatio
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
selectionColor: MoneroComponents.Style.dimmedFontColor
|
||||||
|
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
||||||
|
|
||||||
|
text: walletOptionsPassword
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
radius: 4
|
||||||
|
border.color: Qt.rgba(255, 255, 255, 0.35)
|
||||||
|
border.width: 1
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Image {
|
||||||
|
width: 12
|
||||||
|
height: 16
|
||||||
|
source: "../images/lockIcon.png"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,175 +0,0 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import QtQuick 2.2
|
|
||||||
import "../components"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
opacity: 0
|
|
||||||
visible: false
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpacityChanged: visible = opacity !== 0
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: dotsRow
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.topMargin: 85
|
|
||||||
spacing: 6
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: dotsModel
|
|
||||||
ListElement { dotColor: "#36B05B" }
|
|
||||||
ListElement { dotColor: "#36B05B" }
|
|
||||||
ListElement { dotColor: "#FFE00A" }
|
|
||||||
ListElement { dotColor: "#DBDBDB" }
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: dotsModel
|
|
||||||
delegate: Rectangle {
|
|
||||||
width: 12; height: 12
|
|
||||||
radius: 6
|
|
||||||
color: dotColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: headerText
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 74
|
|
||||||
anchors.leftMargin: 16
|
|
||||||
width: parent.width - dotsRow.width - 16
|
|
||||||
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 28
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
//renderType: Text.NativeRendering
|
|
||||||
color: "#3F3F3F"
|
|
||||||
text: qsTr("We’re almost there - let’s just configure some Monero preferences") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: headerText.bottom
|
|
||||||
anchors.topMargin: 34
|
|
||||||
anchors.leftMargin: 16
|
|
||||||
anchors.rightMargin: 16
|
|
||||||
spacing: 24
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
spacing: 12
|
|
||||||
|
|
||||||
CheckBox {
|
|
||||||
text: qsTr("Kickstart the Monero blockchain?") + translationManager.emptyString
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
background: "#F0EEEE"
|
|
||||||
fontColor: "#4A4646"
|
|
||||||
fontSize: 18
|
|
||||||
checked: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 15
|
|
||||||
color: "#4A4646"
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
text: qsTr("It is very important to write it down as this is the only backup you will need for your wallet.")
|
|
||||||
+ translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
spacing: 12
|
|
||||||
|
|
||||||
CheckBox {
|
|
||||||
text: qsTr("Enable disk conservation mode?") + translationManager.emptyString
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
background: "#F0EEEE"
|
|
||||||
fontColor: "#4A4646"
|
|
||||||
fontSize: 18
|
|
||||||
checked: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 15
|
|
||||||
color: "#4A4646"
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
text: qsTr("Disk conservation mode uses substantially less disk-space, but the same amount of bandwidth as " +
|
|
||||||
"a regular Monero instance. However, storing the full blockchain is beneficial to the security " +
|
|
||||||
"of the Monero network. If you are on a device with limited disk space, then this option is appropriate for you.")
|
|
||||||
+ translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
spacing: 12
|
|
||||||
|
|
||||||
CheckBox {
|
|
||||||
text: qsTr("Allow background mining?") + translationManager.emptyString
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
background: "#F0EEEE"
|
|
||||||
fontColor: "#4A4646"
|
|
||||||
fontSize: 18
|
|
||||||
checked: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 15
|
|
||||||
color: "#4A4646"
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
text: qsTr("Mining secures the Monero network, and also pays a small reward for the work done. This option " +
|
|
||||||
"will let Monero mine when your computer is on mains power and is idle. It will stop mining when you continue working.")
|
|
||||||
+ translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
484
wizard/WizardController.qml
Normal file
|
@ -0,0 +1,484 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import QtQuick.Controls.Styles 1.4
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
|
||||||
|
import moneroComponents.Wallet 1.0
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../js/Windows.js" as Windows
|
||||||
|
import "../js/Utils.js" as Utils
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
import "../pages"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardController
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
signal useMoneroClicked()
|
||||||
|
|
||||||
|
function restart() {
|
||||||
|
wizardStateView.state = "wizardHome"
|
||||||
|
wizardController.walletOptionsName = defaultAccountName;
|
||||||
|
wizardController.walletOptionsLocation = '';
|
||||||
|
wizardController.walletOptionsPassword = '';
|
||||||
|
wizardController.walletOptionsSeed = '';
|
||||||
|
wizardController.walletOptionsBackup = '';
|
||||||
|
wizardController.walletRestoreMode = 'seed';
|
||||||
|
wizardController.walletOptionsRestoreHeight = 0;
|
||||||
|
wizardController.walletOptionsIsRecovering = false;
|
||||||
|
wizardController.walletOptionsIsRecoveringFromDevice = false;
|
||||||
|
wizardController.walletOptionsDeviceName = '';
|
||||||
|
wizardController.tmpWalletFilename = '';
|
||||||
|
wizardController.walletRestoreMode = 'seed'
|
||||||
|
wizardController.walletOptionsSubaddressLookahead = "";
|
||||||
|
wizardController.remoteNodes = {};
|
||||||
|
wizardController.walletOptionsIsRecoveringFromDevice = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
property var m_wallet;
|
||||||
|
property alias wizardState: wizardStateView.state
|
||||||
|
property alias wizardStatePrevious: wizardStateView.previousView
|
||||||
|
property int wizardSubViewWidth: 780 * scaleRatio
|
||||||
|
property int wizardSubViewTopMargin: persistentSettings.customDecorations ? 90 * scaleRatio : 32 * scaleRatio
|
||||||
|
property bool skipModeSelection: false
|
||||||
|
|
||||||
|
// wallet variables
|
||||||
|
property string walletOptionsName: ''
|
||||||
|
property string walletOptionsLocation: ''
|
||||||
|
property string walletOptionsPassword: ''
|
||||||
|
property string walletOptionsSeed: ''
|
||||||
|
property string walletOptionsBackup: ''
|
||||||
|
property int walletOptionsRestoreHeight: 0
|
||||||
|
property string walletOptionsBootstrapAddress: persistentSettings.bootstrapNodeAddress
|
||||||
|
property bool walletOptionsRestoringFromDevice: false
|
||||||
|
property bool walletOptionsIsRecovering: false
|
||||||
|
property bool walletOptionsIsRecoveringFromDevice: false
|
||||||
|
property string walletOptionsSubaddressLookahead: ''
|
||||||
|
property string walletOptionsDeviceName: ''
|
||||||
|
property string tmpWalletFilename: ''
|
||||||
|
property var remoteNodes: ''
|
||||||
|
|
||||||
|
// language settings, updated via sidebar
|
||||||
|
property string language_locale: 'en_US'
|
||||||
|
property string language_wallet: 'English'
|
||||||
|
property string language_language: 'English (US)'
|
||||||
|
|
||||||
|
// recovery made (restore wallet)
|
||||||
|
property string walletRestoreMode: 'seed' // seed, keys, qr
|
||||||
|
|
||||||
|
property int layoutScale: {
|
||||||
|
if(isMobile){
|
||||||
|
return 0;
|
||||||
|
} else if(appWindow.width < 800){
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
opacity: 1.0
|
||||||
|
anchors.fill: parent
|
||||||
|
source: "../images/middlePanelBg.jpg"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardStateView
|
||||||
|
property Item currentView
|
||||||
|
property Item previousView
|
||||||
|
property WizardLanguage wizardLanguageView: WizardLanguage { }
|
||||||
|
property WizardHome wizardHomeView: WizardHome { }
|
||||||
|
property WizardCreateWallet1 wizardCreateWallet1View: WizardCreateWallet1 { }
|
||||||
|
property WizardCreateWallet2 wizardCreateWallet2View: WizardCreateWallet2 { }
|
||||||
|
property WizardCreateWallet3 wizardCreateWallet3View: WizardCreateWallet3 { }
|
||||||
|
property WizardCreateWallet4 wizardCreateWallet4View: WizardCreateWallet4 { }
|
||||||
|
property WizardRestoreWallet1 wizardRestoreWallet1View: WizardRestoreWallet1 { }
|
||||||
|
property WizardRestoreWallet2 wizardRestoreWallet2View: WizardRestoreWallet2 { }
|
||||||
|
property WizardRestoreWallet3 wizardRestoreWallet3View: WizardRestoreWallet3 { }
|
||||||
|
property WizardRestoreWallet4 wizardRestoreWallet4View: WizardRestoreWallet4 { }
|
||||||
|
property WizardCreateDevice1 wizardCreateDevice1View: WizardCreateDevice1 { }
|
||||||
|
property WizardOpenWallet1 wizardOpenWallet1View: WizardOpenWallet1 { }
|
||||||
|
property WizardModeSelection wizardModeSelectionView: WizardModeSelection { }
|
||||||
|
property WizardModeRemoteNodeWarning wizardModeRemoteNodeWarningView: WizardModeRemoteNodeWarning { }
|
||||||
|
property WizardModeBootstrap wizardModeBootstrapView: WizardModeBootstrap {}
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
signal previousClicked;
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
state: ''
|
||||||
|
|
||||||
|
onPreviousClicked: {
|
||||||
|
if (previousView && previousView.viewName != null){
|
||||||
|
state = previousView.viewName;
|
||||||
|
} else {
|
||||||
|
state = "wizardHome";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onCurrentViewChanged: {
|
||||||
|
if (previousView) {
|
||||||
|
if (typeof previousView.onPageClosed === "function") {
|
||||||
|
previousView.onPageClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combined with NumberAnimation to fade out views
|
||||||
|
previousView.opacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentView) {
|
||||||
|
stackView.replace(currentView)
|
||||||
|
// Calls when view is opened
|
||||||
|
if (typeof currentView.onPageCompleted === "function") {
|
||||||
|
currentView.onPageCompleted(previousView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combined with NumberAnimation to fade in views
|
||||||
|
currentView.opacity = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
previousView = currentView;
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "wizardLanguage"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardLanguageView }
|
||||||
|
}, State {
|
||||||
|
name: "wizardHome"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardHomeView }
|
||||||
|
}, State {
|
||||||
|
name: "wizardCreateWallet1"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardCreateWallet1View }
|
||||||
|
}, State {
|
||||||
|
name: "wizardCreateWallet2"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardCreateWallet2View }
|
||||||
|
}, State {
|
||||||
|
name: "wizardCreateWallet3"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardCreateWallet3View }
|
||||||
|
}, State {
|
||||||
|
name: "wizardCreateWallet4"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardCreateWallet4View }
|
||||||
|
}, State {
|
||||||
|
name: "wizardRestoreWallet1"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardRestoreWallet1View }
|
||||||
|
}, State {
|
||||||
|
name: "wizardRestoreWallet2"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardRestoreWallet2View }
|
||||||
|
}, State {
|
||||||
|
name: "wizardRestoreWallet3"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardRestoreWallet3View }
|
||||||
|
}, State {
|
||||||
|
name: "wizardRestoreWallet4"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardRestoreWallet4View }
|
||||||
|
}, State {
|
||||||
|
name: "wizardCreateDevice1"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardCreateDevice1View }
|
||||||
|
}, State {
|
||||||
|
name: "wizardOpenWallet1"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardOpenWallet1View }
|
||||||
|
}, State {
|
||||||
|
name: "wizardModeSelection"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardModeSelectionView }
|
||||||
|
}, State {
|
||||||
|
name: "wizardModeRemoteNodeWarning"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardModeRemoteNodeWarningView }
|
||||||
|
}, State {
|
||||||
|
name: "wizardModeBootstrap"
|
||||||
|
PropertyChanges { target: wizardStateView; currentView: wizardStateView.wizardModeBootstrapView }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
StackView {
|
||||||
|
id: stackView
|
||||||
|
initialItem: wizardStateView.wizardLanguageView
|
||||||
|
anchors.fill: parent
|
||||||
|
clip: false
|
||||||
|
|
||||||
|
delegate: StackViewDelegate {
|
||||||
|
pushTransition: StackViewTransition {
|
||||||
|
PropertyAnimation {
|
||||||
|
target: enterItem
|
||||||
|
property: "x"
|
||||||
|
from: target.width
|
||||||
|
to: 0
|
||||||
|
duration: 300
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
PropertyAnimation {
|
||||||
|
target: exitItem
|
||||||
|
property: "x"
|
||||||
|
from: 0
|
||||||
|
to: 0 - target.width
|
||||||
|
duration: 300
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Open Wallet from file
|
||||||
|
FileDialog {
|
||||||
|
id: fileDialog
|
||||||
|
title: qsTr("Please choose a file") + translationManager.emptyString
|
||||||
|
folder: "file://" + moneroAccountsDir
|
||||||
|
nameFilters: [ "Wallet files (*.keys)"]
|
||||||
|
sidebarVisible: false
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
wizardController.openWalletFile(fileDialog.fileUrl);
|
||||||
|
}
|
||||||
|
onRejected: {
|
||||||
|
console.log("Canceled")
|
||||||
|
appWindow.viewState = "wizard";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createWallet() {
|
||||||
|
// Creates wallet in a temp. location
|
||||||
|
|
||||||
|
// Always delete the wallet object before creating new - we could be stepping back from recovering wallet
|
||||||
|
if (typeof wizardController.m_wallet !== 'undefined') {
|
||||||
|
walletManager.closeWallet()
|
||||||
|
console.log("deleting wallet")
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp_wallet_filename = oshelper.temporaryFilename();
|
||||||
|
console.log("Creating temporary wallet", tmp_wallet_filename)
|
||||||
|
var nettype = appWindow.persistentSettings.nettype;
|
||||||
|
var kdfRounds = appWindow.persistentSettings.kdfRounds;
|
||||||
|
var wallet = walletManager.createWallet(tmp_wallet_filename, "", wizardController.language_wallet, nettype, kdfRounds)
|
||||||
|
|
||||||
|
wizardController.walletOptionsSeed = wallet.seed
|
||||||
|
|
||||||
|
// saving wallet in "global" object
|
||||||
|
// @TODO: wallet should have a property pointing to the file where it stored or loaded from
|
||||||
|
wizardController.m_wallet = wallet;
|
||||||
|
wizardController.tmpWalletFilename = tmp_wallet_filename
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeWallet() {
|
||||||
|
// Save wallet files in user specified location
|
||||||
|
var new_wallet_filename = Wizard.createWalletPath(
|
||||||
|
isIOS,
|
||||||
|
wizardController.walletOptionsLocation,
|
||||||
|
wizardController.walletOptionsName);
|
||||||
|
|
||||||
|
if(isIOS) {
|
||||||
|
console.log("saving in ios: " + moneroAccountsDir + new_wallet_filename)
|
||||||
|
wizardController.m_wallet.store(moneroAccountsDir + new_wallet_filename);
|
||||||
|
} else {
|
||||||
|
console.log("saving in wizard: " + new_wallet_filename)
|
||||||
|
wizardController.m_wallet.store(new_wallet_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure temporary wallet files are deleted
|
||||||
|
console.log("Removing temporary wallet: " + wizardController.tmpWalletFilename)
|
||||||
|
oshelper.removeTemporaryWallet(wizardController.tmpWalletFilename)
|
||||||
|
|
||||||
|
// protecting wallet with password
|
||||||
|
m_wallet.setPassword(walletOptionsPassword);
|
||||||
|
|
||||||
|
// Store password in session to be able to use password protected functions (e.g show seed)
|
||||||
|
appWindow.walletPassword = walletOptionsPassword
|
||||||
|
|
||||||
|
// save to persistent settings
|
||||||
|
persistentSettings.language = wizardController.language_language
|
||||||
|
persistentSettings.locale = wizardController.language_locale
|
||||||
|
|
||||||
|
persistentSettings.account_name = wizardController.walletOptionsName
|
||||||
|
persistentSettings.wallet_path = new_wallet_filename
|
||||||
|
persistentSettings.restore_height = (isNaN(walletOptionsRestoreHeight))? 0 : walletOptionsRestoreHeight
|
||||||
|
|
||||||
|
persistentSettings.allow_background_mining = false
|
||||||
|
persistentSettings.is_recovering = (wizardController.walletOptionsIsRecovering === undefined) ? false : wizardController.walletOptionsIsRecovering
|
||||||
|
persistentSettings.is_recovering_from_device = (wizardController.walletOptionsIsRecoveringFromDevice === undefined) ? false : wizardController.walletOptionsIsRecoveringFromDevice
|
||||||
|
}
|
||||||
|
|
||||||
|
function createWalletFromDevice() {
|
||||||
|
// TODO: create wallet in temporary filename and a) move it to the path specified by user after the final
|
||||||
|
// page submitted or b) delete it when program closed before reaching final page
|
||||||
|
|
||||||
|
// Always delete the wallet object before creating new - we could be stepping back from recovering wallet
|
||||||
|
if (typeof wizardController.m_wallet !== 'undefined') {
|
||||||
|
walletManager.closeWallet()
|
||||||
|
console.log("deleting wallet")
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp_wallet_filename = oshelper.temporaryFilename();
|
||||||
|
console.log("Creating temporary wallet", tmp_wallet_filename)
|
||||||
|
var nettype = persistentSettings.nettype;
|
||||||
|
var restoreHeight = wizardController.walletOptionsRestoreHeight;
|
||||||
|
var subaddressLookahead = wizardController.walletOptionsSubaddressLookahead;
|
||||||
|
var deviceName = wizardController.walletOptionsDeviceName;
|
||||||
|
|
||||||
|
var wallet = walletManager.createWalletFromDevice(tmp_wallet_filename, "", nettype, deviceName, restoreHeight, subaddressLookahead);
|
||||||
|
|
||||||
|
var success = wallet.status === Wallet.Status_Ok;
|
||||||
|
if (success) {
|
||||||
|
wizardController.m_wallet = wallet;
|
||||||
|
wizardController.walletOptionsIsRecoveringFromDevice = true;
|
||||||
|
wizardController.tmpWalletFilename = tmp_wallet_filename;
|
||||||
|
wizardController.walletOptionsRestoreHeight = wizardController.m_wallet.walletCreationHeight;
|
||||||
|
} else {
|
||||||
|
console.log(wallet.errorString)
|
||||||
|
appWindow.showStatusMessage(qsTr(wallet.errorString), 5);
|
||||||
|
walletManager.closeWallet();
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
function openWallet(){
|
||||||
|
if (typeof wizardController.m_wallet !== 'undefined' && wizardController.m_wallet != null) {
|
||||||
|
walletManager.closeWallet()
|
||||||
|
}
|
||||||
|
|
||||||
|
fileDialog.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
function openWalletFile(fn) {
|
||||||
|
persistentSettings.restore_height = 0;
|
||||||
|
persistentSettings.is_recovering = false;
|
||||||
|
|
||||||
|
appWindow.restoreHeight = 0;
|
||||||
|
appWindow.walletPassword = "";
|
||||||
|
|
||||||
|
if(typeof fn == 'object')
|
||||||
|
persistentSettings.wallet_path = walletManager.urlToLocalPath(fn);
|
||||||
|
else
|
||||||
|
persistentSettings.wallet_path = fn;
|
||||||
|
|
||||||
|
if(isIOS)
|
||||||
|
persistentSettings.wallet_path = persistentSettings.wallet_path.replace(moneroAccountsDir, "");
|
||||||
|
|
||||||
|
console.log(moneroAccountsDir);
|
||||||
|
console.log(fn);
|
||||||
|
console.log(persistentSettings.wallet_path);
|
||||||
|
|
||||||
|
passwordDialog.onAcceptedCallback = function() {
|
||||||
|
walletPassword = passwordDialog.password;
|
||||||
|
appWindow.initialize();
|
||||||
|
}
|
||||||
|
passwordDialog.onRejectedCallback = function() {
|
||||||
|
console.log("Canceled");
|
||||||
|
appWindow.viewState = "wizard";
|
||||||
|
}
|
||||||
|
|
||||||
|
passwordDialog.open(appWindow.usefulName(appWindow.walletPath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchRemoteNodes(cb, cb_err){
|
||||||
|
// Fetch remote nodes, parse JSON, store in result `wizardController.remoteNodes`, call setAutNode(), call callback
|
||||||
|
var url = appWindow.remoteNodeService + 'api/nodes.json';
|
||||||
|
console.log("HTTP request: " + url);
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.timeout = 3500;
|
||||||
|
|
||||||
|
// Unfortunately we cannot spoof User-Agent since it is hardcoded in Qt
|
||||||
|
//xhr.setRequestHeader("User-Agent", "-");
|
||||||
|
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
var msg;
|
||||||
|
if (xhr.readyState != 4) {
|
||||||
|
return;
|
||||||
|
} else if(xhr.status != 200){
|
||||||
|
msg = "Error fetching remote nodes; status code was not 200";
|
||||||
|
console.log(msg);
|
||||||
|
if(typeof cb_err === 'function')
|
||||||
|
return cb_err(msg);
|
||||||
|
} else {
|
||||||
|
var body = xhr.responseText;
|
||||||
|
if(typeof body === 'undefined' || body === ''){
|
||||||
|
msg = "Error fetching remote nodes; response body was empty";
|
||||||
|
console.log(msg);
|
||||||
|
if(typeof cb_err === 'function')
|
||||||
|
return cb_err(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = JSON.parse(body);
|
||||||
|
wizardController.remoteNodes = data;
|
||||||
|
console.log("node list updated");
|
||||||
|
setAutoNode();
|
||||||
|
return cb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.open('GET', url, true);
|
||||||
|
xhr.send(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setAutoNode(){
|
||||||
|
var node;
|
||||||
|
var nodes;
|
||||||
|
var nodeObject = wizardController.remoteNodes;
|
||||||
|
var region = persistentSettings.remoteNodeRegion;
|
||||||
|
|
||||||
|
if(typeof region !== 'undefined' && region !== ""){
|
||||||
|
if(nodeObject.hasOwnProperty(region) && nodeObject[region].length > 0){
|
||||||
|
nodes = nodeObject[region];
|
||||||
|
} else {
|
||||||
|
console.log("No suitable nodes found for region " + region + ". Defaulting to random node.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(typeof nodes === 'undefined'){
|
||||||
|
nodes = [];
|
||||||
|
Object.keys(nodeObject).forEach(function(obj, i){
|
||||||
|
nodes = nodes.concat(nodeObject[obj]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 18089 has precedence
|
||||||
|
var filteredNodes = Utils.filterNodes(nodes, "18089");
|
||||||
|
if(filteredNodes.length > 0){
|
||||||
|
node = Utils.randomChoice(filteredNodes);
|
||||||
|
console.log('Choosing remote node \''+ node +'\' from a list of ' + filteredNodes.length);
|
||||||
|
} else if(nodes.length > 0){
|
||||||
|
node = Utils.randomChoice(nodes);
|
||||||
|
console.log('Choosing remote node \''+ node +'\' from a list of ' + nodes.length);
|
||||||
|
} else {
|
||||||
|
console.log("No suitable nodes found.")
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
if(appWindow.walletMode === 0)
|
||||||
|
persistentSettings.remoteNodeAddress = node;
|
||||||
|
else if(appWindow.walletMode === 1)
|
||||||
|
persistentSettings.bootstrapNodeAddress = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
187
wizard/WizardCreateDevice1.qml
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import moneroComponents.Wallet 1.0
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components"
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardCreateDevice1
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property string viewName: "wizardCreateDevice1"
|
||||||
|
|
||||||
|
property var deviceName: deviceNameModel.get(deviceNameDropdown.currentIndex).column2
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: deviceNameModel
|
||||||
|
ListElement { column1: qsTr("Ledger") ; column2: "Ledger"; }
|
||||||
|
// ListElement { column1: qsTr("Trezor") ; column2: "Trezor"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(){
|
||||||
|
// update device dropdown
|
||||||
|
deviceNameDropdown.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader {
|
||||||
|
title: qsTr("Create a new wallet") + translationManager.emptyString
|
||||||
|
subtitle: qsTr("Using a hardware device.") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardWalletInput{
|
||||||
|
id: walletInput
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
Layout.topMargin: 10 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
columnSpacing: 20 * scaleRatio
|
||||||
|
columns: 2
|
||||||
|
|
||||||
|
MoneroComponents.LineEdit {
|
||||||
|
id: restoreHeight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
labelText: qsTr("Restore height (optional)") + translationManager.emptyString
|
||||||
|
labelFontSize: 14 * scaleRatio
|
||||||
|
placeholderFontSize: 16 * scaleRatio
|
||||||
|
placeholderText: "0"
|
||||||
|
validator: RegExpValidator { regExp: /(\d+)?$/ }
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.LineEdit {
|
||||||
|
id: lookahead
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
labelText: qsTr("Subaddress lookahead (optional)") + translationManager.emptyString
|
||||||
|
labelFontSize: 14 * scaleRatio
|
||||||
|
placeholderText: "<major>:<minor>"
|
||||||
|
placeholderFontSize: 16 * scaleRatio
|
||||||
|
validator: RegExpValidator { regExp: /(\d+):(\d+)?$/ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Layout.topMargin: 10 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
ColumnLayout{
|
||||||
|
MoneroComponents.StandardDropdown {
|
||||||
|
id: deviceNameDropdown
|
||||||
|
dataModel: deviceNameModel
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 6 * scaleRatio
|
||||||
|
releasedColor: "#363636"
|
||||||
|
pressedColor: "#202020"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextArea {
|
||||||
|
id: errorMsg
|
||||||
|
text: qsTr("Error writing wallet from hardware device. Check application logs.") + translationManager.emptyString;
|
||||||
|
visible: errorMsg.text !== ""
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
color: MoneroComponents.Style.errorColor
|
||||||
|
font.pixelSize: 16 * scaleRatio
|
||||||
|
|
||||||
|
selectionColor: MoneroComponents.Style.dimmedFontColor
|
||||||
|
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
||||||
|
|
||||||
|
selectByMouse: true
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
textMargin: 0
|
||||||
|
leftPadding: 0
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
progressSteps: 4
|
||||||
|
progress: 1
|
||||||
|
btnNext.enabled: walletInput.verify();
|
||||||
|
btnPrev.text: qsTr("Back to menu") + translationManager.emptyString
|
||||||
|
btnNext.text: qsTr("Create wallet") + translationManager.emptyString
|
||||||
|
onPrevClicked: {
|
||||||
|
wizardStateView.state = "wizardHome";
|
||||||
|
}
|
||||||
|
onNextClicked: {
|
||||||
|
wizardController.walletOptionsName = walletInput.walletName.text;
|
||||||
|
wizardController.walletOptionsLocation = walletInput.walletLocation.text;
|
||||||
|
wizardController.walletOptionsDeviceName = wizardCreateDevice1.deviceName;
|
||||||
|
|
||||||
|
if(restoreHeight.text)
|
||||||
|
wizardController.walletOptionsRestoreHeight = parseInt(restoreHeight.text);
|
||||||
|
if(lookahead.text)
|
||||||
|
wizardController.walletOptionsSubaddressLookahead = lookahead.text;
|
||||||
|
|
||||||
|
var written = wizardController.createWalletFromDevice();
|
||||||
|
if(written){
|
||||||
|
wizardController.walletOptionsIsRecoveringFromDevice = true;
|
||||||
|
wizardStateView.state = "wizardCreateWallet2";
|
||||||
|
} else {
|
||||||
|
errorMsg.text = qsTr("Error writing wallet from hardware device. Check application logs.") + translationManager.emptyString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
errorMsg.text = "";
|
||||||
|
wizardCreateDevice1.update();
|
||||||
|
console.log()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,112 +0,0 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import QtQuick 2.2
|
|
||||||
import moneroComponents.WalletManager 1.0
|
|
||||||
import moneroComponents.Wallet 1.0
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import QtQuick.Dialogs 1.2
|
|
||||||
import 'utils.js' as Utils
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
opacity: 0
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onOpacityChanged: visible = opacity !== 0
|
|
||||||
|
|
||||||
function onWizardRestarted() {
|
|
||||||
// reset account name field
|
|
||||||
uiItem.accountNameText = defaultAccountName
|
|
||||||
}
|
|
||||||
|
|
||||||
//! function called each time we display this page
|
|
||||||
|
|
||||||
function onPageOpened(settingsOblect) {
|
|
||||||
checkNextButton()
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPageClosed(settingsObject) {
|
|
||||||
settingsObject['account_name'] = uiItem.accountNameText
|
|
||||||
settingsObject['words'] = uiItem.wordsTexttext
|
|
||||||
settingsObject['wallet_path'] = uiItem.walletPath
|
|
||||||
console.log("path " +uiItem.walletPath);
|
|
||||||
var walletFullPath = wizard.createWalletPath(uiItem.walletPath,uiItem.accountNameText);
|
|
||||||
return wizard.walletPathValid(walletFullPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkNextButton() {
|
|
||||||
var wordsArray = Utils.lineBreaksToSpaces(uiItem.wordsTextItem.memoText).split(" ");
|
|
||||||
wizard.nextButton.enabled = wordsArray.length === 25;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! function called each time we hide this page
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
function createWallet(settingsObject) {
|
|
||||||
// TODO: create wallet in temporary filename and a) move it to the path specified by user after the final
|
|
||||||
// page submitted or b) delete it when program closed before reaching final page
|
|
||||||
|
|
||||||
// Always delete the wallet object before creating new - we could be stepping back from recovering wallet
|
|
||||||
if (typeof m_wallet !== 'undefined') {
|
|
||||||
walletManager.closeWallet()
|
|
||||||
console.log("deleting wallet")
|
|
||||||
}
|
|
||||||
|
|
||||||
var tmp_wallet_filename = oshelper.temporaryFilename();
|
|
||||||
console.log("Creating temporary wallet", tmp_wallet_filename)
|
|
||||||
var nettype = appWindow.persistentSettings.nettype;
|
|
||||||
var kdfRounds = appWindow.persistentSettings.kdfRounds;
|
|
||||||
var wallet = walletManager.createWallet(tmp_wallet_filename, "", settingsObject.wallet_language,
|
|
||||||
nettype, kdfRounds)
|
|
||||||
uiItem.wordsTextItem.memoText = wallet.seed
|
|
||||||
// saving wallet in "global" settings object
|
|
||||||
// TODO: wallet should have a property pointing to the file where it stored or loaded from
|
|
||||||
m_wallet = wallet;
|
|
||||||
settingsObject['tmp_wallet_filename'] = tmp_wallet_filename
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardManageWalletUI {
|
|
||||||
id: uiItem
|
|
||||||
titleText: qsTr("Create a new wallet") + translationManager.emptyString
|
|
||||||
wordsTextItem.clipboardButtonVisible: true
|
|
||||||
wordsTextItem.tipTextVisible: true
|
|
||||||
wordsTextItem.memoTextReadOnly: true
|
|
||||||
restoreHeightVisible:false
|
|
||||||
recoverMode: false
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
parent.wizardRestarted.connect(onWizardRestarted)
|
|
||||||
}
|
|
||||||
}
|
|
147
wizard/WizardCreateWallet1.qml
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardCreateWallet1
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property string viewName: "wizardCreateWallet1"
|
||||||
|
property alias seed: seed
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader {
|
||||||
|
title: qsTr("Create a new wallet") + translationManager.emptyString
|
||||||
|
subtitle: qsTr("Creates a new wallet on this computer.") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardWalletInput{
|
||||||
|
id: walletInput
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Layout.topMargin: 10 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
MoneroComponents.LineEditMulti {
|
||||||
|
id: seed
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
inputPaddingLeft: 16 * scaleRatio
|
||||||
|
inputPaddingRight: 16 * scaleRatio
|
||||||
|
inputPaddingTop: 20 * scaleRatio
|
||||||
|
inputPaddingBottom: 20 * scaleRatio
|
||||||
|
inputRadius: 0
|
||||||
|
|
||||||
|
fontSize: 18 * scaleRatio
|
||||||
|
fontBold: true
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
backgroundColor: "red"
|
||||||
|
addressValidation: false
|
||||||
|
labelText: qsTr("Mnemonic seed") + translationManager.emptyString
|
||||||
|
labelFontSize: 14 * scaleRatio
|
||||||
|
copyButton: false
|
||||||
|
readOnly: true
|
||||||
|
|
||||||
|
placeholderText: qsTr("-") + translationManager.emptyString
|
||||||
|
text: wizardController.walletOptionsSeed
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.WarningBox {
|
||||||
|
Rectangle {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
width: 1
|
||||||
|
color: MoneroComponents.Style.inputBorderColorInActive
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
height: 1
|
||||||
|
color: MoneroComponents.Style.inputBorderColorInActive
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
width: 1
|
||||||
|
color: MoneroComponents.Style.inputBorderColorInActive
|
||||||
|
}
|
||||||
|
|
||||||
|
radius: 0
|
||||||
|
border.color: MoneroComponents.Style.inputBorderColorInActive
|
||||||
|
border.width: 0
|
||||||
|
|
||||||
|
text: qsTr("This seed is <b>very</b> important to write down and keep secret. It is all you need to backup and restore your wallet.") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
progressSteps: 4
|
||||||
|
progress: 1
|
||||||
|
btnNext.enabled: walletInput.verify();
|
||||||
|
btnPrev.text: qsTr("Back to menu") + translationManager.emptyString
|
||||||
|
onPrevClicked: {
|
||||||
|
wizardStateView.state = "wizardHome";
|
||||||
|
}
|
||||||
|
onNextClicked: {
|
||||||
|
wizardController.walletOptionsName = walletInput.walletName.text;
|
||||||
|
wizardController.walletOptionsLocation = walletInput.walletLocation.text;
|
||||||
|
wizardStateView.state = "wizardCreateWallet2";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
86
wizard/WizardCreateWallet2.qml
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardCreateWallet2
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property string viewName: "wizardCreateWallet2"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 0 * scaleRatio
|
||||||
|
|
||||||
|
WizardAskPassword {
|
||||||
|
id: passwordFields
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
progressSteps: 4
|
||||||
|
progress: 2
|
||||||
|
btnNext.enabled: passwordFields.calcStrengthAndVerify();
|
||||||
|
onPrevClicked: {
|
||||||
|
if(wizardController.walletOptionsIsRecoveringFromDevice){
|
||||||
|
wizardStateView.state = "wizardCreateDevice1";
|
||||||
|
} else {
|
||||||
|
wizardStateView.state = "wizardCreateWallet1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onNextClicked: {
|
||||||
|
if(appWindow.walletMode === 0 || appWindow.walletMode === 1){
|
||||||
|
wizardController.fetchRemoteNodes(function(){
|
||||||
|
wizardStateView.state = "wizardCreateWallet4";
|
||||||
|
}, function(){
|
||||||
|
appWindow.showStatusMessage(qsTr("Failed to fetch remote nodes from third-party server."), 5);
|
||||||
|
wizardStateView.state = "wizardCreateWallet4";
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
wizardStateView.state = "wizardCreateWallet3";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
78
wizard/WizardCreateWallet3.qml
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardCreateWallet3
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property string viewName: "wizardCreateWallet3"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader {
|
||||||
|
title: qsTr("Daemon settings") + translationManager.emptyString
|
||||||
|
subtitle: qsTr("To be able to communicate with the Monero network your wallet needs to be connected to a Monero node. For best privacy it's recommended to run your own node.") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardDaemonSettings {
|
||||||
|
id: daemonSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
progressSteps: 4
|
||||||
|
progress: 3
|
||||||
|
onPrevClicked: {
|
||||||
|
wizardStateView.state = "wizardCreateWallet2";
|
||||||
|
}
|
||||||
|
onNextClicked: {
|
||||||
|
daemonSettings.save();
|
||||||
|
wizardStateView.state = "wizardCreateWallet4";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
wizard/WizardCreateWallet4.qml
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardCreateWallet4
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property string viewName: "wizardCreateWallet4"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader {
|
||||||
|
title: qsTr("You're all set up!") + translationManager.emptyString
|
||||||
|
subtitle: qsTr("New wallet details:") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardSummary {}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
Layout.topMargin: 24 * scaleRatio
|
||||||
|
btnNextText: qsTr("Open wallet")
|
||||||
|
progressSteps: 4
|
||||||
|
progress: 4
|
||||||
|
|
||||||
|
onPrevClicked: {
|
||||||
|
if (appWindow.walletMode <= 1){
|
||||||
|
wizardStateView.state = "wizardCreateWallet1";
|
||||||
|
} else {
|
||||||
|
wizardStateView.state = "wizardCreateWallet3";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onNextClicked: {
|
||||||
|
wizardController.writeWallet();
|
||||||
|
wizardController.useMoneroClicked();
|
||||||
|
wizardController.walletOptionsIsRecoveringFromDevice = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,124 +0,0 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import QtQuick 2.2
|
|
||||||
import moneroComponents.WalletManager 1.0
|
|
||||||
import moneroComponents.Wallet 1.0
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import QtQuick.Dialogs 1.2
|
|
||||||
import 'utils.js' as Utils
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
opacity: 0
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onOpacityChanged: visible = opacity !== 0
|
|
||||||
|
|
||||||
function onWizardRestarted() {
|
|
||||||
// reset account name field
|
|
||||||
uiItem.accountNameText = defaultAccountName
|
|
||||||
}
|
|
||||||
|
|
||||||
//! function called each time we display this page
|
|
||||||
|
|
||||||
function onPageOpened(settingsOblect) {
|
|
||||||
uiItem.checkNextButton()
|
|
||||||
uiItem.deviceNameDropdown.update()
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPageClosed(settingsObject) {
|
|
||||||
settingsObject['account_name'] = uiItem.accountNameText
|
|
||||||
settingsObject['wallet_path'] = uiItem.walletPath
|
|
||||||
var restoreHeight = parseInt(uiItem.restoreHeight);
|
|
||||||
settingsObject['restore_height'] = isNaN(restoreHeight)? 0 : restoreHeight;
|
|
||||||
settingsObject['subaddress_lookahead'] = uiItem.subaddressLookahead;
|
|
||||||
settingsObject['deviceName'] = uiItem.deviceName;
|
|
||||||
var walletFullPath = wizard.createWalletPath(uiItem.walletPath,uiItem.accountNameText);
|
|
||||||
if (!wizard.walletPathValid(walletFullPath)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return createWalletFromDevice(settingsObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
//! function called each time we hide this page
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
function createWalletFromDevice(settingsObject) {
|
|
||||||
// TODO: create wallet in temporary filename and a) move it to the path specified by user after the final
|
|
||||||
// page submitted or b) delete it when program closed before reaching final page
|
|
||||||
|
|
||||||
// Always delete the wallet object before creating new - we could be stepping back from recovering wallet
|
|
||||||
if (typeof m_wallet !== 'undefined') {
|
|
||||||
walletManager.closeWallet()
|
|
||||||
console.log("deleting wallet")
|
|
||||||
}
|
|
||||||
|
|
||||||
var tmp_wallet_filename = oshelper.temporaryFilename();
|
|
||||||
console.log("Creating temporary wallet", tmp_wallet_filename)
|
|
||||||
var nettype = appWindow.persistentSettings.nettype;
|
|
||||||
var restoreHeight = settingsObject.restore_height;
|
|
||||||
var subaddressLookahead = settingsObject.subaddress_lookahead;
|
|
||||||
var deviceName = settingsObject.deviceName;
|
|
||||||
|
|
||||||
var wallet = walletManager.createWalletFromDevice(tmp_wallet_filename, "", nettype, deviceName, restoreHeight, subaddressLookahead);
|
|
||||||
|
|
||||||
var success = wallet.status === Wallet.Status_Ok;
|
|
||||||
if (success) {
|
|
||||||
m_wallet = wallet;
|
|
||||||
settingsObject['restore_height'] = m_wallet.walletCreationHeight;
|
|
||||||
settingsObject['is_recovering_from_device'] = true;
|
|
||||||
settingsObject['tmp_wallet_filename'] = tmp_wallet_filename
|
|
||||||
} else {
|
|
||||||
console.log(wallet.errorString)
|
|
||||||
walletErrorDialog.text = wallet.errorString;
|
|
||||||
walletErrorDialog.open();
|
|
||||||
walletManager.closeWallet();
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardManageWalletUI {
|
|
||||||
id: uiItem
|
|
||||||
titleText: qsTr("Create a new wallet from hardware device") + translationManager.emptyString
|
|
||||||
wordsTextItem.clipboardButtonVisible: false
|
|
||||||
wordsTextItem.tipTextVisible: false
|
|
||||||
restoreHeightVisible:true
|
|
||||||
recoverMode: false
|
|
||||||
recoverFromDevice: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
parent.wizardRestarted.connect(onWizardRestarted)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -26,171 +26,142 @@
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import moneroComponents.WalletManager 1.0
|
import QtQuick 2.7
|
||||||
import QtQuick 2.2
|
import QtQuick.Dialogs 1.2
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Layouts 1.2
|
||||||
import "../components"
|
import QtQuick.Controls 2.0
|
||||||
import "utils.js" as Utils
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Layout.leftMargin: wizardLeftMargin
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: wizardRightMargin
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 10 * scaleRatio
|
||||||
|
|
||||||
id: passwordPage
|
function save(){
|
||||||
opacity: 0
|
persistentSettings.useRemoteNode = remoteNode.checked
|
||||||
visible: false
|
persistentSettings.remoteNodeAddress = remoteNodeEdit.getAddress();
|
||||||
property alias titleText: titleText.text
|
persistentSettings.bootstrapNodeAddress = bootstrapNodeEdit.daemonAddrText ? bootstrapNodeEdit.getAddress() : "";
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpacityChanged: visible = opacity !== 0
|
MoneroComponents.RadioButton {
|
||||||
|
id: localNode
|
||||||
|
text: qsTr("Start a node automatically in background (recommended)") + translationManager.emptyString
|
||||||
function onPageOpened(settingsObject) {
|
fontSize: 16 * scaleRatio
|
||||||
}
|
checked: !appWindow.persistentSettings.useRemoteNode && !isAndroid && !isIOS
|
||||||
function onWizardRestarted(){
|
visible: !isAndroid && !isIOS
|
||||||
}
|
onClicked: {
|
||||||
|
checked = true;
|
||||||
function onPageClosed(settingsObject) {
|
remoteNode.checked = false;
|
||||||
appWindow.persistentSettings.useRemoteNode = remoteNode.checked
|
|
||||||
appWindow.persistentSettings.remoteNodeAddress = remoteNodeEdit.getAddress();
|
|
||||||
appWindow.persistentSettings.bootstrapNodeAddress = bootstrapNodeEdit.daemonAddrText ? bootstrapNodeEdit.getAddress() : "";
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: dotsRow
|
|
||||||
Layout.alignment: Qt.AlignRight
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: dotsModel
|
|
||||||
ListElement { dotColor: "#36B05B" }
|
|
||||||
ListElement { dotColor: "#36B05B" }
|
|
||||||
ListElement { dotColor: "#FFE00A" }
|
|
||||||
ListElement { dotColor: "#DBDBDB" }
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Repeater {
|
ColumnLayout {
|
||||||
model: dotsModel
|
visible: localNode.checked
|
||||||
delegate: Rectangle {
|
id: blockchainFolderRow
|
||||||
// Password page is last page when creating view only wallet
|
spacing: 20 * scaleRatio
|
||||||
// TODO: make this dynamic for all pages in wizard
|
|
||||||
visible: (wizard.currentPath != "create_view_only_wallet" || index < 2)
|
Layout.topMargin: 8 * scaleRatio
|
||||||
width: 12; height: 12
|
Layout.fillWidth: true
|
||||||
radius: 6
|
|
||||||
color: dotColor
|
MoneroComponents.LineEdit {
|
||||||
|
id: blockchainFolder
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
readOnly: true
|
||||||
|
labelText: qsTr("Blockchain location (optional)") + translationManager.emptyString
|
||||||
|
labelFontSize: 14 * scaleRatio
|
||||||
|
placeholderText: qsTr("Default") + translationManager.emptyString
|
||||||
|
placeholderFontSize: 15 * scaleRatio
|
||||||
|
text: persistentSettings.blockchainDataDir
|
||||||
|
inlineButton.small: true
|
||||||
|
inlineButtonText: qsTr("Browse") + translationManager.emptyString
|
||||||
|
inlineButton.onClicked: {
|
||||||
|
if(persistentSettings.blockchainDataDir != "");
|
||||||
|
blockchainFileDialog.folder = "file://" + persistentSettings.blockchainDataDir;
|
||||||
|
blockchainFileDialog.open();
|
||||||
|
blockchainFolder.focus = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout{
|
||||||
id: headerColumn
|
Layout.topMargin: 6 * scaleRatio
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
Text {
|
TextArea {
|
||||||
Layout.fillWidth: true
|
text: qsTr("Bootstrap node") + translationManager.emptyString
|
||||||
id: titleText
|
Layout.topMargin: 10 * scaleRatio
|
||||||
font.family: "Arial"
|
Layout.fillWidth: true
|
||||||
font.pixelSize: 28 * scaleRatio
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
wrapMode: Text.Wrap
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
horizontalAlignment: Text.AlignHCenter
|
font.pixelSize: {
|
||||||
//renderType: Text.NativeRendering
|
if(wizardController.layoutScale === 2 ){
|
||||||
color: "#3F3F3F"
|
return 22 * scaleRatio;
|
||||||
text: "Daemon settings"
|
} else {
|
||||||
|
return 16 * scaleRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 30 * scaleRatio
|
|
||||||
Layout.bottomMargin: 30 * scaleRatio
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 18 * scaleRatio
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
//renderType: Text.NativeRendering
|
|
||||||
color: "#4A4646"
|
|
||||||
textFormat: Text.RichText
|
|
||||||
// horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: qsTr("To be able to communicate with the Monero network your wallet needs to be connected to a Monero node. For best privacy it's recommended to run your own node. \
|
|
||||||
<br><br> \
|
|
||||||
If you don't have the option to run your own node, there's an option to connect to a remote node.")
|
|
||||||
+ translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
RadioButton {
|
|
||||||
id: localNode
|
|
||||||
text: qsTr("Start a node automatically in background (recommended)") + translationManager.emptyString
|
|
||||||
checkedColor: Qt.rgba(0, 0, 0, 0.75)
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.45)
|
|
||||||
fontColor: "#4A4646"
|
|
||||||
fontSize: 16 * scaleRatio
|
|
||||||
checked: !appWindow.persistentSettings.useRemoteNode && !isAndroid && !isIOS
|
|
||||||
visible: !isAndroid && !isIOS
|
|
||||||
onClicked: {
|
|
||||||
checked = true;
|
|
||||||
remoteNode.checked = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectionColor: MoneroComponents.Style.dimmedFontColor
|
||||||
|
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
||||||
|
|
||||||
|
selectByMouse: true
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
textMargin: 0
|
||||||
|
leftPadding: 0
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextArea {
|
||||||
|
text: qsTr("Additionally, you may specify a bootstrap node to use Monero immediately.") + translationManager.emptyString
|
||||||
|
Layout.topMargin: 4 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
color: MoneroComponents.Style.dimmedFontColor
|
||||||
|
|
||||||
|
font.pixelSize: {
|
||||||
|
if(wizardController.layoutScale === 2 ){
|
||||||
|
return 16 * scaleRatio;
|
||||||
|
} else {
|
||||||
|
return 14 * scaleRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectionColor: MoneroComponents.Style.dimmedFontColor
|
||||||
|
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
||||||
|
|
||||||
|
selectByMouse: true
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
textMargin: 0
|
||||||
|
leftPadding: 0
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
readOnly: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
visible: localNode.checked
|
spacing: 8
|
||||||
id: blockchainFolderRow
|
Layout.fillWidth: true
|
||||||
Label {
|
Layout.bottomMargin: 12 * scaleRatio
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 20 * scaleRatio
|
|
||||||
fontSize: 14 * scaleRatio
|
|
||||||
fontColor: "black"
|
|
||||||
text: qsTr("Blockchain location") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
LineEdit {
|
|
||||||
id: blockchainFolder
|
|
||||||
Layout.preferredWidth: 200 * scaleRatio
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: persistentSettings.blockchainDataDir
|
|
||||||
placeholderFontBold: true
|
|
||||||
placeholderFontFamily: "Arial"
|
|
||||||
placeholderColor: Style.legacy_placeholderFontColor
|
|
||||||
placeholderOpacity: 1.0
|
|
||||||
placeholderText: qsTr("(optional)") + translationManager.emptyString
|
|
||||||
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.15)
|
MoneroComponents.RemoteNodeEdit {
|
||||||
backgroundColor: "white"
|
|
||||||
fontColor: "black"
|
|
||||||
fontBold: false
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
mouse.accepted = false
|
|
||||||
if(persistentSettings.blockchainDataDir != "")
|
|
||||||
blockchainFileDialog.folder = "file://" + persistentSettings.blockchainDataDir
|
|
||||||
blockchainFileDialog.open()
|
|
||||||
blockchainFolder.focus = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 20 * scaleRatio
|
|
||||||
fontSize: 14 * scaleRatio
|
|
||||||
color: 'black'
|
|
||||||
text: qsTr("Bootstrap node (leave blank if not wanted)") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
RemoteNodeEdit {
|
|
||||||
Layout.minimumWidth: 300 * scaleRatio
|
|
||||||
opacity: localNode.checked
|
|
||||||
id: bootstrapNodeEdit
|
id: bootstrapNodeEdit
|
||||||
|
Layout.minimumWidth: 300 * scaleRatio
|
||||||
|
|
||||||
placeholderFontBold: true
|
//labelText: qsTr("Bootstrap node (leave blank if not wanted)") + translationManager.emptyString
|
||||||
placeholderFontFamily: "Arial"
|
|
||||||
placeholderColor: Style.legacy_placeholderFontColor
|
lineEditBackgroundColor: "transparent"
|
||||||
placeholderOpacity: 1.0
|
lineEditFontColor: MoneroComponents.Style.defaultFontColor
|
||||||
|
lineEditFontBold: false
|
||||||
|
lineEditBorderColor: Qt.rgba(255, 255, 255, 0.35)
|
||||||
|
labelFontSize: 14 * scaleRatio
|
||||||
|
placeholderFontSize: 15 * scaleRatio
|
||||||
|
|
||||||
daemonAddrText: persistentSettings.bootstrapNodeAddress.split(":")[0].trim()
|
daemonAddrText: persistentSettings.bootstrapNodeAddress.split(":")[0].trim()
|
||||||
daemonPortText: {
|
daemonPortText: {
|
||||||
|
@ -203,48 +174,41 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
RadioButton {
|
|
||||||
id: remoteNode
|
|
||||||
text: qsTr("Connect to a remote node") + translationManager.emptyString
|
|
||||||
checkedColor: Qt.rgba(0, 0, 0, 0.75)
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.45)
|
|
||||||
Layout.topMargin: 20 * scaleRatio
|
|
||||||
fontColor: "#4A4646"
|
|
||||||
fontSize: 16 * scaleRatio
|
|
||||||
checked: appWindow.persistentSettings.useRemoteNode
|
|
||||||
onClicked: {
|
|
||||||
checked = true
|
|
||||||
localNode.checked = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
RemoteNodeEdit {
|
MoneroComponents.RadioButton {
|
||||||
Layout.minimumWidth: 300 * scaleRatio
|
id: remoteNode
|
||||||
opacity: remoteNode.checked
|
text: qsTr("Connect to a remote node") + translationManager.emptyString
|
||||||
id: remoteNodeEdit
|
checkedColor: Qt.rgba(0, 0, 0, 0.75)
|
||||||
property var rna: persistentSettings.remoteNodeAddress
|
borderColor: Qt.rgba(0, 0, 0, 0.45)
|
||||||
daemonAddrText: rna.search(":") != -1 ? rna.split(":")[0].trim() : ""
|
Layout.topMargin: 20 * scaleRatio
|
||||||
daemonPortText: rna.search(":") != -1 ? (rna.split(":")[1].trim() == "") ? appWindow.getDefaultDaemonRpcPort(persistentSettings.nettype) : persistentSettings.remoteNodeAddress.split(":")[1] : ""
|
fontColor: "#4A4646"
|
||||||
|
fontSize: 16 * scaleRatio
|
||||||
placeholderFontBold: true
|
checked: appWindow.persistentSettings.useRemoteNode
|
||||||
placeholderFontFamily: "Arial"
|
onClicked: {
|
||||||
placeholderColor: Style.legacy_placeholderFontColor
|
checked = true
|
||||||
placeholderOpacity: 1.0
|
localNode.checked = false
|
||||||
|
|
||||||
lineEditBorderColor: Qt.rgba(0, 0, 0, 0.15)
|
|
||||||
lineEditBackgroundColor: "white"
|
|
||||||
lineEditFontColor: "black"
|
|
||||||
lineEditFontBold: false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
MoneroComponents.RemoteNodeEdit {
|
||||||
|
Layout.minimumWidth: 300 * scaleRatio
|
||||||
|
opacity: remoteNode.checked
|
||||||
|
id: remoteNodeEdit
|
||||||
|
property var rna: persistentSettings.remoteNodeAddress
|
||||||
|
daemonAddrText: rna.search(":") != -1 ? rna.split(":")[0].trim() : ""
|
||||||
|
daemonPortText: rna.search(":") != -1 ? (rna.split(":")[1].trim() == "") ? appWindow.getDefaultDaemonRpcPort(persistentSettings.nettype) : persistentSettings.remoteNodeAddress.split(":")[1] : ""
|
||||||
|
|
||||||
Component.onCompleted: {
|
lineEditBackgroundColor: "transparent"
|
||||||
parent.wizardRestarted.connect(onWizardRestarted)
|
lineEditFontColor: MoneroComponents.Style.defaultFontColor
|
||||||
|
lineEditFontBold: false
|
||||||
|
lineEditBorderColor: Qt.rgba(255, 255, 255, 0.35)
|
||||||
|
labelFontSize: 14 * scaleRatio
|
||||||
|
placeholderFontSize: 15 * scaleRatio
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,196 +0,0 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import QtQuick 2.2
|
|
||||||
import "../components"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
opacity: 0
|
|
||||||
visible: false
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpacityChanged: visible = opacity !== 0
|
|
||||||
|
|
||||||
function onPageOpened(settingsObject) {
|
|
||||||
enableAutoDonationCheckBox.checked = settingsObject.auto_donations_enabled
|
|
||||||
autoDonationAmountText.text = settingsObject.auto_donations_amount
|
|
||||||
allowBackgroundMiningCheckBox.checked = settingsObject.allow_background_mining
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPageClosed(settingsObject) {
|
|
||||||
settingsObject['auto_donations_enabled'] = enableAutoDonationCheckBox.checked;
|
|
||||||
settingsObject['auto_donations_amount'] = parseInt(autoDonationAmountText.text);
|
|
||||||
settingsObject['allow_background_mining'] = allowBackgroundMiningCheckBox.checked;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: dotsRow
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.topMargin: 85
|
|
||||||
spacing: 6
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: dotsModel
|
|
||||||
ListElement { dotColor: "#36B05B" }
|
|
||||||
ListElement { dotColor: "#36B05B" }
|
|
||||||
ListElement { dotColor: "#36B05B" }
|
|
||||||
ListElement { dotColor: "#FFE00A" }
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: dotsModel
|
|
||||||
delegate: Rectangle {
|
|
||||||
width: 12; height: 12
|
|
||||||
radius: 6
|
|
||||||
color: dotColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: headerText
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 74
|
|
||||||
anchors.leftMargin: 16
|
|
||||||
width: parent.width - dotsRow.width - 16
|
|
||||||
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 28
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
//renderType: Text.NativeRendering
|
|
||||||
color: "#3F3F3F"
|
|
||||||
text: qsTr("Monero development is solely supported by donations") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
anchors.top: headerText.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.leftMargin: 16
|
|
||||||
anchors.rightMargin: 16
|
|
||||||
anchors.topMargin: 34
|
|
||||||
spacing: 12
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
spacing: 2
|
|
||||||
|
|
||||||
CheckBox {
|
|
||||||
id: enableAutoDonationCheckBox
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
text: qsTr("Enable auto-donations of?") + translationManager.emptyString
|
|
||||||
background: "#F0EEEE"
|
|
||||||
fontColor: "#4A4646"
|
|
||||||
fontSize: 18
|
|
||||||
checked: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
height: 30
|
|
||||||
width: 41
|
|
||||||
|
|
||||||
TextInput {
|
|
||||||
id: autoDonationAmountText
|
|
||||||
anchors.fill: parent
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 18
|
|
||||||
color: "#6B0072"
|
|
||||||
text: "50"
|
|
||||||
validator: IntValidator { bottom: 0; top: 100 }
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
height: 1
|
|
||||||
color: "#DBDBDB"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 18
|
|
||||||
color: "#4A4646"
|
|
||||||
text: qsTr("% of my fee added to each transaction") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 15
|
|
||||||
color: "#4A4646"
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
text: qsTr("For every transaction, a small transaction fee is charged. This option lets you add an additional amount, " +
|
|
||||||
"as a percentage of that fee, to your transaction to support Monero development. For instance, a 50% " +
|
|
||||||
"autodonation take a transaction fee of 0.005 XMR and add a 0.0025 XMR to support Monero development.")
|
|
||||||
+ translationManager.emptyString
|
|
||||||
}
|
|
||||||
Column {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
spacing: 12
|
|
||||||
|
|
||||||
CheckBox {
|
|
||||||
id: allowBackgroundMiningCheckBox
|
|
||||||
text: qsTr("Allow background mining?") + translationManager.emptyString
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
background: "#F0EEEE"
|
|
||||||
fontColor: "#4A4646"
|
|
||||||
fontSize: 18
|
|
||||||
checked: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 15
|
|
||||||
color: "#4A4646"
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
text: qsTr("Mining secures the Monero network, and also pays a small reward for the work done. This option " +
|
|
||||||
"will let Monero mine when your computer is on mains power and is idle. It will stop mining when you continue working.")
|
|
||||||
+ translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,152 +0,0 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import QtQuick 2.2
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import moneroComponents.NetworkType 1.0
|
|
||||||
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.leftMargin: wizardLeftMargin
|
|
||||||
Layout.rightMargin: wizardRightMargin
|
|
||||||
opacity: 0
|
|
||||||
visible: false
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpacityChanged: visible = opacity !== 0
|
|
||||||
|
|
||||||
function buildSettingsString() {
|
|
||||||
var trStart = '<tr><td style="padding-top:5px;"><b>',
|
|
||||||
trMiddle = '</b></td><td style="padding-left:10px;padding-top:5px;">',
|
|
||||||
trEnd = "</td></tr>",
|
|
||||||
autoDonationEnabled = wizard.settings['auto_donations_enabled'] === true,
|
|
||||||
autoDonationText = autoDonationEnabled ? qsTr("Enabled") : qsTr("Disabled"),
|
|
||||||
autoDonationAmount = wizard.settings["auto_donations_amount"] + " %",
|
|
||||||
backgroundMiningEnabled = wizard.settings["allow_background_mining"] === true,
|
|
||||||
backgroundMiningText = backgroundMiningEnabled ? qsTr("Enabled") : qsTr("Disabled"),
|
|
||||||
nettype = appWindow.persistentSettings.nettype,
|
|
||||||
networkText = nettype == NetworkType.TESTNET ? qsTr("Testnet") : nettype == NetworkType.STAGENET ? qsTr("Stagenet") : qsTr("Mainnet"),
|
|
||||||
restoreHeightEnabled = wizard.settings['restore_height'] !== undefined;
|
|
||||||
|
|
||||||
var daemonAddress = persistentSettings.daemon_address;
|
|
||||||
if(persistentSettings.useRemoteNode)
|
|
||||||
{
|
|
||||||
daemonAddress = persistentSettings.remoteNodeAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "<table>"
|
|
||||||
+ trStart + qsTr("Language") + trMiddle + wizard.settings["language"] + trEnd
|
|
||||||
+ trStart + qsTr("Wallet name") + trMiddle + wizard.settings["account_name"] + trEnd
|
|
||||||
// TODO: wizard.settings['wallet'].seed doesnt work anymore; yields undefined.
|
|
||||||
// + trStart + qsTr("Backup seed") + trMiddle + wizard.settings["wallet"].seed + trEnd
|
|
||||||
+ trStart + qsTr("Backup seed") + trMiddle + '****' + trEnd
|
|
||||||
+ trStart + qsTr("Wallet path") + trMiddle + wizard.settings["wallet_path"] + trEnd
|
|
||||||
// + trStart + qsTr("Auto donations") + trMiddle + autoDonationText + trEnd
|
|
||||||
// + (autoDonationEnabled
|
|
||||||
// ? trStart + qsTr("Donation amount") + trMiddle + autoDonationAmount + trEnd
|
|
||||||
// : "")
|
|
||||||
// + trStart + qsTr("Background mining") + trMiddle + backgroundMiningText + trEnd
|
|
||||||
+ trStart + qsTr("Daemon address") + trMiddle + daemonAddress + trEnd
|
|
||||||
+ trStart + qsTr("Network Type") + trMiddle + networkText + trEnd
|
|
||||||
+ (restoreHeightEnabled
|
|
||||||
? trStart + qsTr("Restore height") + trMiddle + wizard.settings['restore_height'] + trEnd
|
|
||||||
: "")
|
|
||||||
+ "</table>"
|
|
||||||
+ translationManager.emptyString;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateSettingsSummary() {
|
|
||||||
if (!isMobile){
|
|
||||||
settingsText.text = qsTr("New wallet details:") + translationManager.emptyString
|
|
||||||
+ "<br>"
|
|
||||||
+ buildSettingsString();
|
|
||||||
} else {
|
|
||||||
settingsText.text = qsTr("Don't forget to write down your seed. You can view your seed and change your settings on settings page.")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPageOpened(settings) {
|
|
||||||
updateSettingsSummary();
|
|
||||||
wizard.nextButton.visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: dotsRow
|
|
||||||
Layout.alignment: Qt.AlignRight
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: dotsModel
|
|
||||||
ListElement { dotColor: "#36B05B" }
|
|
||||||
ListElement { dotColor: "#36B05B" }
|
|
||||||
ListElement { dotColor: "#36B05B" }
|
|
||||||
ListElement { dotColor: "#FFE00A" }
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: dotsModel
|
|
||||||
delegate: Rectangle {
|
|
||||||
width: 12; height: 12
|
|
||||||
radius: 6
|
|
||||||
color: dotColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: headerColumn
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 28 * scaleRatio
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
//renderType: Text.NativeRendering
|
|
||||||
color: "#3F3F3F"
|
|
||||||
text: qsTr("You’re all set up!") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
id: settingsText
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 16 * scaleRatio
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
textFormat: Text.RichText
|
|
||||||
horizontalAlignment: Text.AlignHLeft
|
|
||||||
//renderType: Text.NativeRendering
|
|
||||||
color: "#4A4646"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
96
wizard/WizardHeader.qml
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components"
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
property string title: ""
|
||||||
|
property string subtitle: ""
|
||||||
|
spacing: 4 * scaleRatio
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
|
||||||
|
TextArea {
|
||||||
|
text: title
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
font.pixelSize: {
|
||||||
|
if(wizardController.layoutScale === 2 ){
|
||||||
|
return 34 * scaleRatio;
|
||||||
|
} else {
|
||||||
|
return 28 * scaleRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectionColor: MoneroComponents.Style.dimmedFontColor
|
||||||
|
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
||||||
|
|
||||||
|
selectByMouse: true
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
textMargin: 0
|
||||||
|
leftPadding: 0
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextArea {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
visible: parent.subtitle !== ""
|
||||||
|
|
||||||
|
color: MoneroComponents.Style.dimmedFontColor
|
||||||
|
text: subtitle
|
||||||
|
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: {
|
||||||
|
if(wizardController.layoutScale === 2 ){
|
||||||
|
return 16 * scaleRatio;
|
||||||
|
} else {
|
||||||
|
return 14 * scaleRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectionColor: MoneroComponents.Style.dimmedFontColor
|
||||||
|
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
||||||
|
|
||||||
|
selectByMouse: true
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
textMargin: 0
|
||||||
|
leftPadding: 0
|
||||||
|
topPadding: 0
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
}
|
250
wizard/WizardHome.qml
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
import moneroComponents.NetworkType 1.0
|
||||||
|
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardHome
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
property string viewName: "wizardHome"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 10 * scaleRatio
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 0 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader {
|
||||||
|
Layout.bottomMargin: 20 * scaleRatio
|
||||||
|
title: qsTr("Welcome to Monero.") + translationManager.emptyString
|
||||||
|
subtitle: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardMenuItem {
|
||||||
|
headerText: qsTr("Create a new wallet") + translationManager.emptyString
|
||||||
|
bodyText: qsTr("Choose this option if this is your first time using Monero.") + translationManager.emptyString
|
||||||
|
imageIcon: "../images/create-wallet.png"
|
||||||
|
|
||||||
|
onMenuClicked: {
|
||||||
|
wizardController.restart();
|
||||||
|
wizardController.createWallet();
|
||||||
|
wizardStateView.state = "wizardCreateWallet1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredHeight: 1
|
||||||
|
Layout.topMargin: 3 * scaleRatio
|
||||||
|
Layout.bottomMargin: 3 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: MoneroComponents.Style.dividerColor
|
||||||
|
opacity: MoneroComponents.Style.dividerOpacity
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardMenuItem {
|
||||||
|
headerText: qsTr("Create a new wallet from hardware") + translationManager.emptyString
|
||||||
|
bodyText: qsTr("Connect your hardware wallet to create a new Monero wallet.") + translationManager.emptyString
|
||||||
|
imageIcon: "../images/restore-wallet-from-hardware.png"
|
||||||
|
|
||||||
|
onMenuClicked: {
|
||||||
|
wizardController.restart();
|
||||||
|
wizardStateView.state = "wizardCreateDevice1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredHeight: 1
|
||||||
|
Layout.topMargin: 3 * scaleRatio
|
||||||
|
Layout.bottomMargin: 3 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: MoneroComponents.Style.dividerColor
|
||||||
|
opacity: MoneroComponents.Style.dividerOpacity
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardMenuItem {
|
||||||
|
headerText: qsTr("Open a wallet from file") + translationManager.emptyString
|
||||||
|
bodyText: qsTr("Import an existing .keys wallet file from your computer.") + translationManager.emptyString
|
||||||
|
imageIcon: "../images/open-wallet-from-file.png"
|
||||||
|
|
||||||
|
onMenuClicked: {
|
||||||
|
wizardStateView.state = "wizardOpenWallet1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredHeight: 1
|
||||||
|
Layout.topMargin: 3 * scaleRatio
|
||||||
|
Layout.bottomMargin: 3 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: MoneroComponents.Style.dividerColor
|
||||||
|
opacity: MoneroComponents.Style.dividerOpacity
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardMenuItem {
|
||||||
|
headerText: qsTr("Restore wallet from keys or mnemonic seed") + translationManager.emptyString
|
||||||
|
bodyText: qsTr("Enter your private keys or 25-word mnemonic seed to restore your wallet.") + translationManager.emptyString
|
||||||
|
imageIcon: "../images/restore-wallet.png"
|
||||||
|
|
||||||
|
onMenuClicked: {
|
||||||
|
wizardController.restart();
|
||||||
|
wizardController.createWallet();
|
||||||
|
wizardStateView.state = "wizardRestoreWallet1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16 * scaleRatio
|
||||||
|
spacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
small: true
|
||||||
|
text: qsTr("Change wallet mode") + translationManager.emptyString
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
wizardController.wizardState = 'wizardModeSelection';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
visible: !persistentSettings.customDecorations
|
||||||
|
small: true
|
||||||
|
text: qsTr("Change language") + translationManager.emptyString
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
wizardController.skipModeSelection = true;
|
||||||
|
wizardController.wizardState = 'wizardLanguage';
|
||||||
|
languageSidebar.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.CheckBox2 {
|
||||||
|
id: showAdvancedCheckbox
|
||||||
|
Layout.topMargin: 30 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
fontSize: 15 * scaleRatio
|
||||||
|
checked: false
|
||||||
|
text: qsTr("Advanced options") + translationManager.emptyString
|
||||||
|
visible: appWindow.walletMode >= 2
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: networkTypeModel
|
||||||
|
// @TODO: try real enums
|
||||||
|
ListElement {column1: "Mainnet"; column2: ""; nettype: "mainnet"}
|
||||||
|
ListElement {column1: "Testnet"; column2: ""; nettype: "testnet"}
|
||||||
|
ListElement {column1: "Stagenet"; column2: ""; nettype: "stagenet"}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
visible: showAdvancedCheckbox.checked && appWindow.walletMode >= 2
|
||||||
|
columns: 4
|
||||||
|
columnSpacing: 20
|
||||||
|
|
||||||
|
MoneroComponents.StandardDropdown {
|
||||||
|
id: networkTypeDropdown
|
||||||
|
dataModel: networkTypeModel
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 41
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#363636"
|
||||||
|
pressedColor: "#202020"
|
||||||
|
|
||||||
|
onChanged: {
|
||||||
|
var item = dataModel.get(currentIndex).nettype.toLowerCase();
|
||||||
|
if(item === "mainnet") {
|
||||||
|
persistentSettings.nettype = NetworkType.MAINNET
|
||||||
|
} else if(item === "stagenet"){
|
||||||
|
persistentSettings.nettype = NetworkType.STAGENET
|
||||||
|
} else if(item === "testnet"){
|
||||||
|
persistentSettings.nettype = NetworkType.TESTNET
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.LineEdit {
|
||||||
|
id: kdfRoundsText
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
labelText: qsTr("Number of KDF rounds:") + translationManager.emptyString
|
||||||
|
labelFontSize: 14 * scaleRatio
|
||||||
|
placeholderFontSize: 16 * scaleRatio
|
||||||
|
placeholderText: "0"
|
||||||
|
validator: IntValidator { bottom: 1 }
|
||||||
|
text: persistentSettings.kdfRounds ? persistentSettings.kdfRounds : "1"
|
||||||
|
onTextChanged: {
|
||||||
|
console.log('x');
|
||||||
|
kdfRoundsText.text = persistentSettings.kdfRounds = parseInt(kdfRoundsText.text) >= 1 ? parseInt(kdfRoundsText.text) : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 200;
|
||||||
|
easing.type: Easing.InCubic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
networkTypeDropdown.currentIndex = persistentSettings.nettype;
|
||||||
|
networkTypeDropdown.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPageCompleted(){
|
||||||
|
wizardController.walletOptionsIsRecoveringFromDevice = false;
|
||||||
|
}
|
||||||
|
}
|
253
wizard/WizardLanguage.qml
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../components"
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
import "../version.js" as Version
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: "black"
|
||||||
|
|
||||||
|
property string viewName: "wizardLanguage"
|
||||||
|
|
||||||
|
Image {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: "../images/middlePanelBg.jpg"
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: root
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
spacing: 30 * scaleRatio
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
// some margins for the titlebar
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 0
|
||||||
|
color: "transparent"
|
||||||
|
}
|
||||||
|
|
||||||
|
TextArea {
|
||||||
|
id: textWelcome
|
||||||
|
opacity: 0
|
||||||
|
Layout.preferredWidth: parent.width / 1.3
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
text: "Welcome - Wilkommen - Bonvenon - Bienvenido - Bienvenue - Välkommen - Selamat datang - Benvenuto - 歡迎 - Welkom - Bem Vindo - добро пожаловать"
|
||||||
|
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 18 * scaleRatio
|
||||||
|
horizontalAlignment: TextInput.AlignHCenter
|
||||||
|
selectByMouse: false
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
textMargin: 0
|
||||||
|
leftPadding: 0
|
||||||
|
topPadding: 0
|
||||||
|
readOnly: true
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 350;
|
||||||
|
easing.type: Easing.InCubic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: globe
|
||||||
|
source: "../images/world-flags-globe.png"
|
||||||
|
opacity: 0
|
||||||
|
property bool small: appWindow.width < 700 ? true : false
|
||||||
|
property int size: {
|
||||||
|
if(small){
|
||||||
|
return 196;
|
||||||
|
} else {
|
||||||
|
return 312;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Layout.preferredWidth: size
|
||||||
|
Layout.preferredHeight: size
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
mipmap: true
|
||||||
|
|
||||||
|
property bool animSlow: false
|
||||||
|
property int animSpeedSlow: 4000
|
||||||
|
property int animSpeedNormal: 120000
|
||||||
|
property real animFrom: 0
|
||||||
|
property real animTo: 360
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
visible: !globe.small
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.leftMargin: 117 * scaleRatio
|
||||||
|
anchors.topMargin: 71 * scaleRatio
|
||||||
|
width: 36 * scaleRatio
|
||||||
|
height: 40 * scaleRatio
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
anim.stop();
|
||||||
|
globe.animFrom = globe.rotation;
|
||||||
|
globe.animTo = globe.animFrom + 360;
|
||||||
|
anim.duration = globe.animSlow ? globe.animSpeedNormal : globe.animSpeedSlow;
|
||||||
|
globe.animSlow = !globe.animSlow;
|
||||||
|
anim.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 450;
|
||||||
|
easing.type: Easing.InCubic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RotationAnimation on rotation {
|
||||||
|
id: anim
|
||||||
|
loops: Animation.Infinite
|
||||||
|
from: globe.animFrom
|
||||||
|
to: globe.animTo
|
||||||
|
duration: globe.animSpeedNormal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: buttonsGrid
|
||||||
|
opacity: 0
|
||||||
|
columns: isMobile ? 1 : 2
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
Layout.topMargin: 20 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
columnSpacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
id: idChangeLang
|
||||||
|
Layout.minimumWidth: 150 * scaleRatio
|
||||||
|
text: "Language"
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
languageSidebar.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
id: btnContinue
|
||||||
|
Layout.minimumWidth: 150 * scaleRatio
|
||||||
|
text: "Continue"
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if(wizardController.skipModeSelection){
|
||||||
|
wizardStateView.state = "wizardHome"
|
||||||
|
} else {
|
||||||
|
wizardStateView.state = "wizardModeSelection"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 350;
|
||||||
|
easing.type: Easing.InCubic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: versionText
|
||||||
|
opacity: 0
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 12 * scaleRatio
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
text: Version.GUI_VERSION + " (Qt " + qtRuntimeVersion + ")"
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 350;
|
||||||
|
easing.type: Easing.InCubic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
// opacity effects
|
||||||
|
delay(textTimer, 100, function() {
|
||||||
|
textWelcome.opacity = 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
delay(globeTimer, 150, function() {
|
||||||
|
globe.opacity = 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
delay(buttonTimer, 250, function() {
|
||||||
|
buttonsGrid.opacity = 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
delay(versionTimer, 350, function() {
|
||||||
|
versionText.opacity = 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function delay(timer, interval, cb) {
|
||||||
|
timer.interval = interval;
|
||||||
|
timer.repeat = false;
|
||||||
|
timer.triggered.connect(cb);
|
||||||
|
timer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: globeTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: textTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: buttonTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: versionTimer
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,435 +0,0 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import QtQuick 2.2
|
|
||||||
import Qt.labs.settings 1.0
|
|
||||||
import QtQuick.Dialogs 1.2
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
|
|
||||||
import "../components"
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
Layout.fillHeight: true
|
|
||||||
id: wizard
|
|
||||||
property alias nextButton : nextButton
|
|
||||||
property var settings : ({})
|
|
||||||
property int currentPage: 0
|
|
||||||
property int wizardLeftMargin: (!isMobile) ? 150 : 25 * scaleRatio
|
|
||||||
property int wizardRightMargin: (!isMobile) ? 150 : 25 * scaleRatio
|
|
||||||
property int wizardBottomMargin: (isMobile) ? 150 : 25 * scaleRatio
|
|
||||||
property int wizardTopMargin: (isMobile) ? 15 * scaleRatio : 50
|
|
||||||
// Storing wallet in Settings object doesn't work in qt 5.8 on android
|
|
||||||
property var m_wallet;
|
|
||||||
|
|
||||||
property var paths: {
|
|
||||||
// "create_wallet" : [welcomePage, optionsPage, createWalletPage, passwordPage, donationPage, finishPage ],
|
|
||||||
// "recovery_wallet" : [welcomePage, optionsPage, recoveryWalletPage, passwordPage, donationPage, finishPage ],
|
|
||||||
// disable donation page
|
|
||||||
"create_wallet" : [welcomePage, optionsPage, createWalletPage, passwordPage, daemonSettingsPage, finishPage ],
|
|
||||||
"recovery_wallet" : [welcomePage, optionsPage, recoveryWalletPage, passwordPage, daemonSettingsPage, finishPage ],
|
|
||||||
"create_view_only_wallet" : [ createViewOnlyWalletPage, passwordPage ],
|
|
||||||
"create_wallet_from_device" : [welcomePage, optionsPage, createWalletFromDevicePage, passwordPage, daemonSettingsPage, finishPage ],
|
|
||||||
|
|
||||||
}
|
|
||||||
property string currentPath: "create_wallet"
|
|
||||||
property var pages: paths[currentPath]
|
|
||||||
|
|
||||||
signal wizardRestarted();
|
|
||||||
signal useMoneroClicked()
|
|
||||||
signal openWalletFromFileClicked()
|
|
||||||
// border.color: "#DBDBDB"
|
|
||||||
// border.width: 1
|
|
||||||
// color: "#FFFFFF"
|
|
||||||
|
|
||||||
function restart(){
|
|
||||||
wizard.currentPage = 0;
|
|
||||||
wizard.settings = ({})
|
|
||||||
wizard.currentPath = "create_wallet"
|
|
||||||
wizard.pages = paths[currentPath]
|
|
||||||
wizardRestarted();
|
|
||||||
|
|
||||||
//hide all pages except first
|
|
||||||
for (var i = 1; i < wizard.pages.length; i++){
|
|
||||||
wizard.pages[i].opacity = 0;
|
|
||||||
}
|
|
||||||
//Show first pages
|
|
||||||
wizard.pages[0].opacity = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchPage(next) {
|
|
||||||
|
|
||||||
// Android focus workaround
|
|
||||||
releaseFocus();
|
|
||||||
|
|
||||||
// save settings for current page;
|
|
||||||
if (next && typeof pages[currentPage].onPageClosed !== 'undefined') {
|
|
||||||
if (pages[currentPage].onPageClosed(settings) !== true) {
|
|
||||||
print ("Can't go to the next page");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
console.log("switchpage: currentPage: ", currentPage);
|
|
||||||
|
|
||||||
// Update prev/next button positions for mobile/desktop
|
|
||||||
prevButton.anchors.verticalCenter = (!isMobile) ? wizard.verticalCenter : undefined
|
|
||||||
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) {
|
|
||||||
pages[currentPage].opacity = 0
|
|
||||||
var step_value = next ? 1 : -1
|
|
||||||
currentPage += step_value
|
|
||||||
pages[currentPage].opacity = 1;
|
|
||||||
|
|
||||||
var nextButtonVisible = currentPage > 1 && currentPage < pages.length - 1
|
|
||||||
nextButton.visible = nextButtonVisible
|
|
||||||
|
|
||||||
if (typeof pages[currentPage].onPageOpened !== 'undefined') {
|
|
||||||
pages[currentPage].onPageOpened(settings,next)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function openCreateWalletPage() {
|
|
||||||
wizardRestarted();
|
|
||||||
print ("show create wallet page");
|
|
||||||
currentPath = "create_wallet"
|
|
||||||
pages = paths[currentPath]
|
|
||||||
createWalletPage.createWallet(settings)
|
|
||||||
wizard.nextButton.visible = true
|
|
||||||
// goto next page
|
|
||||||
switchPage(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function openRecoveryWalletPage() {
|
|
||||||
wizardRestarted();
|
|
||||||
print ("show recovery wallet page");
|
|
||||||
currentPath = "recovery_wallet"
|
|
||||||
pages = paths[currentPath]
|
|
||||||
// Create temporary wallet
|
|
||||||
createWalletPage.createWallet(settings)
|
|
||||||
wizard.nextButton.visible = true
|
|
||||||
// goto next page
|
|
||||||
switchPage(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function openOpenWalletPage() {
|
|
||||||
console.log("open wallet from file page");
|
|
||||||
if (typeof m_wallet !== 'undefined' && m_wallet != null) {
|
|
||||||
walletManager.closeWallet()
|
|
||||||
}
|
|
||||||
optionsPage.onPageClosed(settings)
|
|
||||||
wizard.openWalletFromFileClicked();
|
|
||||||
}
|
|
||||||
|
|
||||||
function openCreateViewOnlyWalletPage(){
|
|
||||||
pages[currentPage].opacity = 0
|
|
||||||
currentPath = "create_view_only_wallet"
|
|
||||||
pages = paths[currentPath]
|
|
||||||
currentPage = pages.indexOf(createViewOnlyWalletPage)
|
|
||||||
createViewOnlyWalletPage.opacity = 1
|
|
||||||
nextButton.visible = true
|
|
||||||
rootItem.state = "wizard";
|
|
||||||
}
|
|
||||||
|
|
||||||
function openCreateWalletFromDevicePage() {
|
|
||||||
wizardRestarted();
|
|
||||||
print ("show create wallet from device page");
|
|
||||||
currentPath = "create_wallet_from_device"
|
|
||||||
pages = paths[currentPath]
|
|
||||||
wizard.nextButton.visible = true
|
|
||||||
// goto next page
|
|
||||||
switchPage(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createWalletPath(folder_path,account_name){
|
|
||||||
|
|
||||||
// Remove trailing slash - (default on windows and mac)
|
|
||||||
if (folder_path.substring(folder_path.length -1) === "/"){
|
|
||||||
folder_path = folder_path.substring(0,folder_path.length -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store releative path on ios.
|
|
||||||
if(isIOS)
|
|
||||||
folder_path = "";
|
|
||||||
|
|
||||||
return folder_path + "/" + account_name + "/" + account_name
|
|
||||||
}
|
|
||||||
|
|
||||||
function walletPathValid(path){
|
|
||||||
if(isIOS)
|
|
||||||
path = moneroAccountsDir + path;
|
|
||||||
if (walletManager.walletExists(path)) {
|
|
||||||
walletErrorDialog.text = qsTr("A wallet with same name already exists. Please change wallet name") + translationManager.emptyString;
|
|
||||||
walletErrorDialog.open();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isAscii(str){
|
|
||||||
for (var i = 0; i < str.length; i++) {
|
|
||||||
if (str.charCodeAt(i) > 127)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! actually writes the wallet
|
|
||||||
function applySettings() {
|
|
||||||
// Save wallet files in user specified location
|
|
||||||
var new_wallet_filename = createWalletPath(settings.wallet_path,settings.account_name)
|
|
||||||
if(isIOS) {
|
|
||||||
console.log("saving in ios: "+ moneroAccountsDir + new_wallet_filename)
|
|
||||||
m_wallet.store(moneroAccountsDir + new_wallet_filename);
|
|
||||||
} else {
|
|
||||||
console.log("saving in wizard: "+ new_wallet_filename)
|
|
||||||
m_wallet.store(new_wallet_filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// make sure temporary wallet files are deleted
|
|
||||||
console.log("Removing temporary wallet: "+ settings.tmp_wallet_filename)
|
|
||||||
oshelper.removeTemporaryWallet(settings.tmp_wallet_filename)
|
|
||||||
|
|
||||||
// protecting wallet with password
|
|
||||||
m_wallet.setPassword(settings.wallet_password);
|
|
||||||
|
|
||||||
// Store password in session to be able to use password protected functions (e.g show seed)
|
|
||||||
appWindow.walletPassword = settings.wallet_password
|
|
||||||
|
|
||||||
// saving wallet_filename;
|
|
||||||
settings['wallet_filename'] = new_wallet_filename;
|
|
||||||
|
|
||||||
// persist settings
|
|
||||||
appWindow.persistentSettings.language = settings.language
|
|
||||||
appWindow.persistentSettings.locale = settings.locale
|
|
||||||
appWindow.persistentSettings.account_name = settings.account_name
|
|
||||||
appWindow.persistentSettings.wallet_path = new_wallet_filename
|
|
||||||
appWindow.persistentSettings.allow_background_mining = false //settings.allow_background_mining
|
|
||||||
appWindow.persistentSettings.auto_donations_enabled = false //settings.auto_donations_enabled
|
|
||||||
appWindow.persistentSettings.auto_donations_amount = false //settings.auto_donations_amount
|
|
||||||
appWindow.persistentSettings.restore_height = (isNaN(settings.restore_height))? 0 : settings.restore_height
|
|
||||||
appWindow.persistentSettings.is_recovering = (settings.is_recovering === undefined)? false : settings.is_recovering
|
|
||||||
appWindow.persistentSettings.is_recovering_from_device = (settings.is_recovering_from_device === undefined)? false : settings.is_recovering_from_device
|
|
||||||
}
|
|
||||||
|
|
||||||
// reading settings from persistent storage
|
|
||||||
Component.onCompleted: {
|
|
||||||
settings['allow_background_mining'] = appWindow.persistentSettings.allow_background_mining
|
|
||||||
settings['auto_donations_enabled'] = appWindow.persistentSettings.auto_donations_enabled
|
|
||||||
settings['auto_donations_amount'] = appWindow.persistentSettings.auto_donations_amount
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageDialog {
|
|
||||||
id: walletErrorDialog
|
|
||||||
title: "Error"
|
|
||||||
onAccepted: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardWelcome {
|
|
||||||
id: welcomePage
|
|
||||||
// Layout.bottomMargin: wizardBottomMargin
|
|
||||||
Layout.topMargin: wizardTopMargin
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardOptions {
|
|
||||||
id: optionsPage
|
|
||||||
Layout.bottomMargin: wizardBottomMargin
|
|
||||||
Layout.topMargin: wizardTopMargin
|
|
||||||
onCreateWalletClicked: wizard.openCreateWalletPage()
|
|
||||||
onRecoveryWalletClicked: wizard.openRecoveryWalletPage()
|
|
||||||
onOpenWalletClicked: wizard.openOpenWalletPage();
|
|
||||||
onCreateWalletFromDeviceClicked: wizard.openCreateWalletFromDevicePage()
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardCreateWallet {
|
|
||||||
id: createWalletPage
|
|
||||||
Layout.bottomMargin: wizardBottomMargin
|
|
||||||
Layout.topMargin: wizardTopMargin
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardCreateViewOnlyWallet {
|
|
||||||
id: createViewOnlyWalletPage
|
|
||||||
Layout.bottomMargin: wizardBottomMargin
|
|
||||||
Layout.topMargin: wizardTopMargin
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardRecoveryWallet {
|
|
||||||
id: recoveryWalletPage
|
|
||||||
Layout.bottomMargin: wizardBottomMargin
|
|
||||||
Layout.topMargin: wizardTopMargin
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardCreateWalletFromDevice {
|
|
||||||
id: createWalletFromDevicePage
|
|
||||||
Layout.bottomMargin: wizardBottomMargin
|
|
||||||
Layout.topMargin: wizardTopMargin
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardPassword {
|
|
||||||
id: passwordPage
|
|
||||||
Layout.bottomMargin: wizardBottomMargin
|
|
||||||
Layout.topMargin: wizardTopMargin
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardDaemonSettings {
|
|
||||||
id: daemonSettingsPage
|
|
||||||
Layout.bottomMargin: wizardBottomMargin
|
|
||||||
Layout.topMargin: wizardTopMargin
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardDonation {
|
|
||||||
id: donationPage
|
|
||||||
Layout.bottomMargin: wizardBottomMargin
|
|
||||||
Layout.topMargin: wizardTopMargin
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardFinish {
|
|
||||||
id: finishPage
|
|
||||||
Layout.bottomMargin: wizardBottomMargin
|
|
||||||
Layout.topMargin: wizardTopMargin
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: prevButton
|
|
||||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
|
||||||
Layout.leftMargin: isMobile ? 20 : 50
|
|
||||||
Layout.bottomMargin: isMobile ? 20 * scaleRatio : 50
|
|
||||||
visible: parent.currentPage > 0
|
|
||||||
|
|
||||||
width: 50 * scaleRatio; height: 50 * scaleRatio
|
|
||||||
radius: 25
|
|
||||||
color: prevArea.containsMouse ? "#FF4304" : "#FF6C3C"
|
|
||||||
|
|
||||||
Image {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
anchors.horizontalCenterOffset: -3
|
|
||||||
source: "qrc:///images/nextPage.png"
|
|
||||||
transformOrigin: Item.Center
|
|
||||||
rotation: 180
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: prevArea
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: wizard.switchPage(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: nextButton
|
|
||||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
|
||||||
Layout.rightMargin: isMobile ? 20 * scaleRatio : 50
|
|
||||||
Layout.bottomMargin: isMobile ? 20 * scaleRatio : 50
|
|
||||||
visible: currentPage > 1 && currentPage < pages.length - 1
|
|
||||||
width: 50 * scaleRatio; height: 50 * scaleRatio
|
|
||||||
radius: 25
|
|
||||||
color: enabled ? nextArea.containsMouse ? "#FF4304" : "#FF6C3C" : "#DBDBDB"
|
|
||||||
|
|
||||||
|
|
||||||
Image {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
anchors.horizontalCenterOffset: 3
|
|
||||||
source: "qrc:///images/nextPage.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: nextArea
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: wizard.switchPage(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StandardButton {
|
|
||||||
id: sendButton
|
|
||||||
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
|
|
||||||
Layout.margins: (isMobile) ? 20 * scaleRatio : 50 * scaleRatio
|
|
||||||
text: qsTr("USE MONERO") + translationManager.emptyString
|
|
||||||
visible: parent.paths[currentPath][currentPage] === finishPage
|
|
||||||
onClicked: {
|
|
||||||
wizard.applySettings();
|
|
||||||
wizard.useMoneroClicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StandardButton {
|
|
||||||
id: createViewOnlyWalletButton
|
|
||||||
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
|
|
||||||
Layout.margins: (isMobile) ? 20 * scaleRatio : 50
|
|
||||||
text: qsTr("Create wallet") + translationManager.emptyString
|
|
||||||
visible: currentPath === "create_view_only_wallet" && parent.paths[currentPath][currentPage] === passwordPage
|
|
||||||
enabled: passwordPage.passwordsMatch
|
|
||||||
onClicked: {
|
|
||||||
if (currentWallet.createViewOnly(settings['view_only_wallet_path'],passwordPage.password)) {
|
|
||||||
console.log("view only wallet created in ",settings['view_only_wallet_path']);
|
|
||||||
informationPopup.title = qsTr("Success") + translationManager.emptyString;
|
|
||||||
informationPopup.text = qsTr('The view only wallet has been created. You can open it by closing this current wallet, clicking the "Open wallet from file" option, and selecting the view wallet in: \n%1')
|
|
||||||
.arg(settings['view_only_wallet_path']);
|
|
||||||
informationPopup.open()
|
|
||||||
informationPopup.onCloseCallback = null
|
|
||||||
rootItem.state = "normal"
|
|
||||||
wizard.restart();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
informationPopup.title = qsTr("Error") + translationManager.emptyString;
|
|
||||||
informationPopup.text = currentWallet.errorString;
|
|
||||||
informationPopup.open()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StandardButton {
|
|
||||||
id: abortViewOnlyButton
|
|
||||||
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
|
|
||||||
Layout.margins: (isMobile) ? 20 * scaleRatio : 50
|
|
||||||
text: qsTr("Abort") + translationManager.emptyString
|
|
||||||
visible: currentPath === "create_view_only_wallet" && parent.paths[currentPath][currentPage] === passwordPage
|
|
||||||
onClicked: {
|
|
||||||
wizard.restart();
|
|
||||||
rootItem.state = "normal"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,415 +0,0 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import QtQuick 2.2
|
|
||||||
import moneroComponents.TranslationManager 1.0
|
|
||||||
import QtQuick.Dialogs 1.2
|
|
||||||
import QtQuick.Layouts 1.2
|
|
||||||
import "../components" as MoneroComponents
|
|
||||||
import 'utils.js' as Utils
|
|
||||||
|
|
||||||
// Reusable component for mnaging wallet (account name, path, private key)
|
|
||||||
ColumnLayout {
|
|
||||||
id: page
|
|
||||||
Layout.leftMargin: wizardLeftMargin
|
|
||||||
Layout.rightMargin: wizardRightMargin
|
|
||||||
property alias titleText: titleText.text
|
|
||||||
property alias accountNameText: accountName.text
|
|
||||||
property alias walletPath: fileUrlInput.text
|
|
||||||
property alias wordsTextItem : memoTextItem
|
|
||||||
property alias restoreHeight : restoreHeightItem.text
|
|
||||||
property alias restoreHeightVisible: restoreHeightItem.visible
|
|
||||||
property alias subaddressLookahead : subaddressLookaheadItem.text
|
|
||||||
property alias walletName : accountName.text
|
|
||||||
property alias progressDotsModel : progressDots.model
|
|
||||||
property alias recoverFromKeysAddress: addressLine.text;
|
|
||||||
property alias recoverFromKeysViewKey: viewKeyLine.text;
|
|
||||||
property alias recoverFromKeysSpendKey: spendKeyLine.text;
|
|
||||||
// recover mode or create new wallet
|
|
||||||
property bool recoverMode: false
|
|
||||||
// Recover form seed or keys
|
|
||||||
property bool recoverFromSeedMode: true
|
|
||||||
// Recover form hardware device
|
|
||||||
property bool recoverFromDevice: false
|
|
||||||
property var deviceName: deviceNameModel.get(deviceNameDropdown.currentIndex).column2
|
|
||||||
property alias deviceNameDropdown: deviceNameDropdown
|
|
||||||
property int rowSpacing: 10
|
|
||||||
|
|
||||||
function checkFields(){
|
|
||||||
var addressOK = (viewKeyLine.text.length > 0 || spendKeyLine.text.length > 0)? walletManager.addressValid(addressLine.text, persistentSettings.nettype) : false
|
|
||||||
var viewKeyOK = (viewKeyLine.text.length > 0)? walletManager.keyValid(viewKeyLine.text, addressLine.text, true, persistentSettings.nettype) : true
|
|
||||||
// Spendkey is optional
|
|
||||||
var spendKeyOK = (spendKeyLine.text.length > 0)? walletManager.keyValid(spendKeyLine.text, addressLine.text, false, persistentSettings.nettype) : true
|
|
||||||
|
|
||||||
addressLine.error = !addressOK && addressLine.text.length != 0
|
|
||||||
viewKeyLine.error = !viewKeyOK && viewKeyLine.text.length != 0
|
|
||||||
spendKeyLine.error = !spendKeyOK && spendKeyLine.text.length != 0
|
|
||||||
|
|
||||||
return addressOK && viewKeyOK && spendKeyOK
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkNextButton(){
|
|
||||||
wizard.nextButton.enabled = false
|
|
||||||
console.log("check next", recoverFromSeed.visible)
|
|
||||||
if(recoverMode && !recoverFromSeedMode) {
|
|
||||||
console.log("checking key fields")
|
|
||||||
wizard.nextButton.enabled = checkFields();
|
|
||||||
} else if (recoverMode && recoverFromSeedMode) {
|
|
||||||
wizard.nextButton.enabled = checkSeed()
|
|
||||||
} else
|
|
||||||
wizard.nextButton.enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkSeed() {
|
|
||||||
console.log("Checking seed")
|
|
||||||
var wordsArray = Utils.lineBreaksToSpaces(uiItem.wordsTextItem.memoText).split(" ");
|
|
||||||
return wordsArray.length === 25 || wordsArray.length === 24
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateFromQrCode(address, payment_id, amount, tx_description, recipient_name, extra_parameters) {
|
|
||||||
// Switch to recover from keys
|
|
||||||
recoverFromSeedMode = false
|
|
||||||
spendKeyLine.text = ""
|
|
||||||
viewKeyLine.text = ""
|
|
||||||
restoreHeightItem.text = ""
|
|
||||||
|
|
||||||
|
|
||||||
if(typeof extra_parameters.secret_view_key != "undefined") {
|
|
||||||
viewKeyLine.text = extra_parameters.secret_view_key
|
|
||||||
}
|
|
||||||
if(typeof extra_parameters.secret_spend_key != "undefined") {
|
|
||||||
spendKeyLine.text = extra_parameters.secret_spend_key
|
|
||||||
}
|
|
||||||
if(typeof extra_parameters.restore_height != "undefined") {
|
|
||||||
restoreHeightItem.text = extra_parameters.restore_height
|
|
||||||
}
|
|
||||||
addressLine.text = address
|
|
||||||
|
|
||||||
cameraUi.qrcode_decoded.disconnect(updateFromQrCode)
|
|
||||||
|
|
||||||
// Check if keys are correct
|
|
||||||
checkNextButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: dotsRow
|
|
||||||
Layout.alignment: Qt.AlignRight
|
|
||||||
spacing: 6
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: dotsModel
|
|
||||||
ListElement { dotColor: "#FFE00A" }
|
|
||||||
ListElement { dotColor: "#DBDBDB" }
|
|
||||||
ListElement { dotColor: "#DBDBDB" }
|
|
||||||
ListElement { dotColor: "#DBDBDB" }
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
id: progressDots
|
|
||||||
model: dotsModel
|
|
||||||
delegate: Rectangle {
|
|
||||||
width: 12; height: 12
|
|
||||||
radius: 6
|
|
||||||
color: dotColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: headerColumn
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Text {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
id: titleText
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 28 * scaleRatio
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
color: "#3F3F3F"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.bottomMargin: rowSpacing
|
|
||||||
|
|
||||||
MoneroComponents.Label {
|
|
||||||
Layout.topMargin: 20 * scaleRatio
|
|
||||||
fontFamily: "Arial"
|
|
||||||
fontColor: "#555555"
|
|
||||||
fontSize: 14 * scaleRatio
|
|
||||||
text: qsTr("Wallet name")
|
|
||||||
+ translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.LineEdit {
|
|
||||||
id: accountName
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.maximumWidth: 600 * scaleRatio
|
|
||||||
Layout.minimumWidth: 200 * scaleRatio
|
|
||||||
text: defaultAccountName
|
|
||||||
onTextUpdated: checkNextButton()
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.15)
|
|
||||||
backgroundColor: "white"
|
|
||||||
fontColor: "black"
|
|
||||||
fontBold: false
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.WarningBox {
|
|
||||||
color: "#DBDBDB"
|
|
||||||
textColor: "#4A4646"
|
|
||||||
visible: !recoverFromDevice && !recoverMode
|
|
||||||
text: qsTr("WARNING: Copying your seed to clipboard can expose you to malicious software, which may record your seed and steal your Monero. Please write down your seed manually.") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout{
|
|
||||||
columns: (isMobile)? 2 : 4
|
|
||||||
visible: recoverMode
|
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
|
||||||
id: recoverFromSeedButton
|
|
||||||
text: qsTr("Restore from seed") + translationManager.emptyString
|
|
||||||
enabled: recoverFromKeys.visible
|
|
||||||
onClicked: {
|
|
||||||
recoverFromSeedMode = true;
|
|
||||||
checkNextButton();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
|
||||||
id: recoverFromKeysButton
|
|
||||||
text: qsTr("Restore from keys") + translationManager.emptyString
|
|
||||||
enabled: recoverFromSeed.visible
|
|
||||||
onClicked: {
|
|
||||||
recoverFromSeedMode = false;
|
|
||||||
checkNextButton();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.StandardButton {
|
|
||||||
id: qrfinderButton
|
|
||||||
text: qsTr("From QR Code") + translationManager.emptyString
|
|
||||||
visible : appWindow.qrScannerEnabled
|
|
||||||
enabled : visible
|
|
||||||
onClicked: {
|
|
||||||
cameraUi.state = "Capture"
|
|
||||||
cameraUi.qrcode_decoded.connect(updateFromQrCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recover from seed
|
|
||||||
RowLayout {
|
|
||||||
id: recoverFromSeed
|
|
||||||
visible: !recoverFromDevice && (!recoverMode || ( recoverMode && recoverFromSeedMode))
|
|
||||||
WizardMemoTextInput {
|
|
||||||
id : memoTextItem
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.maximumWidth: 600 * scaleRatio
|
|
||||||
Layout.minimumWidth: 200 * scaleRatio
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recover from keys
|
|
||||||
GridLayout {
|
|
||||||
Layout.bottomMargin: page.rowSpacing
|
|
||||||
rowSpacing: page.rowSpacing
|
|
||||||
id: recoverFromKeys
|
|
||||||
visible: recoverMode && !recoverFromSeedMode
|
|
||||||
columns: 1
|
|
||||||
MoneroComponents.LineEdit {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
id: addressLine
|
|
||||||
Layout.maximumWidth: 600 * scaleRatio
|
|
||||||
Layout.minimumWidth: 200 * scaleRatio
|
|
||||||
placeholderFontBold: true
|
|
||||||
placeholderFontFamily: "Arial"
|
|
||||||
placeholderColor: MoneroComponents.Style.legacy_placeholderFontColor
|
|
||||||
placeholderText: qsTr("Account address (public)") + translationManager.emptyString
|
|
||||||
placeholderOpacity: 1.0
|
|
||||||
onTextUpdated: checkNextButton()
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.15)
|
|
||||||
backgroundColor: "white"
|
|
||||||
fontColor: "black"
|
|
||||||
fontBold: false
|
|
||||||
}
|
|
||||||
MoneroComponents.LineEdit {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
id: viewKeyLine
|
|
||||||
Layout.maximumWidth: 600 * scaleRatio
|
|
||||||
Layout.minimumWidth: 200 * scaleRatio
|
|
||||||
placeholderFontBold: true
|
|
||||||
placeholderFontFamily: "Arial"
|
|
||||||
placeholderColor: MoneroComponents.Style.legacy_placeholderFontColor
|
|
||||||
placeholderText: qsTr("View key (private)") + translationManager.emptyString
|
|
||||||
placeholderOpacity: 1.0
|
|
||||||
onTextUpdated: checkNextButton()
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.15)
|
|
||||||
backgroundColor: "white"
|
|
||||||
fontColor: "black"
|
|
||||||
fontBold: false
|
|
||||||
|
|
||||||
}
|
|
||||||
MoneroComponents.LineEdit {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.maximumWidth: 600 * scaleRatio
|
|
||||||
Layout.minimumWidth: 200 * scaleRatio
|
|
||||||
id: spendKeyLine
|
|
||||||
placeholderFontBold: true
|
|
||||||
placeholderFontFamily: "Arial"
|
|
||||||
placeholderColor: MoneroComponents.Style.legacy_placeholderFontColor
|
|
||||||
placeholderText: qsTr("Spend key (private)") + translationManager.emptyString
|
|
||||||
placeholderOpacity: 1.0
|
|
||||||
onTextUpdated: checkNextButton()
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.15)
|
|
||||||
backgroundColor: "white"
|
|
||||||
fontColor: "black"
|
|
||||||
fontBold: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore Height
|
|
||||||
RowLayout {
|
|
||||||
MoneroComponents.LineEdit {
|
|
||||||
id: restoreHeightItem
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.maximumWidth: 600 * scaleRatio
|
|
||||||
Layout.minimumWidth: 200 * scaleRatio
|
|
||||||
placeholderFontBold: true
|
|
||||||
placeholderFontFamily: "Arial"
|
|
||||||
placeholderColor: MoneroComponents.Style.legacy_placeholderFontColor
|
|
||||||
placeholderText: qsTr("Restore height (optional)") + translationManager.emptyString
|
|
||||||
placeholderOpacity: 1.0
|
|
||||||
validator: IntValidator {
|
|
||||||
bottom:0
|
|
||||||
}
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.15)
|
|
||||||
backgroundColor: "white"
|
|
||||||
fontColor: "black"
|
|
||||||
fontBold: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subaddress lookahead
|
|
||||||
RowLayout {
|
|
||||||
visible: recoverFromDevice
|
|
||||||
MoneroComponents.LineEdit {
|
|
||||||
id: subaddressLookaheadItem
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.maximumWidth: 600 * scaleRatio
|
|
||||||
Layout.minimumWidth: 200 * scaleRatio
|
|
||||||
placeholderFontBold: true
|
|
||||||
placeholderFontFamily: "Arial"
|
|
||||||
placeholderColor: MoneroComponents.Style.legacy_placeholderFontColor
|
|
||||||
placeholderText: qsTr("Subaddress lookahead (optional): <major>:<minor>") + translationManager.emptyString
|
|
||||||
placeholderOpacity: 1.0
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.15)
|
|
||||||
backgroundColor: "white"
|
|
||||||
fontColor: "black"
|
|
||||||
fontBold: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Device name
|
|
||||||
ColumnLayout {
|
|
||||||
visible: recoverFromDevice
|
|
||||||
MoneroComponents.Label {
|
|
||||||
Layout.topMargin: 20 * scaleRatio
|
|
||||||
fontFamily: "Arial"
|
|
||||||
fontColor: "#555555"
|
|
||||||
fontSize: 14 * scaleRatio
|
|
||||||
text: qsTr("Device name") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
ListModel {
|
|
||||||
id: deviceNameModel
|
|
||||||
ListElement { column1: qsTr("Ledger") ; column2: "Ledger"; }
|
|
||||||
// ListElement { column1: qsTr("Trezor") ; column2: "Trezor"; }
|
|
||||||
}
|
|
||||||
MoneroComponents.StandardDropdown {
|
|
||||||
id: deviceNameDropdown
|
|
||||||
dataModel: deviceNameModel
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 6
|
|
||||||
colorHeaderBackground: "black"
|
|
||||||
releasedColor: "#363636"
|
|
||||||
pressedColor: "#202020"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wallet store location
|
|
||||||
ColumnLayout {
|
|
||||||
z: deviceNameDropdown.z - 1
|
|
||||||
MoneroComponents.Label {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 20 * scaleRatio
|
|
||||||
fontSize: 14
|
|
||||||
fontFamily: "Arial"
|
|
||||||
fontColor: "#555555"
|
|
||||||
text: qsTr("Your wallet is stored in") + ": " + fileUrlInput.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
MoneroComponents.LineEdit {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.maximumWidth: 600 * scaleRatio
|
|
||||||
Layout.minimumWidth: 200 * scaleRatio
|
|
||||||
id: fileUrlInput
|
|
||||||
text: moneroAccountsDir + "/"
|
|
||||||
|
|
||||||
// workaround for the bug "filechooser only opens once"
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
mouse.accepted = false
|
|
||||||
fileDialog.folder = walletManager.localPathToUrl(fileUrlInput.text)
|
|
||||||
fileDialog.open()
|
|
||||||
fileUrlInput.focus = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.15)
|
|
||||||
backgroundColor: "white"
|
|
||||||
fontColor: "black"
|
|
||||||
fontBold: false
|
|
||||||
}
|
|
||||||
|
|
||||||
FileDialog {
|
|
||||||
id: fileDialog
|
|
||||||
selectMultiple: false
|
|
||||||
selectFolder: true
|
|
||||||
title: qsTr("Please choose a directory") + translationManager.emptyString
|
|
||||||
onAccepted: {
|
|
||||||
fileUrlInput.text = walletManager.urlToLocalPath(fileDialog.folder)
|
|
||||||
fileDialog.visible = false
|
|
||||||
}
|
|
||||||
onRejected: {
|
|
||||||
fileDialog.visible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
import QtQuick 2.0
|
|
||||||
import moneroComponents.Clipboard 1.0
|
|
||||||
|
|
||||||
Column {
|
|
||||||
|
|
||||||
property alias memoText : memoTextInput.text
|
|
||||||
property alias tipText: wordsTipText.text
|
|
||||||
property alias tipTextVisible: tipRect.visible
|
|
||||||
property alias memoTextReadOnly : memoTextInput.readOnly
|
|
||||||
property alias clipboardButtonVisible: clipboardButton.visible
|
|
||||||
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: memoTextRect
|
|
||||||
width: parent.width
|
|
||||||
height: {
|
|
||||||
memoTextInput.height
|
|
||||||
// to have less gap between button and text input we reduce overall height by button height
|
|
||||||
//+ (clipboardButton.visible ? clipboardButton.height : 0)
|
|
||||||
+ (tipRect.visible ? tipRect.height : 0)
|
|
||||||
}
|
|
||||||
border.width: 1
|
|
||||||
border.color: "#DBDBDB"
|
|
||||||
|
|
||||||
TextEdit {
|
|
||||||
id: memoTextInput
|
|
||||||
property alias placeholderText: memoTextPlaceholder.text
|
|
||||||
textMargin: 8 * scaleRatio
|
|
||||||
text: ""
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 16 * scaleRatio
|
|
||||||
wrapMode: TextInput.Wrap
|
|
||||||
width: parent.width
|
|
||||||
selectByMouse: true
|
|
||||||
property int minimumHeight: 100 * scaleRatio
|
|
||||||
height: contentHeight > minimumHeight ? contentHeight : minimumHeight
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: memoTextPlaceholder
|
|
||||||
anchors.fill:parent
|
|
||||||
font.pixelSize: 16 * scaleRatio
|
|
||||||
anchors.margins: 8 * scaleRatio
|
|
||||||
font.bold:true
|
|
||||||
font.family: "Arial"
|
|
||||||
text: qsTr("Enter your 25 (or 24) word mnemonic seed") + translationManager.emptyString
|
|
||||||
color: "#BABABA"
|
|
||||||
visible: !memoTextInput.text/* && !parent.focus*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Image {
|
|
||||||
id : clipboardButton
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 5 * scaleRatio
|
|
||||||
anchors.bottom: tipRect.top
|
|
||||||
anchors.bottomMargin: 5 * scaleRatio
|
|
||||||
source: "qrc:///images/copyToClipboard.png"
|
|
||||||
Clipboard { id: clipboard }
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
clipboard.setText(memoTextInput.text)
|
|
||||||
appWindow.showStatusMessage(qsTr("Seed copied to clipboard"),3)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
id: tipRect
|
|
||||||
visible: true
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: memoTextRect.bottom
|
|
||||||
height: wordsTipText.contentHeight + wordsTipText.anchors.topMargin
|
|
||||||
color: "#DBDBDB"
|
|
||||||
property alias text: wordsTipText.text
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: wordsTipText
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.topMargin : 16 * scaleRatio
|
|
||||||
anchors.bottomMargin: 16 * scaleRatio
|
|
||||||
anchors.leftMargin: 16 * scaleRatio
|
|
||||||
anchors.rightMargin: 16 * scaleRatio
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 15 * scaleRatio
|
|
||||||
color: "#4A4646"
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
text: qsTr("This seed is <b>very</b> important to write down and keep secret. It is all you need to backup and restore your wallet.")
|
|
||||||
+ translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
120
wizard/WizardMenuItem.qml
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: rowlayout
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.bottomMargin: 10 * scaleRatio
|
||||||
|
property alias imageIcon: icon.source
|
||||||
|
property alias headerText: header.text
|
||||||
|
property alias bodyText: body.text
|
||||||
|
signal menuClicked();
|
||||||
|
spacing: 10 * scaleRatio
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.preferredWidth: 70 * scaleRatio
|
||||||
|
Layout.preferredHeight: 70 * scaleRatio
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: icon
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
source: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
rowlayout.menuClicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: header
|
||||||
|
Layout.fillWidth: true
|
||||||
|
leftPadding: parent.leftPadding
|
||||||
|
topPadding: 0
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
font.bold: true
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: {
|
||||||
|
if(wizardController.layoutScale === 2 ){
|
||||||
|
return 22 * scaleRatio;
|
||||||
|
} else {
|
||||||
|
return 16 * scaleRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
rowlayout.menuClicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: body
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: MoneroComponents.Style.dimmedFontColor
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: {
|
||||||
|
if(wizardController.layoutScale === 2 ){
|
||||||
|
return 16 * scaleRatio;
|
||||||
|
} else {
|
||||||
|
return 14 * scaleRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
topPadding: 4 * scaleRatio
|
||||||
|
wrapMode: Text.WordWrap;
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
rowlayout.menuClicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
206
wizard/WizardModeBootstrap.qml
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardModeBootstrapWarning
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property string viewName: "wizardModeRemoteNodeWarning"
|
||||||
|
property bool understood: false
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 10 * scaleRatio
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 0 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader {
|
||||||
|
title: qsTr("About the bootstrap mode") + translationManager.emptyString
|
||||||
|
subtitle: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
Layout.topMargin: 10 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("This mode will use a remote node whilst also syncing the blockchain. This is different from the first menu option (Simple mode), since it will only use the remote node until the blockchain is fully synced locally. It is a reasonable tradeoff for most people who care about privacy but also want the convenience of an automatic fallback option.") + translationManager.emptyString
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
Layout.topMargin: 14 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: 16 * scaleRatio
|
||||||
|
color: MoneroComponents.Style.lightGreyFontColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Temporary use of remote nodes is useful in order to use Monero immediately (hence the name <i>bootstrap</i>), however be aware that when using remote nodes (including with the bootstrap setting), nodes could track your IP address, track your \"restore height\" and associated block request data, and send you inaccurate information to learn more about transactions you make.") + translationManager.emptyString
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
Layout.topMargin: 8 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: 16 * scaleRatio
|
||||||
|
color: MoneroComponents.Style.lightGreyFontColor
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.WarningBox{
|
||||||
|
Layout.topMargin: 14 * scaleRatio
|
||||||
|
Layout.bottomMargin: 6 * scaleRatio
|
||||||
|
text: qsTr("Remain aware of these limitations. <b>Users who prioritize privacy and decentralization must use a full node instead</b>.") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("For enhanced node performance you may specify your region:") + translationManager.emptyString
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
Layout.topMargin: 8 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: 16 * scaleRatio
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
columns: 3
|
||||||
|
columnSpacing: 20
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
MoneroComponents.StandardDropdown {
|
||||||
|
id: regionDropdown
|
||||||
|
Layout.fillWidth: true
|
||||||
|
dataModel: regionModel
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#363636"
|
||||||
|
pressedColor: "#202020"
|
||||||
|
currentIndex: 0
|
||||||
|
|
||||||
|
onChanged: {
|
||||||
|
var region = regionModel.get(currentIndex).region;
|
||||||
|
persistentSettings.remoteNodeRegion = region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
z: parent.z + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.CheckBox {
|
||||||
|
id: understoodCheckbox
|
||||||
|
Layout.topMargin: 20 * scaleRatio
|
||||||
|
fontSize: 16 * scaleRatio
|
||||||
|
text: qsTr("I understand the privacy implications of using a third-party server.") + translationManager.emptyString
|
||||||
|
onClicked: {
|
||||||
|
wizardModeBootstrapWarning.understood = !wizardModeBootstrapWarning.understood
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
Layout.topMargin: 4 * scaleRatio
|
||||||
|
btnNext.enabled: wizardModeBootstrapWarning.understood
|
||||||
|
progressSteps: 0
|
||||||
|
|
||||||
|
onPrevClicked: {
|
||||||
|
wizardController.wizardState = 'wizardModeSelection';
|
||||||
|
}
|
||||||
|
|
||||||
|
onNextClicked: {
|
||||||
|
appWindow.changeWalletMode(1);
|
||||||
|
wizardController.wizardState = 'wizardHome';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: regionModel
|
||||||
|
ListElement {column1: "Unspecified"; region: ""}
|
||||||
|
ListElement {column1: "Africa"; region: "af"}
|
||||||
|
ListElement {column1: "Asia"; region: "as"}
|
||||||
|
ListElement {column1: "Central America"; region: "ca";}
|
||||||
|
ListElement {column1: "North America"; region: "na";}
|
||||||
|
ListElement {column1: "Europe"; region: "eu";}
|
||||||
|
ListElement {column1: "Oceania"; region: "oc";}
|
||||||
|
ListElement {column1: "South America"; region: "sa";}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPageCompleted(previousView){
|
||||||
|
wizardModeBootstrapWarning.understood = false;
|
||||||
|
understoodCheckbox.checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
var region = persistentSettings.remoteNodeRegion;
|
||||||
|
|
||||||
|
if(region){
|
||||||
|
for(var i = 0; i !== regionDropdown.dataModel.count; i++){
|
||||||
|
var item = regionDropdown.dataModel.get(i);
|
||||||
|
if(item['region'] === region){
|
||||||
|
regionDropdown.currentIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
regionDropdown.currentIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
regionDropdown.update();
|
||||||
|
}
|
||||||
|
}
|
206
wizard/WizardModeRemoteNodeWarning.qml
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardModeRemoteNodeWarning
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property string viewName: "wizardModeRemoteNodeWarning"
|
||||||
|
property bool understood: false
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 10 * scaleRatio
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 0 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader {
|
||||||
|
title: qsTr("About the simple mode") + translationManager.emptyString
|
||||||
|
subtitle: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
Layout.topMargin: 10 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("This mode is ideal for managing small amounts of Monero. You have access to basic features for making and managing transactions. It will automatically connect to the Monero network so you can start using Monero immediately.") + translationManager.emptyString
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
Layout.topMargin: 14 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: 16 * scaleRatio
|
||||||
|
color: MoneroComponents.Style.lightGreyFontColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Remote nodes are useful if you are not able/don't want to download the whole blockchain, but be advised that malicious remote nodes could compromise some privacy. They could track your IP address, track your \"restore height\" and associated block request data, and send you inaccurate information to learn more about transactions you make.") + translationManager.emptyString
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
Layout.topMargin: 8 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: 16 * scaleRatio
|
||||||
|
color: MoneroComponents.Style.lightGreyFontColor
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.WarningBox{
|
||||||
|
Layout.topMargin: 14 * scaleRatio
|
||||||
|
Layout.bottomMargin: 6 * scaleRatio
|
||||||
|
text: qsTr("Remain aware of these limitations. <b>Users who prioritize privacy and decentralization must use a full node instead</b>.") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("For enhanced node performance you may specify your region:") + translationManager.emptyString
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
Layout.topMargin: 8 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: 16 * scaleRatio
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
columns: 3
|
||||||
|
columnSpacing: 20
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
MoneroComponents.StandardDropdown {
|
||||||
|
id: regionDropdown
|
||||||
|
Layout.fillWidth: true
|
||||||
|
dataModel: regionModel
|
||||||
|
shadowReleasedColor: "#FF4304"
|
||||||
|
shadowPressedColor: "#B32D00"
|
||||||
|
releasedColor: "#363636"
|
||||||
|
pressedColor: "#202020"
|
||||||
|
currentIndex: 0
|
||||||
|
|
||||||
|
onChanged: {
|
||||||
|
var region = regionModel.get(currentIndex).region;
|
||||||
|
persistentSettings.remoteNodeRegion = region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
z: parent.z + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.CheckBox {
|
||||||
|
id: understoodCheckbox
|
||||||
|
Layout.topMargin: 20 * scaleRatio
|
||||||
|
fontSize: 16 * scaleRatio
|
||||||
|
text: qsTr("I understand the privacy implications of using a third-party server.") + translationManager.emptyString
|
||||||
|
onClicked: {
|
||||||
|
wizardModeRemoteNodeWarning.understood = !wizardModeRemoteNodeWarning.understood
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
Layout.topMargin: 4 * scaleRatio
|
||||||
|
btnNext.enabled: wizardModeRemoteNodeWarning.understood
|
||||||
|
progressSteps: 0
|
||||||
|
|
||||||
|
onPrevClicked: {
|
||||||
|
wizardController.wizardState = 'wizardModeSelection';
|
||||||
|
}
|
||||||
|
|
||||||
|
onNextClicked: {
|
||||||
|
appWindow.changeWalletMode(0);
|
||||||
|
wizardController.wizardState = 'wizardHome';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: regionModel
|
||||||
|
ListElement {column1: "Unspecified"; region: ""}
|
||||||
|
ListElement {column1: "Africa"; region: "af"}
|
||||||
|
ListElement {column1: "Asia"; region: "as"}
|
||||||
|
ListElement {column1: "Central America"; region: "ca";}
|
||||||
|
ListElement {column1: "North America"; region: "na";}
|
||||||
|
ListElement {column1: "Europe"; region: "eu";}
|
||||||
|
ListElement {column1: "Oceania"; region: "oc";}
|
||||||
|
ListElement {column1: "South America"; region: "sa";}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPageCompleted(previousView){
|
||||||
|
wizardModeRemoteNodeWarning.understood = false;
|
||||||
|
understoodCheckbox.checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
var region = persistentSettings.remoteNodeRegion;
|
||||||
|
|
||||||
|
if(region){
|
||||||
|
for(var i = 0; i !== regionDropdown.dataModel.count; i++){
|
||||||
|
var item = regionDropdown.dataModel.get(i);
|
||||||
|
if(item['region'] === region){
|
||||||
|
regionDropdown.currentIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
regionDropdown.currentIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
regionDropdown.update();
|
||||||
|
}
|
||||||
|
}
|
153
wizard/WizardModeSelection.qml
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardModeSelection1
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
property string viewName: "wizardModeSelection1"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 10 * scaleRatio
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 0 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader {
|
||||||
|
title: qsTr("Mode selection.") + translationManager.emptyString
|
||||||
|
subtitle: qsTr("Please select the statement that best matches you.") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardMenuItem {
|
||||||
|
opacity: appWindow.persistentSettings.nettype == 0 ? 1.0 : 0.5
|
||||||
|
Layout.topMargin: 20 * scaleRatio
|
||||||
|
headerText: qsTr("Simple mode") + translationManager.emptyString
|
||||||
|
bodyText: {
|
||||||
|
if(appWindow.persistentSettings.nettype == 0){
|
||||||
|
return qsTr("Easy access to sending, receiving and basic functionality.") + translationManager.emptyString;
|
||||||
|
} else {
|
||||||
|
return "Available on mainnet.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
imageIcon: "../images/remote-node.png"
|
||||||
|
|
||||||
|
onMenuClicked: {
|
||||||
|
if(appWindow.persistentSettings.nettype == 0){
|
||||||
|
appWindow.changeWalletMode(0);
|
||||||
|
wizardController.wizardState = 'wizardModeRemoteNodeWarning';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredHeight: 1
|
||||||
|
Layout.topMargin: 5 * scaleRatio
|
||||||
|
Layout.bottomMargin: 10 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: MoneroComponents.Style.dividerColor
|
||||||
|
opacity: MoneroComponents.Style.dividerOpacity
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardMenuItem {
|
||||||
|
opacity: appWindow.persistentSettings.nettype == 0 ? 1.0 : 0.5
|
||||||
|
headerText: qsTr("Simple mode") + " (bootstrap)" + translationManager.emptyString
|
||||||
|
bodyText: {
|
||||||
|
if(appWindow.persistentSettings.nettype == 0){
|
||||||
|
return qsTr("Easy access to sending, receiving and basic functionality. The blockchain is downloaded to your computer.") + translationManager.emptyString;
|
||||||
|
} else {
|
||||||
|
return "Available on mainnet.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imageIcon: "../images/local-node.png"
|
||||||
|
|
||||||
|
onMenuClicked: {
|
||||||
|
if(appWindow.persistentSettings.nettype == 0){
|
||||||
|
appWindow.changeWalletMode(1);
|
||||||
|
wizardController.wizardState = 'wizardModeBootstrap';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredHeight: 1
|
||||||
|
Layout.topMargin: 5 * scaleRatio
|
||||||
|
Layout.bottomMargin: 10 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: MoneroComponents.Style.dividerColor
|
||||||
|
opacity: MoneroComponents.Style.dividerOpacity
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardMenuItem {
|
||||||
|
headerText: qsTr("Advanced mode") + translationManager.emptyString
|
||||||
|
bodyText: qsTr("Includes extra features like mining and message verification. The blockchain is downloaded to your computer.") + translationManager.emptyString
|
||||||
|
imageIcon: "../images/local-node-full.png"
|
||||||
|
|
||||||
|
onMenuClicked: {
|
||||||
|
appWindow.changeWalletMode(2);
|
||||||
|
wizardController.wizardState = 'wizardHome';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
Layout.topMargin: 5 * scaleRatio
|
||||||
|
btnPrevText: qsTr("Change language") + translationManager.emptyString
|
||||||
|
btnNext.visible: false
|
||||||
|
progressSteps: 0
|
||||||
|
|
||||||
|
onPrevClicked: {
|
||||||
|
wizardController.wizardState = 'wizardLanguage';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 200;
|
||||||
|
easing.type: Easing.InCubic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
116
wizard/WizardNav.qml
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: menuNav
|
||||||
|
property alias progressEnabled: wizardProgress.visible
|
||||||
|
property int progressSteps: 0
|
||||||
|
property int progress: 0
|
||||||
|
property alias btnPrev: btnPrev
|
||||||
|
property alias btnNext: btnNext
|
||||||
|
property string btnPrevText: qsTr("Previous") + translationManager.emptyString
|
||||||
|
property string btnNextText: qsTr("Next") + translationManager.emptyString
|
||||||
|
Layout.topMargin: 20 * scaleRatio
|
||||||
|
Layout.preferredHeight: 70 * scaleRatio
|
||||||
|
Layout.preferredWidth: parent.width
|
||||||
|
columns: 3
|
||||||
|
|
||||||
|
signal nextClicked;
|
||||||
|
signal prevClicked;
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredHeight: parent.height
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
id: btnPrev
|
||||||
|
small: true
|
||||||
|
text: menuNav.btnPrevText
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
menuNav.prevClicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
// progress dots
|
||||||
|
Layout.preferredHeight: parent.height
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: wizardProgress
|
||||||
|
spacing: 0
|
||||||
|
width: 100 // default, dynamically set later
|
||||||
|
height: 30
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredHeight: parent.height
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
id: btnNext
|
||||||
|
small: true
|
||||||
|
text: menuNav.btnNextText
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
menuNav.nextClicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
for(var i =0; i < menuNav.progressSteps; i++) {
|
||||||
|
var active = i < menuNav.progress ? 'true' : 'false';
|
||||||
|
Qt.createQmlObject("WizardNavProgressDot { active: " + active + " }", wizardProgress, 'dynamicWizardNavDot');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set `wizardProgress` width based on amount of progress dots
|
||||||
|
wizardProgress.width = 30 * menuNav.progressSteps;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -26,43 +26,26 @@
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import QtQuick 2.0
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Layouts 1.2
|
||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls 2.0
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
|
|
||||||
ColumnLayout {
|
import "../components" as MoneroComponents
|
||||||
property alias password: password.text
|
|
||||||
property alias placeholderText: password.placeholderText
|
|
||||||
signal changed(string password)
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
TextField {
|
property bool active: false
|
||||||
Layout.fillWidth: true
|
Layout.preferredWidth: 30 * scaleRatio
|
||||||
id : password
|
Layout.fillHeight: true
|
||||||
focus:true
|
property string activeColor: MoneroComponents.Style.defaultFontColor
|
||||||
font.family: "Arial"
|
property string inactiveColor: "#333333"
|
||||||
font.pixelSize: (isMobile) ? 25 * scaleRatio : 26 * scaleRatio
|
color: "transparent"
|
||||||
echoMode: TextInput.Password
|
|
||||||
style: TextFieldStyle {
|
|
||||||
renderType: Text.NativeRendering
|
|
||||||
textColor: "#35B05A"
|
|
||||||
passwordCharacter: "•"
|
|
||||||
background: Rectangle {
|
|
||||||
radius: 0
|
|
||||||
border.width: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onTextChanged: changed(text)
|
|
||||||
|
|
||||||
Keys.onReleased: {
|
|
||||||
changed(text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.fillWidth:true
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
height: 1
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
color: "#DBDBDB"
|
width: 10 * scaleRatio
|
||||||
|
height: 10 * scaleRatio
|
||||||
|
radius: 10 * scaleRatio
|
||||||
|
color: parent.active ? parent.activeColor : parent.inactiveColor
|
||||||
}
|
}
|
||||||
}
|
}
|
236
wizard/WizardOpenWallet1.qml
Normal file
|
@ -0,0 +1,236 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
import Qt.labs.folderlistmodel 2.1
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components"
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardOpenWallet1
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property string viewName: "wizardOpenWallet1"
|
||||||
|
|
||||||
|
FolderListModel {
|
||||||
|
// @TODO: Current implementation only lists the folders in `/home/foo/Monero/wallets`, better
|
||||||
|
// solution is to actually scan for .keys files.
|
||||||
|
id: folderModel
|
||||||
|
nameFilters: ["*"]
|
||||||
|
folder: "file:" + moneroAccountsDir + "/"
|
||||||
|
|
||||||
|
showFiles: false
|
||||||
|
showHidden: false
|
||||||
|
sortField: FolderListModel.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader {
|
||||||
|
title: qsTr("Open a wallet from file") + translationManager.emptyString
|
||||||
|
subtitle: qsTr("Import an existing .keys wallet file from your computer.") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
Layout.topMargin: 20 * scaleRatio
|
||||||
|
id: btnNext
|
||||||
|
small: true
|
||||||
|
text: qsTr("Browse filesystem")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
wizardController.openWallet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
visible: folderModel.count > 0
|
||||||
|
Layout.topMargin: 30 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
columnSpacing: 20 * scaleRatio
|
||||||
|
columns: 2
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Most recent wallets") + translationManager.emptyString
|
||||||
|
font.family: MoneroComponents.Style.fontLight.name
|
||||||
|
font.pixelSize: 16 * scaleRatio
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
visible: folderModel.count > 0
|
||||||
|
Layout.topMargin: 10 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
columnSpacing: 20 * scaleRatio
|
||||||
|
columns: 2
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: recentList
|
||||||
|
property int itemHeight: 42 * scaleRatio
|
||||||
|
property int maxItems: 7
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: recentList.itemHeight * folderModel.count
|
||||||
|
Layout.maximumHeight: recentList.itemHeight * recentList.maxItems
|
||||||
|
interactive: false // disable scrolling
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
height: recentList.itemHeight
|
||||||
|
width: 200 * scaleRatio
|
||||||
|
property string activeColor: "#26FFFFFF"
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
height: recentList.itemHeight
|
||||||
|
width: parent.width
|
||||||
|
spacing: 10 * scaleRatio
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.preferredWidth: recentList.itemHeight
|
||||||
|
Layout.preferredHeight: recentList.itemHeight
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Image {
|
||||||
|
height: recentList.itemHeight
|
||||||
|
width: recentList.itemHeight
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: "../images/open-wallet-from-file.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: recentList.itemHeight
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
TextArea {
|
||||||
|
text: fileName
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
font.pixelSize: 18 * scaleRatio
|
||||||
|
|
||||||
|
selectionColor: MoneroComponents.Style.dimmedFontColor
|
||||||
|
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
||||||
|
|
||||||
|
selectByMouse: false
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
textMargin: 0
|
||||||
|
leftPadding: 0
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
readOnly: true
|
||||||
|
|
||||||
|
// @TODO: Legacy. Remove after Qt 5.8.
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
|
onEntered: {
|
||||||
|
parent.color = parent.activeColor;
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
parent.color = "transparent";
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
// open wallet
|
||||||
|
if(appWindow.walletMode === 0 || appWindow.walletMode === 1){
|
||||||
|
wizardController.fetchRemoteNodes(function(){
|
||||||
|
wizardController.openWalletFile(moneroAccountsDir + "/" + fileName + "/" + fileName + ".keys");
|
||||||
|
}, function(){
|
||||||
|
appWindow.showStatusMessage(qsTr("Failed to fetch remote nodes from third-party server."), 5);
|
||||||
|
wizardController.openWalletFile(moneroAccountsDir + "/" + fileName + "/" + fileName + ".keys");
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
wizardController.openWalletFile(moneroAccountsDir + "/" + fileName + "/" + fileName + ".keys");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model: folderModel
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
Layout.topMargin: {
|
||||||
|
if(folderModel.count > 0){
|
||||||
|
return 40 * scaleRatio;
|
||||||
|
} else {
|
||||||
|
return 20 * scaleRatio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
progressEnabled: false
|
||||||
|
btnPrev.text: qsTr("Back to menu") + translationManager.emptyString
|
||||||
|
btnNext.visible: false
|
||||||
|
onPrevClicked: {
|
||||||
|
wizardStateView.state = "wizardHome";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,394 +0,0 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import QtQuick 2.2
|
|
||||||
import QtQml 2.2
|
|
||||||
import QtQuick.Controls 2.0
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import moneroComponents.NetworkType 1.0
|
|
||||||
import "../components"
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: page
|
|
||||||
signal createWalletClicked()
|
|
||||||
signal recoveryWalletClicked()
|
|
||||||
signal openWalletClicked()
|
|
||||||
signal createWalletFromDeviceClicked()
|
|
||||||
opacity: 0
|
|
||||||
visible: false
|
|
||||||
property int buttonSize: (isMobile) ? 80 * scaleRatio : 140 * scaleRatio
|
|
||||||
property int buttonImageSize: (isMobile) ? buttonSize - 10 * scaleRatio : buttonSize - 30 * scaleRatio
|
|
||||||
|
|
||||||
function onPageClosed() {
|
|
||||||
// Save settings used in open from file.
|
|
||||||
// other wizard settings are saved on last page in applySettings()
|
|
||||||
appWindow.persistentSettings.language = wizard.settings.language
|
|
||||||
appWindow.persistentSettings.locale = wizard.settings.locale
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpacityChanged: visible = opacity !== 0
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: headerColumn
|
|
||||||
Layout.leftMargin: wizardLeftMargin
|
|
||||||
Layout.rightMargin: wizardRightMargin
|
|
||||||
Layout.bottomMargin: (!isMobile) ? 40 * scaleRatio : 20
|
|
||||||
spacing: 30 * scaleRatio
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 28 * scaleRatio
|
|
||||||
//renderType: Text.NativeRendering
|
|
||||||
color: "#3F3F3F"
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: qsTr("Welcome to Monero!") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 18 * scaleRatio
|
|
||||||
//renderType: Text.NativeRendering
|
|
||||||
color: "#4A4646"
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: qsTr("Please select one of the following options:") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
Layout.leftMargin: wizardLeftMargin
|
|
||||||
Layout.rightMargin: wizardRightMargin
|
|
||||||
Layout.alignment: Qt.AlignCenter
|
|
||||||
id: actionButtons
|
|
||||||
columnSpacing: 40 * scaleRatio
|
|
||||||
rowSpacing: 10 * scaleRatio
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
flow: isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
flow: !isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
|
|
||||||
rowSpacing: 20 * scaleRatio
|
|
||||||
columnSpacing: 10 * scaleRatio
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.preferredHeight: page.buttonSize
|
|
||||||
Layout.preferredWidth: page.buttonSize
|
|
||||||
radius: page.buttonSize
|
|
||||||
color: createWalletArea.containsMouse ? "#DBDBDB" : "#FFFFFF"
|
|
||||||
|
|
||||||
|
|
||||||
Image {
|
|
||||||
width: page.buttonImageSize
|
|
||||||
height: page.buttonImageSize
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
horizontalAlignment: Image.AlignRight
|
|
||||||
verticalAlignment: Image.AlignTop
|
|
||||||
anchors.centerIn: parent
|
|
||||||
source: "qrc:///images/createWallet.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: createWalletArea
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: {
|
|
||||||
page.createWalletClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.preferredWidth: page.buttonSize
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 16 * scaleRatio
|
|
||||||
color: "#4A4949"
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
text: qsTr("Create a new wallet") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
flow: !isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
|
|
||||||
rowSpacing: 20 * scaleRatio
|
|
||||||
columnSpacing: 10 * scaleRatio
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.preferredHeight: page.buttonSize
|
|
||||||
Layout.preferredWidth: page.buttonSize
|
|
||||||
radius: page.buttonSize
|
|
||||||
color: recoverWalletArea.containsMouse ? "#DBDBDB" : "#FFFFFF"
|
|
||||||
|
|
||||||
Image {
|
|
||||||
width: page.buttonImageSize
|
|
||||||
height: page.buttonImageSize
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
anchors.centerIn: parent
|
|
||||||
source: "qrc:///images/recoverWallet.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: recoverWalletArea
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: {
|
|
||||||
page.recoveryWalletClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.preferredWidth: page.buttonSize
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 16 * scaleRatio
|
|
||||||
color: "#4A4949"
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: qsTr("Restore wallet from keys or mnemonic seed") + translationManager.emptyString
|
|
||||||
width:page.buttonSize
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
flow: !isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
|
|
||||||
rowSpacing: 20 * scaleRatio
|
|
||||||
columnSpacing: 10 * scaleRatio
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.preferredHeight: page.buttonSize
|
|
||||||
Layout.preferredWidth: page.buttonSize
|
|
||||||
radius: page.buttonSize
|
|
||||||
color: openWalletArea.containsMouse ? "#DBDBDB" : "#FFFFFF"
|
|
||||||
|
|
||||||
Image {
|
|
||||||
width: page.buttonImageSize
|
|
||||||
height: page.buttonImageSize
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
anchors.centerIn: parent
|
|
||||||
source: "qrc:///images/openAccount.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: openWalletArea
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: {
|
|
||||||
page.openWalletClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.preferredWidth: page.buttonSize
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 16 * scaleRatio
|
|
||||||
color: "#4A4949"
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: qsTr("Open a wallet from file") + translationManager.emptyString
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
flow: !isMobile ? GridLayout.TopToBottom : GridLayout.LeftToRight
|
|
||||||
rowSpacing: 20 * scaleRatio
|
|
||||||
columnSpacing: 10 * scaleRatio
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.preferredHeight: page.buttonSize
|
|
||||||
Layout.preferredWidth: page.buttonSize
|
|
||||||
radius: page.buttonSize
|
|
||||||
color: createWalletFromDeviceArea.containsMouse ? "#DBDBDB" : "#FFFFFF"
|
|
||||||
|
|
||||||
|
|
||||||
Image {
|
|
||||||
width: page.buttonImageSize
|
|
||||||
height: page.buttonImageSize
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
horizontalAlignment: Image.AlignRight
|
|
||||||
verticalAlignment: Image.AlignTop
|
|
||||||
anchors.centerIn: parent
|
|
||||||
source: "qrc:///images/createWalletFromDevice.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: createWalletFromDeviceArea
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: {
|
|
||||||
page.createWalletFromDeviceClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.preferredWidth: page.buttonSize
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 16 * scaleRatio
|
|
||||||
color: "#4A4949"
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
text: qsTr("Create a new wallet from hardware device") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.leftMargin: wizardLeftMargin
|
|
||||||
Layout.rightMargin: wizardRightMargin
|
|
||||||
Layout.topMargin: 30 * scaleRatio
|
|
||||||
Layout.alignment: Qt.AlignCenter
|
|
||||||
Layout.fillWidth: true
|
|
||||||
spacing: 38 * scaleRatio
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
CheckBox2 {
|
|
||||||
id: showAdvancedCheckbox
|
|
||||||
darkDropIndicator: true
|
|
||||||
text: qsTr("Advanced options") + translationManager.emptyString
|
|
||||||
fontColor: "#4A4646"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 100 * scaleRatio
|
|
||||||
RadioButton {
|
|
||||||
visible: showAdvancedCheckbox.checked
|
|
||||||
enabled: !this.checked
|
|
||||||
id: mainNet
|
|
||||||
text: qsTr("Mainnet") + translationManager.emptyString
|
|
||||||
checkedColor: Qt.rgba(0, 0, 0, 0.75)
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.45)
|
|
||||||
fontColor: "#4A4646"
|
|
||||||
fontSize: 16 * scaleRatio
|
|
||||||
checked: appWindow.persistentSettings.nettype == NetworkType.MAINNET;
|
|
||||||
onClicked: {
|
|
||||||
persistentSettings.nettype = NetworkType.MAINNET
|
|
||||||
testNet.checked = false;
|
|
||||||
stageNet.checked = false;
|
|
||||||
console.log("Network type set to MainNet")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 100 * scaleRatio
|
|
||||||
RadioButton {
|
|
||||||
visible: showAdvancedCheckbox.checked
|
|
||||||
enabled: !this.checked
|
|
||||||
id: testNet
|
|
||||||
text: qsTr("Testnet") + translationManager.emptyString
|
|
||||||
checkedColor: Qt.rgba(0, 0, 0, 0.75)
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.45)
|
|
||||||
fontColor: "#4A4646"
|
|
||||||
fontSize: 16 * scaleRatio
|
|
||||||
checked: appWindow.persistentSettings.nettype == NetworkType.TESTNET;
|
|
||||||
onClicked: {
|
|
||||||
persistentSettings.nettype = testNet.checked ? NetworkType.TESTNET : NetworkType.MAINNET
|
|
||||||
mainNet.checked = false;
|
|
||||||
stageNet.checked = false;
|
|
||||||
console.log("Network type set to ", persistentSettings.nettype == NetworkType.TESTNET ? "Testnet" : "Mainnet")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 100 * scaleRatio
|
|
||||||
RadioButton {
|
|
||||||
visible: showAdvancedCheckbox.checked
|
|
||||||
enabled: !this.checked
|
|
||||||
id: stageNet
|
|
||||||
text: qsTr("Stagenet") + translationManager.emptyString
|
|
||||||
checkedColor: Qt.rgba(0, 0, 0, 0.75)
|
|
||||||
borderColor: Qt.rgba(0, 0, 0, 0.45)
|
|
||||||
fontColor: "#4A4646"
|
|
||||||
fontSize: 16 * scaleRatio
|
|
||||||
checked: appWindow.persistentSettings.nettype == NetworkType.STAGENET;
|
|
||||||
onClicked: {
|
|
||||||
persistentSettings.nettype = stageNet.checked ? NetworkType.STAGENET : NetworkType.MAINNET
|
|
||||||
mainNet.checked = false;
|
|
||||||
testNet.checked = false;
|
|
||||||
console.log("Network type set to ", persistentSettings.nettype == NetworkType.STAGENET ? "Stagenet" : "Mainnet")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Layout.leftMargin: wizardLeftMargin
|
|
||||||
Layout.rightMargin: wizardRightMargin
|
|
||||||
Layout.topMargin: 50 * scaleRatio
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: showAdvancedCheckbox.checked
|
|
||||||
|
|
||||||
Text {
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 16 * scaleRatio
|
|
||||||
color: "#4A4949"
|
|
||||||
text: qsTr("Number of KDF rounds:") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
TextField {
|
|
||||||
id: kdfRoundsText
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 16 * scaleRatio
|
|
||||||
Layout.preferredWidth: 60
|
|
||||||
horizontalAlignment: TextInput.AlignRight
|
|
||||||
selectByMouse: true
|
|
||||||
color: "#4A4949"
|
|
||||||
text: persistentSettings.kdfRounds
|
|
||||||
validator: IntValidator { bottom: 1 }
|
|
||||||
onEditingFinished: {
|
|
||||||
kdfRoundsText.text = persistentSettings.kdfRounds = parseInt(kdfRoundsText.text) >= 1 ? parseInt(kdfRoundsText.text) : 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,143 +0,0 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import moneroComponents.WalletManager 1.0
|
|
||||||
import QtQuick 2.2
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import "../components"
|
|
||||||
import "utils.js" as Utils
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.leftMargin: wizardLeftMargin
|
|
||||||
Layout.rightMargin: wizardRightMargin
|
|
||||||
|
|
||||||
id: passwordPage
|
|
||||||
opacity: 0
|
|
||||||
visible: false
|
|
||||||
property alias titleText: titleText.text
|
|
||||||
property alias passwordsMatch: passwordUI.passwordsMatch
|
|
||||||
property alias password: passwordUI.password
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpacityChanged: visible = opacity !== 0
|
|
||||||
|
|
||||||
|
|
||||||
function onPageOpened(settingsObject) {
|
|
||||||
wizard.nextButton.enabled = true
|
|
||||||
passwordUI.handlePassword();
|
|
||||||
|
|
||||||
if (wizard.currentPath === "create_wallet") {
|
|
||||||
passwordPage.titleText = qsTr("Give your wallet a password") + translationManager.emptyString
|
|
||||||
} else {
|
|
||||||
passwordPage.titleText = qsTr("Give your wallet a password") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
passwordUI.resetFocus()
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPageClosed(settingsObject) {
|
|
||||||
// TODO: set password on the final page
|
|
||||||
settingsObject['wallet_password'] = passwordUI.password
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
function onWizardRestarted(){
|
|
||||||
// Reset password fields
|
|
||||||
passwordUI.password = "";
|
|
||||||
passwordUI.confirmPassword = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: dotsRow
|
|
||||||
Layout.alignment: Qt.AlignRight
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: dotsModel
|
|
||||||
ListElement { dotColor: "#36B05B" }
|
|
||||||
ListElement { dotColor: "#FFE00A" }
|
|
||||||
ListElement { dotColor: "#DBDBDB" }
|
|
||||||
ListElement { dotColor: "#DBDBDB" }
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: dotsModel
|
|
||||||
delegate: Rectangle {
|
|
||||||
// Password page is last page when creating view only wallet
|
|
||||||
// TODO: make this dynamic for all pages in wizard
|
|
||||||
visible: (wizard.currentPath != "create_view_only_wallet" || index < 2)
|
|
||||||
width: 12; height: 12
|
|
||||||
radius: 6
|
|
||||||
color: dotColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: headerColumn
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
id: titleText
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 28 * scaleRatio
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
//renderType: Text.NativeRendering
|
|
||||||
color: "#3F3F3F"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.bottomMargin: 30 * scaleRatio
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 18 * scaleRatio
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
//renderType: Text.NativeRendering
|
|
||||||
color: "#4A4646"
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: qsTr(" <br>Note: this password cannot be recovered. If you forget it then the wallet will have to be restored from its 25 word mnemonic seed.<br/><br/>
|
|
||||||
<b>Enter a strong password</b> (using letters, numbers, and/or symbols):")
|
|
||||||
+ translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.fillWidth: true;
|
|
||||||
WizardPasswordUI {
|
|
||||||
id: passwordUI
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
parent.wizardRestarted.connect(onWizardRestarted)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,102 +0,0 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import moneroComponents.WalletManager 1.0
|
|
||||||
import QtQuick 2.2
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import "../components"
|
|
||||||
import "utils.js" as Utils
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
property alias password: passwordItem.password
|
|
||||||
property alias confirmPassword: retypePasswordItem.password
|
|
||||||
property bool passwordsMatch: passwordItem.password === retypePasswordItem.password
|
|
||||||
|
|
||||||
function handlePassword() {
|
|
||||||
// allow to forward step only if passwords match
|
|
||||||
|
|
||||||
wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password
|
|
||||||
|
|
||||||
// TODO: password strength meter segfaults on Android.
|
|
||||||
if (!isAndroid) {
|
|
||||||
// scorePassword returns value from 0 to... lots
|
|
||||||
var strength = walletManager.getPasswordStrength(passwordItem.password);
|
|
||||||
// consider anything below 10 bits as dire
|
|
||||||
strength -= 10
|
|
||||||
if (strength < 0)
|
|
||||||
strength = 0
|
|
||||||
// use a slight parabola to discourage short passwords
|
|
||||||
strength = strength ^ 1.2 / 3
|
|
||||||
// mapScope does not clamp
|
|
||||||
if (strength > 100)
|
|
||||||
strength = 100
|
|
||||||
// privacyLevel component uses 1..13 scale
|
|
||||||
privacyLevel.fillLevel = Utils.mapScope(1, 100, 1, 13, strength)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetFocus() {
|
|
||||||
passwordItem.focus = true
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardPasswordInput {
|
|
||||||
id: passwordItem
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.maximumWidth: 300 * scaleRatio
|
|
||||||
Layout.minimumWidth: 200 * scaleRatio
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
placeholderText : qsTr("Password") + translationManager.emptyString;
|
|
||||||
KeyNavigation.tab: retypePasswordItem
|
|
||||||
onChanged: handlePassword()
|
|
||||||
focus: true
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardPasswordInput {
|
|
||||||
id: retypePasswordItem
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.maximumWidth: 300 * scaleRatio
|
|
||||||
Layout.minimumWidth: 200 * scaleRatio
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
placeholderText : qsTr("Confirm password") + translationManager.emptyString;
|
|
||||||
KeyNavigation.tab: passwordItem
|
|
||||||
onChanged: handlePassword()
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivacyLevelSmall {
|
|
||||||
visible: !isAndroid //TODO: strength meter doesnt work on Android
|
|
||||||
Layout.topMargin: isAndroid ? 20 * scaleRatio : 40 * scaleRatio
|
|
||||||
Layout.fillWidth: true
|
|
||||||
id: privacyLevel
|
|
||||||
background: "#F0EEEE"
|
|
||||||
interactive: false
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
//parent.wizardRestarted.connect(onWizardRestarted)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,135 +0,0 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import QtQuick 2.2
|
|
||||||
import QtQuick.Dialogs 1.2
|
|
||||||
import moneroComponents.Wallet 1.0
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import 'utils.js' as Utils
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
opacity: 0
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpacityChanged: visible = opacity !== 0
|
|
||||||
|
|
||||||
function onWizardRestarted() {
|
|
||||||
// reset account name field
|
|
||||||
uiItem.accountNameText = defaultAccountName
|
|
||||||
// Empty seedText
|
|
||||||
uiItem.wordsTextItem.memoText = ""
|
|
||||||
uiItem.recoverFromKeysAddress = ""
|
|
||||||
uiItem.recoverFromKeysSpendKey = ""
|
|
||||||
uiItem.recoverFromKeysViewKey = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPageOpened(settingsObject) {
|
|
||||||
console.log("on page opened")
|
|
||||||
uiItem.checkNextButton();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onPageClosed(settingsObject) {
|
|
||||||
settingsObject['account_name'] = uiItem.accountNameText
|
|
||||||
settingsObject['words'] = Utils.lineBreaksToSpaces(uiItem.wordsTextItem.memoText)
|
|
||||||
settingsObject['wallet_path'] = uiItem.walletPath
|
|
||||||
settingsObject['recover_address'] = uiItem.recoverFromKeysAddress
|
|
||||||
settingsObject['recover_viewkey'] = uiItem.recoverFromKeysViewKey
|
|
||||||
settingsObject['recover_spendkey'] = uiItem.recoverFromKeysSpendKey
|
|
||||||
|
|
||||||
|
|
||||||
var restoreHeight = parseInt(uiItem.restoreHeight);
|
|
||||||
settingsObject['restore_height'] = isNaN(restoreHeight)? 0 : restoreHeight
|
|
||||||
var walletFullPath = wizard.createWalletPath(uiItem.walletPath,uiItem.accountNameText);
|
|
||||||
if(!wizard.walletPathValid(walletFullPath)){
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return recoveryWallet(settingsObject, uiItem.recoverFromSeedMode)
|
|
||||||
}
|
|
||||||
|
|
||||||
function recoveryWallet(settingsObject, fromSeed) {
|
|
||||||
var nettype = appWindow.persistentSettings.nettype;
|
|
||||||
var kdfRounds = appWindow.persistentSettings.kdfRounds;
|
|
||||||
var restoreHeight = settingsObject.restore_height;
|
|
||||||
var tmp_wallet_filename = oshelper.temporaryFilename()
|
|
||||||
console.log("Creating temporary wallet", tmp_wallet_filename)
|
|
||||||
|
|
||||||
// delete the temporary wallet object before creating new
|
|
||||||
if (typeof m_wallet !== 'undefined') {
|
|
||||||
walletManager.closeWallet()
|
|
||||||
console.log("deleting temporary wallet")
|
|
||||||
}
|
|
||||||
|
|
||||||
// From seed or keys
|
|
||||||
if(fromSeed)
|
|
||||||
var wallet = walletManager.recoveryWallet(tmp_wallet_filename, settingsObject.words, nettype, restoreHeight, kdfRounds)
|
|
||||||
else
|
|
||||||
var wallet = walletManager.createWalletFromKeys(tmp_wallet_filename, settingsObject.wallet_language, nettype,
|
|
||||||
settingsObject.recover_address, settingsObject.recover_viewkey,
|
|
||||||
settingsObject.recover_spendkey, restoreHeight, kdfRounds)
|
|
||||||
|
|
||||||
|
|
||||||
var success = wallet.status === Wallet.Status_Ok;
|
|
||||||
if (success) {
|
|
||||||
m_wallet = wallet;
|
|
||||||
settingsObject['is_recovering'] = true;
|
|
||||||
settingsObject['tmp_wallet_filename'] = tmp_wallet_filename
|
|
||||||
} else {
|
|
||||||
console.log(wallet.errorString)
|
|
||||||
walletErrorDialog.text = wallet.errorString;
|
|
||||||
walletErrorDialog.open();
|
|
||||||
walletManager.closeWallet();
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WizardManageWalletUI {
|
|
||||||
id: uiItem
|
|
||||||
accountNameText: defaultAccountName
|
|
||||||
titleText: qsTr("Restore wallet") + translationManager.emptyString
|
|
||||||
wordsTextItem.clipboardButtonVisible: false
|
|
||||||
wordsTextItem.tipTextVisible: false
|
|
||||||
wordsTextItem.memoTextReadOnly: false
|
|
||||||
wordsTextItem.memoText: ""
|
|
||||||
wordsTextItem.visible: true
|
|
||||||
restoreHeightVisible: true
|
|
||||||
recoverMode: true
|
|
||||||
wordsTextItem.onMemoTextChanged: {
|
|
||||||
checkNextButton();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
parent.wizardRestarted.connect(onWizardRestarted)
|
|
||||||
}
|
|
||||||
}
|
|
284
wizard/WizardRestoreWallet1.qml
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardRestoreWallet1
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property string viewName: "wizardCreateWallet1"
|
||||||
|
|
||||||
|
function verify() {
|
||||||
|
if(wizardController.walletRestoreMode === "keys") {
|
||||||
|
var valid = wizardRestoreWallet1.verifyFromKeys();
|
||||||
|
return valid;
|
||||||
|
} else if(wizardController.walletRestoreMode === "seed") {
|
||||||
|
var valid = wizardWalletInput.verify();
|
||||||
|
if(!valid) return false;
|
||||||
|
valid = Wizard.checkSeed(seedInput.text);
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyFromKeys() {
|
||||||
|
var result = Wizard.restoreWalletCheckViewSpendAddress(
|
||||||
|
walletManager,
|
||||||
|
persistentSettings.nettype,
|
||||||
|
viewKeyLine.text,
|
||||||
|
spendKeyLine.text,
|
||||||
|
addressLine.text
|
||||||
|
);
|
||||||
|
|
||||||
|
var addressLineLength = addressLine.text.length
|
||||||
|
var viewKeyLineLength = viewKeyLine.text.length
|
||||||
|
var spendKeyLineLength = spendKeyLine.text.length
|
||||||
|
|
||||||
|
addressLine.error = !result[0] && addressLineLength != 0
|
||||||
|
viewKeyLine.error = !result[1] && viewKeyLineLength != 0
|
||||||
|
spendKeyLine.error = !result[2] && spendKeyLineLength != 0
|
||||||
|
|
||||||
|
return (!addressLine.error && !viewKeyLine.error && !spendKeyLine.error &&
|
||||||
|
addressLineLength != 0 && viewKeyLineLength != 0 && spendKeyLineLength != 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader {
|
||||||
|
title: qsTr("Restore wallet") + translationManager.emptyString
|
||||||
|
subtitle: qsTr("Restore wallet from keys or mnemonic seed.") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardWalletInput{
|
||||||
|
id: wizardWalletInput
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout{
|
||||||
|
columns: 3
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
text: qsTr("Restore from seed") + translationManager.emptyString
|
||||||
|
small: true
|
||||||
|
enabled: wizardController.walletRestoreMode !== 'seed'
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
wizardController.walletRestoreMode = 'seed';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
text: qsTr("Restore from keys") + translationManager.emptyString
|
||||||
|
small: true
|
||||||
|
enabled: wizardController.walletRestoreMode !== 'keys'
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
wizardController.walletRestoreMode = 'keys';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
text: qsTr("From QR Code") + translationManager.emptyString
|
||||||
|
small: true
|
||||||
|
visible: appWindow.qrScannerEnabled
|
||||||
|
enabled: wizardController.walletRestoreMode !== 'qr'
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
wizardController.walletRestoreMode = 'qr';
|
||||||
|
cameraUi.state = "Capture"
|
||||||
|
cameraUi.qrcode_decoded.connect(Wizard.updateFromQrCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
// seed textarea
|
||||||
|
visible: wizardController.walletRestoreMode === 'seed'
|
||||||
|
Layout.preferredHeight: 100 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: "transparent"
|
||||||
|
radius: 4
|
||||||
|
|
||||||
|
Layout.preferredHeight: 100 * scaleRatio
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
border.width: 1
|
||||||
|
border.color: {
|
||||||
|
if(seedInput.text !== "" && seedInput.error){
|
||||||
|
return MoneroComponents.Style.inputBorderColorInvalid;
|
||||||
|
} else if(seedInput.activeFocus){
|
||||||
|
return MoneroComponents.Style.inputBorderColorActive;
|
||||||
|
} else {
|
||||||
|
return MoneroComponents.Style.inputBorderColorInActive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextArea {
|
||||||
|
id: seedInput
|
||||||
|
property bool error: false
|
||||||
|
width: parent.width
|
||||||
|
height: 100 * scaleRatio
|
||||||
|
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
textMargin: 2 * scaleRatio
|
||||||
|
text: ""
|
||||||
|
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
font.pixelSize: 16 * scaleRatio
|
||||||
|
selectionColor: MoneroComponents.Style.dimmedFontColor
|
||||||
|
selectedTextColor: MoneroComponents.Style.defaultFontColor
|
||||||
|
wrapMode: TextInput.Wrap
|
||||||
|
|
||||||
|
selectByMouse: true
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: memoTextPlaceholder
|
||||||
|
opacity: 0.35
|
||||||
|
anchors.fill:parent
|
||||||
|
font.pixelSize: 16 * scaleRatio
|
||||||
|
anchors.margins: 8 * scaleRatio
|
||||||
|
anchors.leftMargin: 10 * scaleRatio
|
||||||
|
font.family: MoneroComponents.Style.fontRegular.name
|
||||||
|
text: qsTr("Enter your 25 (or 24) word mnemonic seed") + translationManager.emptyString
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
visible: !seedInput.text && !parent.focus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.LineEdit {
|
||||||
|
id: addressLine
|
||||||
|
visible: wizardController.walletRestoreMode === 'keys'
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderFontSize: 16 * scaleRatio
|
||||||
|
placeholderText: qsTr("Account address (public)") + translationManager.emptyString
|
||||||
|
|
||||||
|
onTextUpdated: {
|
||||||
|
wizardRestoreWallet1.verifyFromKeys();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.LineEdit {
|
||||||
|
id: viewKeyLine
|
||||||
|
visible: wizardController.walletRestoreMode === 'keys'
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderFontSize: 16 * scaleRatio
|
||||||
|
placeholderText: qsTr("View key (private)") + translationManager.emptyString
|
||||||
|
|
||||||
|
onTextUpdated: {
|
||||||
|
wizardRestoreWallet1.verifyFromKeys();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.LineEdit {
|
||||||
|
id: spendKeyLine
|
||||||
|
visible: wizardController.walletRestoreMode === 'keys'
|
||||||
|
Layout.fillWidth: true
|
||||||
|
placeholderFontSize: 16 * scaleRatio
|
||||||
|
placeholderText: qsTr("Spend key (private)") + translationManager.emptyString
|
||||||
|
|
||||||
|
onTextUpdated: {
|
||||||
|
wizardRestoreWallet1.verifyFromKeys();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout{
|
||||||
|
MoneroComponents.LineEdit {
|
||||||
|
id: restoreHeight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
labelText: qsTr("Restore height") + translationManager.emptyString
|
||||||
|
labelFontSize: 14 * scaleRatio
|
||||||
|
placeholderFontSize: 16 * scaleRatio
|
||||||
|
placeholderText: qsTr("Restore height") + translationManager.emptyString
|
||||||
|
validator: RegExpValidator { regExp: /(\d+)?$/ }
|
||||||
|
text: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
id: nav
|
||||||
|
progressSteps: 4
|
||||||
|
progress: 1
|
||||||
|
btnNext.enabled: wizardRestoreWallet1.verify();
|
||||||
|
btnPrev.text: qsTr("Back to menu") + translationManager.emptyString
|
||||||
|
onPrevClicked: {
|
||||||
|
wizardStateView.state = "wizardHome";
|
||||||
|
}
|
||||||
|
onNextClicked: {
|
||||||
|
wizardController.walletOptionsName = wizardWalletInput.walletName.text;
|
||||||
|
wizardController.walletOptionsLocation = wizardWalletInput.walletLocation.text;
|
||||||
|
wizardController.walletOptionsSeed = seedInput.text;
|
||||||
|
if(restoreHeight.text)
|
||||||
|
wizardController.walletOptionsRestoreHeight = parseInt(restoreHeight.text);
|
||||||
|
|
||||||
|
wizardStateView.state = "wizardRestoreWallet2";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPageCompleted(previousView){
|
||||||
|
if(previousView.viewName == "wizardHome"){
|
||||||
|
// cleanup
|
||||||
|
seedInput.text = "";
|
||||||
|
addressLine.text = "";
|
||||||
|
spendKeyLine.text = "";
|
||||||
|
restoreHeight.text = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
wizard/WizardRestoreWallet2.qml
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardRestoreWallet2
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property string viewName: "wizardRestoreWallet2"
|
||||||
|
property int recoveryMode: 1
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 0 * scaleRatio
|
||||||
|
|
||||||
|
WizardAskPassword {
|
||||||
|
id: passwordFields
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
progressSteps: 4
|
||||||
|
progress: 2
|
||||||
|
btnNext.enabled: passwordFields.calcStrengthAndVerify();
|
||||||
|
onPrevClicked: {
|
||||||
|
wizardStateView.state = "wizardRestoreWallet1";
|
||||||
|
}
|
||||||
|
onNextClicked: {
|
||||||
|
if(appWindow.walletMode === 0 || appWindow.walletMode === 1){
|
||||||
|
wizardController.fetchRemoteNodes(function(){
|
||||||
|
wizardStateView.state = "wizardRestoreWallet4";
|
||||||
|
}, function(){
|
||||||
|
appWindow.showStatusMessage(qsTr("Failed to fetch remote nodes from third-party server."), 5);
|
||||||
|
wizardStateView.state = "wizardRestoreWallet4";
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
wizardStateView.state = "wizardRestoreWallet3";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
86
wizard/WizardRestoreWallet3.qml
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardRestoreWallet3
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property string viewName: "wizardRestoreWallet3"
|
||||||
|
property int recoveryMode: 1
|
||||||
|
|
||||||
|
function verify() {
|
||||||
|
// @TODO: check if walletName already exists in walletLocation
|
||||||
|
return walletName.text !== '';
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader {
|
||||||
|
title: qsTr("Daemon settings") + translationManager.emptyString
|
||||||
|
subtitle: qsTr("To be able to communicate with the Monero network your wallet needs to be connected to a Monero node. For best privacy it's recommended to run your own node.\n\nIf you don't have the option to run your own node, there's an option to connect to a remote node.") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardDaemonSettings {
|
||||||
|
id: daemonSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
progressSteps: 4
|
||||||
|
progress: 3
|
||||||
|
onPrevClicked: {
|
||||||
|
wizardStateView.state = "wizardRestoreWallet2";
|
||||||
|
}
|
||||||
|
onNextClicked: {
|
||||||
|
daemonSettings.save();
|
||||||
|
wizardStateView.state = "wizardRestoreWallet4";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
wizard/WizardRestoreWallet4.qml
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wizardRestoreWallet4
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
property string viewName: "wizardRestoreWallet4"
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter;
|
||||||
|
width: parent.width - 100
|
||||||
|
Layout.fillWidth: true
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter;
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: wizardController.wizardSubViewTopMargin
|
||||||
|
Layout.maximumWidth: wizardController.wizardSubViewWidth
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 20 * scaleRatio
|
||||||
|
|
||||||
|
WizardHeader {
|
||||||
|
title: qsTr("You're all set up!") + translationManager.emptyString
|
||||||
|
subtitle: qsTr("New wallet details:") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardSummary {}
|
||||||
|
|
||||||
|
WizardNav {
|
||||||
|
Layout.topMargin: 24 * scaleRatio
|
||||||
|
btnNextText: "Open wallet"
|
||||||
|
progressSteps: 4
|
||||||
|
progress: 4
|
||||||
|
|
||||||
|
onPrevClicked: {
|
||||||
|
if (appWindow.walletMode <= 1){
|
||||||
|
wizardStateView.state = "wizardRestoreWallet1";
|
||||||
|
} else {
|
||||||
|
wizardStateView.state = "wizardRestoreWallet3";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onNextClicked: {
|
||||||
|
wizardController.writeWallet();
|
||||||
|
wizardController.useMoneroClicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
91
wizard/WizardSummary.qml
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
import moneroComponents.NetworkType 1.0
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../js/Utils.js" as Utils
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
WizardSummaryItem {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
header: qsTr("Wallet name") + translationManager.emptyString
|
||||||
|
value: wizardController.walletOptionsName
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardSummaryItem {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
header: qsTr("Wallet path") + translationManager.emptyString
|
||||||
|
value: wizardController.walletOptionsLocation
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardSummaryItem {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
header: qsTr("Language") + translationManager.emptyString
|
||||||
|
value: wizardController.language_language
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardSummaryItem {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
header: qsTr("Wallet name") + translationManager.emptyString
|
||||||
|
value: walletOptionsName
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardSummaryItem {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
header: qsTr("Restore height") + translationManager.emptyString
|
||||||
|
value: wizardController.walletOptionsRestoreHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardSummaryItem {
|
||||||
|
visible: persistentSettings.remoteNodeAddress !== "" && appWindow.walletMode == 0
|
||||||
|
Layout.fillWidth: true
|
||||||
|
header: qsTr("Daemon address") + translationManager.emptyString
|
||||||
|
value: persistentSettings.remoteNodeAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardSummaryItem {
|
||||||
|
visible: persistentSettings.bootstrapNodeAddress !== "" && appWindow.walletMode == 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
header: qsTr("Bootstrap address") + translationManager.emptyString
|
||||||
|
value: persistentSettings.bootstrapNodeAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
WizardSummaryItem {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
header: qsTr("Network Type") + translationManager.emptyString
|
||||||
|
value: Utils.netTypeToString()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
//
|
//
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
|
@ -26,54 +26,60 @@
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
import moneroComponents.WalletManager 1.0
|
import QtQuick 2.7
|
||||||
import QtQuick 2.2
|
import QtQuick.Layouts 1.2
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Controls 2.0
|
||||||
import "../components"
|
|
||||||
import "utils.js" as Utils
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../js/Utils.js" as Utils
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
property alias header: key.text
|
||||||
|
property alias value: val.text
|
||||||
|
Layout.bottomMargin: 10
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
id: passwordPage
|
GridLayout {
|
||||||
opacity: 0
|
Layout.fillWidth: true
|
||||||
visible: false
|
columns: 2
|
||||||
|
columnSpacing: 0
|
||||||
|
|
||||||
Behavior on opacity {
|
Rectangle {
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 20 * scaleRatio
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
MoneroComponents.TextBlock {
|
||||||
|
id: key
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
font.pixelSize: 16
|
||||||
|
text: "test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 20 * scaleRatio
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
MoneroComponents.TextBlock {
|
||||||
|
id: val
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
font.pixelSize: 16
|
||||||
|
text: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpacityChanged: visible = opacity !== 0
|
Rectangle {
|
||||||
|
Layout.preferredHeight: 1 * scaleRatio
|
||||||
|
Layout.topMargin: 2 * scaleRatio
|
||||||
function onPageOpened(settingsObject) {
|
Layout.bottomMargin: 2 * scaleRatio
|
||||||
wizard.nextButton.enabled = true
|
Layout.fillWidth: true
|
||||||
wizard.nextButton.visible = true
|
color: MoneroComponents.Style.dividerColor
|
||||||
}
|
opacity: MoneroComponents.Style.dividerOpacity
|
||||||
|
|
||||||
function onPageClosed(settingsObject) {
|
|
||||||
var walletFullPath = wizard.createWalletPath(uiItem.walletPath,uiItem.accountNameText);
|
|
||||||
settingsObject['view_only_wallet_path'] = walletFullPath
|
|
||||||
console.log("wallet path", walletFullPath)
|
|
||||||
return wizard.walletPathValid(walletFullPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
ListModel {
|
|
||||||
id: dotsModel
|
|
||||||
ListElement { dotColor: "#36B05B" }
|
|
||||||
ListElement { dotColor: "#DBDBDB" }
|
|
||||||
}
|
|
||||||
|
|
||||||
WizardManageWalletUI {
|
|
||||||
id: uiItem
|
|
||||||
titleText: qsTr("Create view only wallet") + translationManager.emptyString
|
|
||||||
wordsTextItem.visible: false
|
|
||||||
restoreHeightVisible:false
|
|
||||||
walletName: appWindow.walletName + "-viewonly"
|
|
||||||
progressDotsModel: dotsModel
|
|
||||||
recoverMode: false
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
//parent.wizardRestarted.connect(onWizardRestarted)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
111
wizard/WizardWalletInput.qml
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
|
import "../js/Wizard.js" as Wizard
|
||||||
|
import "../components"
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
property alias walletName: walletName
|
||||||
|
property alias walletLocation: walletLocation
|
||||||
|
|
||||||
|
columnSpacing: 20 * scaleRatio
|
||||||
|
columns: 3
|
||||||
|
|
||||||
|
function verify() {
|
||||||
|
if(walletName.text !== '' && walletLocation.text !== ''){
|
||||||
|
if(!walletName.error){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.LineEdit {
|
||||||
|
id: walletName
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
function verify(){
|
||||||
|
if(walletLocation === "") return false;
|
||||||
|
|
||||||
|
var exists = Wizard.walletPathExists(walletLocation.text, walletName.text, isIOS, walletManager);
|
||||||
|
return !exists && walletLocation.error === false;
|
||||||
|
}
|
||||||
|
|
||||||
|
labelText: qsTr("Wallet name") + translationManager.emptyString
|
||||||
|
labelFontSize: 14 * scaleRatio
|
||||||
|
placeholderFontSize: 16 * scaleRatio
|
||||||
|
placeholderText: "-"
|
||||||
|
text: defaultAccountName
|
||||||
|
|
||||||
|
onTextChanged: walletName.error = !walletName.verify();
|
||||||
|
Component.onCompleted: walletName.error = !walletName.verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.LineEdit {
|
||||||
|
id: walletLocation
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
labelText: qsTr("Wallet location") + translationManager.emptyString
|
||||||
|
labelFontSize: 14 * scaleRatio
|
||||||
|
placeholderText: "..."
|
||||||
|
placeholderFontSize: 16 * scaleRatio
|
||||||
|
text: moneroAccountsDir + "/"
|
||||||
|
inlineButton.small: true
|
||||||
|
inlineButtonText: qsTr("Browse") + translationManager.emptyString
|
||||||
|
inlineButton.onClicked: {
|
||||||
|
fileWalletDialog.folder = walletManager.localPathToUrl(walletLocation.text)
|
||||||
|
fileWalletDialog.open()
|
||||||
|
walletLocation.focus = true
|
||||||
|
}
|
||||||
|
onTextChanged: {
|
||||||
|
walletLocation.error = walletLocation.text === "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileDialog {
|
||||||
|
id: fileWalletDialog
|
||||||
|
selectMultiple: false
|
||||||
|
selectFolder: true
|
||||||
|
title: qsTr("Please choose a directory") + translationManager.emptyString
|
||||||
|
onAccepted: {
|
||||||
|
walletLocation.text = walletManager.urlToLocalPath(fileWalletDialog.folder);
|
||||||
|
fileWalletDialog.visible = false;
|
||||||
|
walletName.error = !walletName.verify();
|
||||||
|
}
|
||||||
|
onRejected: {
|
||||||
|
fileWalletDialog.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,195 +0,0 @@
|
||||||
// Copyright (c) 2014-2018, The Monero Project
|
|
||||||
//
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
// permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
// conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
// of conditions and the following disclaimer in the documentation and/or other
|
|
||||||
// materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
|
||||||
// used to endorse or promote products derived from this software without specific
|
|
||||||
// prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
||||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
import QtQuick 2.2
|
|
||||||
import QtQuick.XmlListModel 2.0
|
|
||||||
import QtQuick.Layouts 1.1
|
|
||||||
import QtQml 2.2
|
|
||||||
|
|
||||||
import "../components" as MoneroComponents
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
// anchors.fill:parent
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 100; easing.type: Easing.InQuad }
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpacityChanged: visible = opacity !== 0
|
|
||||||
|
|
||||||
function onPageClosed(settingsObject) {
|
|
||||||
|
|
||||||
// set default language to first item if none selected
|
|
||||||
if(gridView.currentIndex === -1) {
|
|
||||||
gridView.currentIndex = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
var lang = languagesModel.get(gridView.currentIndex);
|
|
||||||
settingsObject['language'] = lang.display_name;
|
|
||||||
settingsObject['wallet_language'] = lang.wallet_language;
|
|
||||||
settingsObject['locale'] = lang.locale;
|
|
||||||
console.log("Language chosen: ",lang.display_name)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: headerColumn
|
|
||||||
Layout.leftMargin: wizardLeftMargin
|
|
||||||
Layout.rightMargin: wizardRightMargin
|
|
||||||
Layout.bottomMargin: 40 * scaleRatio
|
|
||||||
spacing: 20 * scaleRatio
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 28 * scaleRatio
|
|
||||||
color: "#3F3F3F"
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: qsTr("Welcome to Monero!") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 18 * scaleRatio
|
|
||||||
color: "#4A4646"
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
text: qsTr("Please choose a language and regional format.") + translationManager.emptyString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Flags model
|
|
||||||
XmlListModel {
|
|
||||||
id: languagesModel
|
|
||||||
source: "/lang/languages.xml"
|
|
||||||
query: "/languages/language"
|
|
||||||
|
|
||||||
XmlRole { name: "display_name"; query: "@display_name/string()" }
|
|
||||||
XmlRole { name: "locale"; query: "@locale/string()" }
|
|
||||||
XmlRole { name: "wallet_language"; query: "@wallet_language/string()" }
|
|
||||||
XmlRole { name: "flag"; query: "@flag/string()" }
|
|
||||||
// TODO: XmlListModel is read only, we should store current language somewhere else
|
|
||||||
// and set current language accordingly
|
|
||||||
XmlRole { name: "isCurrent"; query: "@enabled/string()" }
|
|
||||||
|
|
||||||
onStatusChanged: {
|
|
||||||
if(status === XmlListModel.Ready){
|
|
||||||
console.log("languages availible: ",count);
|
|
||||||
if(count === 1){
|
|
||||||
console.log("Skipping language page until more languages are availible")
|
|
||||||
wizard.switchPage(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout{
|
|
||||||
// Flags view
|
|
||||||
GridView {
|
|
||||||
property int margin: (isMobile) ? 0 : Math.floor(appWindow.width/12);
|
|
||||||
|
|
||||||
id: gridView
|
|
||||||
cellWidth: 140 * scaleRatio
|
|
||||||
cellHeight: 120 * scaleRatio
|
|
||||||
model: languagesModel
|
|
||||||
// Hack to center the flag grid
|
|
||||||
property int columns: Math.floor(appWindow.width/cellWidth)
|
|
||||||
Layout.leftMargin: margin + (appWindow.width - cellWidth*columns) /2
|
|
||||||
Layout.rightMargin: margin
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
delegate: Item {
|
|
||||||
id: flagDelegate
|
|
||||||
height: gridView.cellHeight
|
|
||||||
width: gridView.cellWidth
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
width: gridView.cellWidth
|
|
||||||
Rectangle {
|
|
||||||
id: flagRect
|
|
||||||
height: 60 * scaleRatio
|
|
||||||
width: 60 * scaleRatio
|
|
||||||
radius: 30 * scaleRatio
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
color: {
|
|
||||||
if (gridView.currentIndex === index) {
|
|
||||||
return MoneroComponents.Style.buttonBackgroundColor;
|
|
||||||
} else if (delegateArea.containsMouse) {
|
|
||||||
return MoneroComponents.Style.dimmedFontColor;
|
|
||||||
} else {
|
|
||||||
return MoneroComponents.Style.buttonTextColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Image {
|
|
||||||
anchors.fill: parent
|
|
||||||
source: flag
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
font.family: "Arial"
|
|
||||||
font.pixelSize: 18 * scaleRatio
|
|
||||||
font.bold: gridView.currentIndex === index
|
|
||||||
color: "#3F3F3F"
|
|
||||||
text: display_name
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: delegateArea
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: {
|
|
||||||
gridView.currentIndex = index
|
|
||||||
var data = languagesModel.get(gridView.currentIndex);
|
|
||||||
if (data !== null || data !== undefined) {
|
|
||||||
var locale = data.locale
|
|
||||||
translationManager.setLanguage(locale.split("_")[0]);
|
|
||||||
wizard.switchPage(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // delegate
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
.pragma library
|
|
||||||
|
|
||||||
function mapScope (inputScopeFrom, inputScopeTo, outputScopeFrom, outputScopeTo, value) {
|
|
||||||
var x = (value - inputScopeFrom) / (inputScopeTo - inputScopeFrom);
|
|
||||||
var result = outputScopeFrom + ((outputScopeTo - outputScopeFrom) * x);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function tr(text) {
|
|
||||||
return qsTr(text) + translationManager.emptyString
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function lineBreaksToSpaces(text) {
|
|
||||||
return text.trim().replace(/(\r\n|\n|\r)/gm, " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
function usefulName(path) {
|
|
||||||
// arbitrary "short enough" limit
|
|
||||||
if (path.length < 32)
|
|
||||||
return path
|
|
||||||
return path.replace(/.*[\/\\]/, '').replace(/\.keys$/, '')
|
|
||||||
}
|
|