@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 848 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 742 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 1008 B |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 737 KiB |
@ -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
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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: {
|
||||
//
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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,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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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 = "";
|
||||
}
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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()
|
||||
}
|
||||
}
|
@ -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$/, '')
|
||||
}
|