diff --git a/LeftPanel.qml b/LeftPanel.qml
index 6f843fc7..8433d7f3 100644
--- a/LeftPanel.qml
+++ b/LeftPanel.qml
@@ -50,6 +50,7 @@ Rectangle {
signal addressBookClicked()
signal miningClicked()
signal signClicked()
+ signal keysClicked()
function selectItem(pos) {
menuColumn.previousButton.checked = false
@@ -483,10 +484,33 @@ Rectangle {
color: "#505050"
height: 1
}
+ // ------------- Sign/verify tab ---------------
+ MenuButton {
+ id: keysButton
+ anchors.left: parent.left
+ anchors.right: parent.right
+ text: qsTr("Seed & Keys") + translationManager.emptyString
+ symbol: qsTr("Y") + translationManager.emptyString
+ dotColor: "#FFD781"
+ under: settingsButton
+ onClicked: {
+ parent.previousButton.checked = false
+ parent.previousButton = keysButton
+ panel.keysClicked()
+ }
+ }
+ Rectangle {
+ visible: settingsButton.present
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.leftMargin: 16
+ color: "#505050"
+ height: 1
+ }
- }
+ } // Column
- }
+ } // Flickable
NetworkStatusItem {
id: networkStatus
diff --git a/MiddlePanel.qml b/MiddlePanel.qml
index 404a9d40..1ffd3132 100644
--- a/MiddlePanel.qml
+++ b/MiddlePanel.qml
@@ -58,6 +58,7 @@ Rectangle {
property Settings settingsView: Settings { }
property Mining miningView: Mining { }
property AddressBook addressBookView: AddressBook { }
+ property Keys keysView: Keys { }
signal paymentClicked(string address, string paymentId, string amount, int mixinCount, int priority, string description)
@@ -93,33 +94,6 @@ Rectangle {
transferView.sendTo(address, paymentId, description);
}
-
- // XXX: just for memo, to be removed
- // states: [
- // State {
- // name: "Dashboard"
- // PropertyChanges { target: loader; source: "pages/Dashboard.qml" }
- // }, State {
- // name: "History"
- // PropertyChanges { target: loader; source: "pages/History.qml" }
- // }, State {
- // name: "Transfer"
- // PropertyChanges { target: loader; source: "pages/Transfer.qml" }
- // }, State {
- // name: "Receive"
- // PropertyChanges { target: loader; source: "pages/Receive.qml" }
- // }, State {
- // name: "AddressBook"
- // PropertyChanges { target: loader; source: "pages/AddressBook.qml" }
- // }, State {
- // name: "Settings"
- // PropertyChanges { target: loader; source: "pages/Settings.qml" }
- // }, State {
- // name: "Mining"
- // PropertyChanges { target: loader; source: "pages/Mining.qml" }
- // }
- // ]
-
states: [
State {
name: "Dashboard"
@@ -157,6 +131,10 @@ Rectangle {
name: "Mining"
PropertyChanges { target: root; currentView: miningView }
PropertyChanges { target: mainFlickable; contentHeight: minHeight }
+ }, State {
+ name: "Keys"
+ PropertyChanges { target: root; currentView: keysView }
+ PropertyChanges { target: mainFlickable; contentHeight: minHeight }
}
]
@@ -195,11 +173,7 @@ Rectangle {
StackView {
id: stackView
initialItem: transferView
- // anchors.topMargin: 30
- // Layout.fillWidth: true
- // Layout.fillHeight: true
anchors.fill:parent
- // anchors.margins: 4
clip: true // otherwise animation will affect left panel
delegate: StackViewDelegate {
diff --git a/main.qml b/main.qml
index bb7f9a5c..b72f21ff 100644
--- a/main.qml
+++ b/main.qml
@@ -988,6 +988,37 @@ ApplicationWindow {
onAcceptedCallback();
}
}
+
+ PasswordDialog {
+ id: settingsPasswordDialog
+ z: parent.z + 1
+ visible:false
+ anchors.fill: parent
+ onAccepted: {
+ if(appWindow.password === settingsPasswordDialog.password){
+ if(currentWallet.seedLanguage == "") {
+ console.log("No seed language set. Using English as default");
+ currentWallet.setSeedLanguage("English");
+ }
+
+ // Load keys page
+ middlePanel.state = "Keys"
+
+ } else {
+ informationPopup.title = qsTr("Error") + translationManager.emptyString;
+ informationPopup.text = qsTr("Wrong password");
+ informationPopup.open()
+ informationPopup.onCloseCallback = function() {
+ settingsPasswordDialog.open()
+ }
+ }
+
+ settingsPasswordDialog.password = ""
+ }
+ onRejected: {
+ appWindow.showPageRequest("Settings");
+ }
+ }
DaemonManagerDialog {
id: daemonManagerDialog
@@ -1068,6 +1099,7 @@ ApplicationWindow {
onMiningClicked: {middlePanel.state = "Mining"; if(isMobile) hideMenu()}
onSignClicked: {middlePanel.state = "Sign"; if(isMobile) hideMenu()}
onSettingsClicked: {middlePanel.state = "Settings"; if(isMobile) hideMenu()}
+ onKeysClicked: {settingsPasswordDialog.open(); if(isMobile) hideMenu()}
}
RightPanel {
diff --git a/pages/Keys.qml b/pages/Keys.qml
new file mode 100644
index 00000000..6c78b7a3
--- /dev/null
+++ b/pages/Keys.qml
@@ -0,0 +1,213 @@
+// Copyright (c) 2014-2017, 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.0
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Layouts 1.1
+import QtQuick.Dialogs 1.2
+import "../version.js" as Version
+
+
+import "../components"
+import moneroComponents.Clipboard 1.0
+
+Rectangle {
+ property bool viewOnly: false
+ id: page
+
+ color: "#F0EEEE"
+
+ Clipboard { id: clipboard }
+
+ ColumnLayout {
+ id: mainLayout
+ anchors.margins: 17 * scaleRatio
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.right: parent.right
+ spacing: 20 * scaleRatio
+ Layout.fillWidth: true
+
+ //! Manage wallet
+ ColumnLayout {
+ Layout.fillWidth: true
+ Label {
+ Layout.fillWidth: true
+ text: qsTr("Mnemonic seed") + translationManager.emptyString
+ }
+ Rectangle {
+ Layout.fillWidth: true
+ height: 1
+ color: "#DEDEDE"
+ }
+ TextEdit {
+ id: seedText
+ wrapMode: TextEdit.Wrap
+ Layout.fillWidth: true;
+ font.pixelSize: 14 * scaleRatio
+ readOnly: true
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ parent.selectAll()
+ parent.copy()
+ parent.deselect()
+ console.log("copied to clipboard");
+ }
+ }
+ }
+ }
+
+ ColumnLayout {
+ Layout.fillWidth: true
+ Label {
+ Layout.fillWidth: true
+ text: qsTr("Keys") + translationManager.emptyString
+ }
+ Rectangle {
+ Layout.fillWidth: true
+ height: 1
+ color: "#DEDEDE"
+ }
+ TextEdit {
+ id: keysText
+ wrapMode: TextEdit.Wrap
+ Layout.fillWidth: true;
+ font.pixelSize: 14 * scaleRatio
+ textFormat: TextEdit.RichText
+ readOnly: true
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ parent.selectAll()
+ parent.copy()
+ parent.deselect()
+ console.log("copied to clipboard");
+ }
+ }
+ }
+ }
+
+ ColumnLayout {
+ Layout.fillWidth: true
+ Label {
+ Layout.fillWidth: true
+ text: qsTr("Export wallet") + translationManager.emptyString
+ }
+ Rectangle {
+ Layout.fillWidth: true
+ height: 1
+ color: "#DEDEDE"
+ }
+
+
+ RowLayout {
+ StandardButton {
+ enabled: !fullWalletQRCode.visible
+ id: showFullQr
+ text: qsTr("Spendable Wallet") + translationManager.emptyString
+ onClicked: {
+ viewOnlyQRCode.visible = false
+ }
+ }
+ StandardButton {
+ enabled: fullWalletQRCode.visible
+ id: showViewOnlyQr
+ text: qsTr("View Only Wallet") + translationManager.emptyString
+ onClicked: {
+ viewOnlyQRCode.visible = true
+ }
+ }
+ Layout.bottomMargin: 30 * scaleRatio
+ }
+
+
+ Image {
+ visible: !viewOnlyQRCode.visible
+ id: fullWalletQRCode
+ Layout.fillWidth: true
+ Layout.minimumHeight: 180 * scaleRatio
+ smooth: false
+ fillMode: Image.PreserveAspectFit
+ }
+
+ Image {
+ visible: false
+ id: viewOnlyQRCode
+ Layout.fillWidth: true
+ Layout.minimumHeight: 180 * scaleRatio
+ smooth: false
+ fillMode: Image.PreserveAspectFit
+ }
+
+ Text {
+ Layout.fillWidth: true
+ font.bold: true
+ font.pixelSize: 16 * scaleRatio
+ text: (viewOnlyQRCode.visible) ? qsTr("View Only Wallet") + translationManager.emptyString : qsTr("Spendable Wallet") + translationManager.emptyString
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+ }
+
+ // fires on every page load
+ function onPageCompleted() {
+ console.log("keys page loaded");
+
+ keysText.text = "" + qsTr("Secret view key") + ": " + currentWallet.secretViewKey
+ keysText.text += "
" + qsTr("Public view key") + ": " + currentWallet.publicViewKey
+ keysText.text += (!currentWallet.viewOnly) ? "
" + qsTr("Secret spend key") + ": " + currentWallet.secretSpendKey : ""
+ keysText.text += "
" + qsTr("Public spend key") + ": " + currentWallet.publicSpendKey
+
+ seedText.text = currentWallet.seed
+
+ if(typeof currentWallet != "undefined") {
+ viewOnlyQRCode.source = "image://qrcode/monero:" + currentWallet.address+"?secret_view_key="+currentWallet.secretViewKey+"&restore_height="+currentWallet.restoreHeight
+ fullWalletQRCode.source = viewOnlyQRCode.source +"&secret_spend_key="+currentWallet.secretSpendKey
+
+ if(currentWallet.viewOnly) {
+ viewOnlyQRCode.visible = true
+ showFullQr.visible = false
+ showViewOnlyQr.visible = false
+ seedText.text = qsTr("(View Only Wallet - No mnemonic seed available)") + translationManager.emptyString
+ }
+ }
+ }
+
+ // fires only once
+ Component.onCompleted: {
+
+ }
+
+}
+
+
+
+
+
diff --git a/pages/Settings.qml b/pages/Settings.qml
index 61e1cd16..015878d8 100644
--- a/pages/Settings.qml
+++ b/pages/Settings.qml
@@ -111,18 +111,6 @@ Rectangle {
}
}
- StandardButton {
- id: showSeedButton
- shadowReleasedColor: "#FF4304"
- shadowPressedColor: "#B32D00"
- releasedColor: "#FF6C3C"
- pressedColor: "#FF4304"
- text: qsTr("Show seed & keys") + translationManager.emptyString
- onClicked: {
- settingsPasswordDialog.open();
- }
- }
-
/* Rescan cache - Disabled until we know it's needed
StandardButton {
@@ -588,61 +576,6 @@ Rectangle {
}
}
- PasswordDialog {
- id: settingsPasswordDialog
-
- onAccepted: {
- if(appWindow.password === settingsPasswordDialog.password){
- if(currentWallet.seedLanguage == "") {
- console.log("No seed language set. Using English as default");
- currentWallet.setSeedLanguage("English");
- }
-
- seedPopup.title = qsTr("Wallet seed & keys") + translationManager.emptyString;
- seedPopup.text = "Wallet Mnemonic seed
" + currentWallet.seed
- + "
" + qsTr("Secret view key") + ": " + currentWallet.secretViewKey
- + "
" + qsTr("Public view key") + ": " + currentWallet.publicViewKey
- + "
" + qsTr("Secret spend key") + ": " + currentWallet.secretSpendKey
- + "
" + qsTr("Public spend key") + ": " + currentWallet.publicSpendKey
- seedPopup.open()
- seedPopup.width = 600
- seedPopup.height = 300
- seedPopup.onCloseCallback = function() {
- seedPopup.text = ""
- }
-
- } else {
- informationPopup.title = qsTr("Error") + translationManager.emptyString;
- informationPopup.text = qsTr("Wrong password");
- informationPopup.open()
- informationPopup.onCloseCallback = function() {
- settingsPasswordDialog.open()
- }
- }
-
- settingsPasswordDialog.password = ""
- }
- onRejected: {
-
- }
-
- }
-
- StandardDialog {
- id: seedPopup
- cancelVisible: false
- okVisible: true
- width:600
- height:400
-
- property var onCloseCallback
- onAccepted: {
- if (onCloseCallback) {
- onCloseCallback()
- }
- }
- }
-
// Choose blockchain folder
FileDialog {
id: blockchainFileDialog
diff --git a/qml.qrc b/qml.qrc
index 00468ad3..a8ba7c87 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -146,5 +146,6 @@
components/TextBlock.qml
wizard/WizardDaemonSettings.qml
components/RemoteNodeEdit.qml
+ pages/Keys.qml