aboutsummaryrefslogtreecommitdiff
path: root/wizard
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2017-01-15 14:58:47 -0500
committerRiccardo Spagni <ric@spagni.net>2017-01-15 14:58:47 -0500
commit98ca4f1a70051447c39d5f9161db2e1741fdceb9 (patch)
tree620c481c47e094d34990fe1c210f1fd0b2fa6f90 /wizard
parent7cbd61dae21fdf8a27081d28ebb130195d77ed69 (diff)
parentae5c21ef17b5585e1c90423a9f45b62b3b678f46 (diff)
downloadmonzero-gui-98ca4f1a70051447c39d5f9161db2e1741fdceb9.tar.gz
monzero-gui-98ca4f1a70051447c39d5f9161db2e1741fdceb9.tar.xz
monzero-gui-98ca4f1a70051447c39d5f9161db2e1741fdceb9.zip
Merge pull request #398
ae5c21e export/import key images when cold signing (Jaquee) 24ccd27 Add rescan spent button (Jaquee) 15c79df GUI cold signing (Jaquee) fd98395 view only wallets (Jaquee) 8f56e98 save wallet name in appwindow (Jaquee) 842e4df adjust button size dynamically (Jaquee)
Diffstat (limited to 'wizard')
-rw-r--r--wizard/WizardCreateViewOnlyWallet.qml94
-rw-r--r--wizard/WizardMain.qml81
-rw-r--r--wizard/WizardManageWalletUI.qml6
-rw-r--r--wizard/WizardPassword.qml75
-rw-r--r--wizard/WizardPasswordUI.qml96
-rw-r--r--wizard/utils.js7
6 files changed, 293 insertions, 66 deletions
diff --git a/wizard/WizardCreateViewOnlyWallet.qml b/wizard/WizardCreateViewOnlyWallet.qml
new file mode 100644
index 00000000..dc1b813e
--- /dev/null
+++ b/wizard/WizardCreateViewOnlyWallet.qml
@@ -0,0 +1,94 @@
+// Copyright (c) 2014-2015, 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 "../components"
+import "utils.js" as Utils
+
+Item {
+
+ id: passwordPage
+ opacity: 0
+ visible: false
+
+ Behavior on opacity {
+ NumberAnimation { duration: 100; easing.type: Easing.InQuad }
+ }
+
+ onOpacityChanged: visible = opacity !== 0
+
+
+ function onPageOpened(settingsObject) {
+ wizard.nextButton.enabled = true
+ }
+
+ function onPageClosed(settingsObject) {
+ var walletFullPath = wizard.createWalletPath(uiItem.walletPath,uiItem.accountNameText);
+ settingsObject['view_only_wallet_path'] = walletFullPath
+ console.log("wallet path", walletFullPath)
+ return wizard.walletPathValid(walletFullPath);
+ }
+
+ Row {
+ id: dotsRow
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.topMargin: 85
+ spacing: 6
+
+ ListModel {
+ id: dotsModel
+ ListElement { dotColor: "#FFE00A" }
+ ListElement { dotColor: "#DBDBDB" }
+ }
+
+ Repeater {
+ model: dotsModel
+ delegate: Rectangle {
+ width: 12; height: 12
+ radius: 6
+ color: dotColor
+ }
+ }
+ }
+
+ WizardManageWalletUI {
+ id: uiItem
+ titleText: qsTr("Give your view only wallet a name") + translationManager.emptyString
+ wordsTextItem.visible: false
+ restoreHeightVisible:false
+ walletName: appWindow.walletName + "-viewonly"
+ progressDotsModel: dotsModel
+ }
+
+
+ Component.onCompleted: {
+ //parent.wizardRestarted.connect(onWizardRestarted)
+ }
+}
diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml
index ec720026..124a5784 100644
--- a/wizard/WizardMain.qml
+++ b/wizard/WizardMain.qml
@@ -44,6 +44,7 @@ Rectangle {
// disable donation page
"create_wallet" : [welcomePage, optionsPage, createWalletPage, passwordPage, finishPage ],
"recovery_wallet" : [welcomePage, optionsPage, recoveryWalletPage, passwordPage, finishPage ],
+ "create_view_only_wallet" : [ createViewOnlyWalletPage, passwordPage ],
}
property string currentPath: "create_wallet"
@@ -89,15 +90,12 @@ Rectangle {
currentPage += step_value
pages[currentPage].opacity = 1;
- var nextButtonVisible = pages[currentPage] !== optionsPage;
+ var nextButtonVisible = pages[currentPage] !== optionsPage && currentPage < pages.length - 1;
nextButton.visible = nextButtonVisible;
if (typeof pages[currentPage].onPageOpened !== 'undefined') {
pages[currentPage].onPageOpened(settings,next)
}
-
-
-
}
}
@@ -130,6 +128,16 @@ Rectangle {
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 createWalletPath(folder_path,account_name){
// Remove trailing slash - (default on windows and mac)
@@ -274,6 +282,16 @@ Rectangle {
anchors.rightMargin: 50
}
+ WizardCreateViewOnlyWallet {
+ id: createViewOnlyWalletPage
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.right: nextButton.left
+ anchors.left: prevButton.right
+ anchors.leftMargin: 50
+ anchors.rightMargin: 50
+ }
+
WizardRecoveryWallet {
id: recoveryWalletPage
anchors.top: parent.top
@@ -356,4 +374,59 @@ Rectangle {
wizard.useMoneroClicked();
}
}
+
+ StandardButton {
+ id: createViewOnlyWalletButton
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ anchors.margins: 50
+ width: 110
+ text: qsTr("Create wallet") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ 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
+ anchors.right: createViewOnlyWalletButton.left
+ anchors.bottom: parent.bottom
+ anchors.margins: 50
+ width: 110
+ text: qsTr("Abort") + translationManager.emptyString
+ shadowReleasedColor: "#FF4304"
+ shadowPressedColor: "#B32D00"
+ releasedColor: "#FF6C3C"
+ pressedColor: "#FF4304"
+ visible: currentPath === "create_view_only_wallet" && parent.paths[currentPath][currentPage] === passwordPage
+ onClicked: {
+ wizard.restart();
+ rootItem.state = "normal"
+ }
+ }
+
+
+
+
}
diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml
index 4420de2d..d3bfb558 100644
--- a/wizard/WizardManageWalletUI.qml
+++ b/wizard/WizardManageWalletUI.qml
@@ -43,7 +43,8 @@ Item {
property alias wordsTextItem : memoTextItem
property alias restoreHeight : restoreHeightItem.text
property alias restoreHeightVisible: restoreHeightItem.visible
-
+ property alias walletName : accountName.text
+ property alias progressDotsModel : progressDots.model
// TODO extend properties if needed
@@ -64,6 +65,7 @@ Item {
}
Repeater {
+ id: progressDots
model: dotsModel
delegate: Rectangle {
width: 12; height: 12
@@ -184,7 +186,7 @@ Item {
Row {
anchors.left: parent.left
anchors.right: parent.right
- anchors.top: (restoreHeightItem.visible)? restoreHeightItem.bottom : memoTextItem.bottom
+ anchors.top: (restoreHeightItem.visible)? restoreHeightItem.bottom : (memoTextItem.visible)? memoTextItem.bottom : frameHeader.bottom
anchors.topMargin: 24
spacing: 16
diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml
index c26a7407..adba7a94 100644
--- a/wizard/WizardPassword.qml
+++ b/wizard/WizardPassword.qml
@@ -36,8 +36,9 @@ Item {
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 }
}
@@ -47,7 +48,7 @@ Item {
function onPageOpened(settingsObject) {
wizard.nextButton.enabled = true
- handlePassword();
+ passwordUI.handlePassword();
if (wizard.currentPath === "create_wallet") {
passwordPage.titleText = qsTr("Give your wallet a password") + translationManager.emptyString
@@ -55,44 +56,22 @@ Item {
passwordPage.titleText = qsTr("Give your wallet a password") + translationManager.emptyString
}
- passwordItem.focus = true;
+ passwordUI.focus = true;
}
function onPageClosed(settingsObject) {
// TODO: set password on the final page
// settingsObject.wallet.setPassword(passwordItem.password)
- settingsObject['wallet_password'] = passwordItem.password
+ settingsObject['wallet_password'] = passwordUI.password
return true
}
function onWizardRestarted(){
// Reset password fields
- passwordItem.password = "";
- retypePasswordItem.password = "";
- }
-
- function handlePassword() {
- // allow to forward step only if passwords match
-
- wizard.nextButton.enabled = passwordItem.password === retypePasswordItem.password
-
- // 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)
+ passwordUI.password = "";
+ passwordUI.confirmPassword = "";
}
-
-
Row {
id: dotsRow
anchors.top: parent.top
@@ -111,6 +90,9 @@ Item {
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
@@ -157,39 +139,12 @@ Item {
}
- WizardPasswordInput {
- id: passwordItem
- anchors.top: headerColumn.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.topMargin: 24
- width: 300
- height: 62
- placeholderText : qsTr("Password") + translationManager.emptyString;
- KeyNavigation.tab: retypePasswordItem
- onChanged: handlePassword()
-
- }
-
- WizardPasswordInput {
- id: retypePasswordItem
- anchors.top: passwordItem.bottom
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.topMargin: 24
- width: 300
- height: 62
- placeholderText : qsTr("Confirm password") + translationManager.emptyString;
- KeyNavigation.tab: passwordItem
- onChanged: handlePassword()
- }
-
- PrivacyLevelSmall {
- id: privacyLevel
- anchors.left: parent.left
+ WizardPasswordUI {
+ id: passwordUI
anchors.right: parent.right
- anchors.top: retypePasswordItem.bottom
- anchors.topMargin: 60
- background: "#F0EEEE"
- interactive: false
+ anchors.left: parent.left
+ anchors.top: headerColumn.bottom
+ anchors.topMargin: 30
}
Component.onCompleted: {
diff --git a/wizard/WizardPasswordUI.qml b/wizard/WizardPasswordUI.qml
new file mode 100644
index 00000000..c9a4b0c8
--- /dev/null
+++ b/wizard/WizardPasswordUI.qml
@@ -0,0 +1,96 @@
+// Copyright (c) 2014-2015, 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 "../components"
+import "utils.js" as Utils
+
+FocusScope {
+ 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
+
+ // 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)
+ }
+
+ WizardPasswordInput {
+ id: passwordItem
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: 24
+ width: 300
+ height: 62
+ placeholderText : qsTr("Password") + translationManager.emptyString;
+ KeyNavigation.tab: retypePasswordItem
+ onChanged: handlePassword()
+ focus: true
+ }
+
+ WizardPasswordInput {
+ id: retypePasswordItem
+ anchors.top: passwordItem.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.topMargin: 24
+ width: 300
+ height: 62
+ placeholderText : qsTr("Confirm password") + translationManager.emptyString;
+ KeyNavigation.tab: passwordItem
+ onChanged: handlePassword()
+ }
+
+ PrivacyLevelSmall {
+ id: privacyLevel
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: retypePasswordItem.bottom
+ anchors.topMargin: 60
+ background: "#F0EEEE"
+ interactive: false
+ }
+
+ Component.onCompleted: {
+ //parent.wizardRestarted.connect(onWizardRestarted)
+ }
+}
diff --git a/wizard/utils.js b/wizard/utils.js
index 7b9fc241..65409046 100644
--- a/wizard/utils.js
+++ b/wizard/utils.js
@@ -15,3 +15,10 @@ function tr(text) {
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$/, '')
+}